^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * linux/fs/lockd/svclock.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Handling of server-side locks, mostly of the blocked variety.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * This is the ugliest part of lockd because we tread on very thin ice.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * GRANT and CANCEL calls may get stuck, meet in mid-flight, etc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * IMNSHO introducing the grant callback into the NLM protocol was one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * of the worst ideas Sun ever had. Except maybe for the idea of doing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * NFS file locking at all.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * I'm trying hard to avoid race conditions by protecting most accesses
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * to a file's list of blocked locks through a semaphore. The global
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * list of blocked locks is not protected in this fashion however.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * Therefore, some functions (such as the RPC callback for the async grant
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * call) move blocked locks towards the head of the list *while some other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * process might be traversing it*. This should not be a problem in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * practice, because this will only cause functions traversing the list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * to visit some blocks twice.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/sunrpc/clnt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/sunrpc/svc_xprt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/lockd/nlm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/lockd/lockd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/kthread.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define NLMDBG_FACILITY NLMDBG_SVCLOCK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #ifdef CONFIG_LOCKD_V4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define nlm_deadlock nlm4_deadlock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define nlm_deadlock nlm_lck_denied
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) static void nlmsvc_release_block(struct nlm_block *block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) static void nlmsvc_insert_block(struct nlm_block *block, unsigned long);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) static void nlmsvc_remove_block(struct nlm_block *block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) static int nlmsvc_setgrantargs(struct nlm_rqst *call, struct nlm_lock *lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) static void nlmsvc_freegrantargs(struct nlm_rqst *call);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) static const struct rpc_call_ops nlmsvc_grant_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * The list of blocked locks to retry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) static LIST_HEAD(nlm_blocked);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) static DEFINE_SPINLOCK(nlm_blocked_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #if IS_ENABLED(CONFIG_SUNRPC_DEBUG)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) static const char *nlmdbg_cookie2a(const struct nlm_cookie *cookie)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * We can get away with a static buffer because this is only called
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * from lockd, which is single-threaded.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) static char buf[2*NLM_MAXCOOKIELEN+1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) unsigned int i, len = sizeof(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) char *p = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) len--; /* allow for trailing \0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) if (len < 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) return "???";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) for (i = 0 ; i < cookie->len ; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) if (len < 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) strcpy(p-3, "...");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) sprintf(p, "%02x", cookie->data[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) p += 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) len -= 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) *p = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) return buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * Insert a blocked lock into the global list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) nlmsvc_insert_block_locked(struct nlm_block *block, unsigned long when)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) struct nlm_block *b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) struct list_head *pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) dprintk("lockd: nlmsvc_insert_block(%p, %ld)\n", block, when);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) if (list_empty(&block->b_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) kref_get(&block->b_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) list_del_init(&block->b_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) pos = &nlm_blocked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) if (when != NLM_NEVER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) if ((when += jiffies) == NLM_NEVER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) when ++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) list_for_each(pos, &nlm_blocked) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) b = list_entry(pos, struct nlm_block, b_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) if (time_after(b->b_when,when) || b->b_when == NLM_NEVER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) /* On normal exit from the loop, pos == &nlm_blocked,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) * so we will be adding to the end of the list - good
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) list_add_tail(&block->b_list, pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) block->b_when = when;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) static void nlmsvc_insert_block(struct nlm_block *block, unsigned long when)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) spin_lock(&nlm_blocked_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) nlmsvc_insert_block_locked(block, when);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) spin_unlock(&nlm_blocked_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * Remove a block from the global list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) nlmsvc_remove_block(struct nlm_block *block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) if (!list_empty(&block->b_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) spin_lock(&nlm_blocked_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) list_del_init(&block->b_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) spin_unlock(&nlm_blocked_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) nlmsvc_release_block(block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * Find a block for a given lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) static struct nlm_block *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) nlmsvc_lookup_block(struct nlm_file *file, struct nlm_lock *lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) struct nlm_block *block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) struct file_lock *fl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) dprintk("lockd: nlmsvc_lookup_block f=%p pd=%d %Ld-%Ld ty=%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) file, lock->fl.fl_pid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) (long long)lock->fl.fl_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) (long long)lock->fl.fl_end, lock->fl.fl_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) list_for_each_entry(block, &nlm_blocked, b_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) fl = &block->b_call->a_args.lock.fl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) dprintk("lockd: check f=%p pd=%d %Ld-%Ld ty=%d cookie=%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) block->b_file, fl->fl_pid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) (long long)fl->fl_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) (long long)fl->fl_end, fl->fl_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) nlmdbg_cookie2a(&block->b_call->a_args.cookie));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) if (block->b_file == file && nlm_compare_locks(fl, &lock->fl)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) kref_get(&block->b_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) return block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) static inline int nlm_cookie_match(struct nlm_cookie *a, struct nlm_cookie *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) if (a->len != b->len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) if (memcmp(a->data, b->data, a->len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) * Find a block with a given NLM cookie.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) static inline struct nlm_block *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) nlmsvc_find_block(struct nlm_cookie *cookie)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) struct nlm_block *block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) list_for_each_entry(block, &nlm_blocked, b_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) if (nlm_cookie_match(&block->b_call->a_args.cookie,cookie))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) goto found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) found:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) dprintk("nlmsvc_find_block(%s): block=%p\n", nlmdbg_cookie2a(cookie), block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) kref_get(&block->b_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) return block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) * Create a block and initialize it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) * Note: we explicitly set the cookie of the grant reply to that of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) * the blocked lock request. The spec explicitly mentions that the client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) * should _not_ rely on the callback containing the same cookie as the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) * request, but (as I found out later) that's because some implementations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) * do just this. Never mind the standards comittees, they support our
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) * logging industries.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) * 10 years later: I hope we can safely ignore these old and broken
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) * clients by now. Let's fix this so we can uniquely identify an incoming
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) * GRANTED_RES message by cookie, without having to rely on the client's IP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) * address. --okir
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) static struct nlm_block *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) nlmsvc_create_block(struct svc_rqst *rqstp, struct nlm_host *host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) struct nlm_file *file, struct nlm_lock *lock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) struct nlm_cookie *cookie)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) struct nlm_block *block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) struct nlm_rqst *call = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) call = nlm_alloc_call(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) if (call == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) /* Allocate memory for block, and initialize arguments */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) block = kzalloc(sizeof(*block), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) if (block == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) goto failed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) kref_init(&block->b_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) INIT_LIST_HEAD(&block->b_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) INIT_LIST_HEAD(&block->b_flist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) if (!nlmsvc_setgrantargs(call, lock))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) goto failed_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) /* Set notifier function for VFS, and init args */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) call->a_args.lock.fl.fl_flags |= FL_SLEEP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) call->a_args.lock.fl.fl_lmops = &nlmsvc_lock_operations;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) nlmclnt_next_cookie(&call->a_args.cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) dprintk("lockd: created block %p...\n", block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) /* Create and initialize the block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) block->b_daemon = rqstp->rq_server;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) block->b_host = host;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) block->b_file = file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) file->f_count++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) /* Add to file's list of blocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) list_add(&block->b_flist, &file->f_blocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) /* Set up RPC arguments for callback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) block->b_call = call;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) call->a_flags = RPC_TASK_ASYNC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) call->a_block = block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) return block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) failed_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) kfree(block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) failed:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) nlmsvc_release_call(call);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) * Delete a block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) * It is the caller's responsibility to check whether the file
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) * can be closed hereafter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) static int nlmsvc_unlink_block(struct nlm_block *block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) int status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) dprintk("lockd: unlinking block %p...\n", block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) /* Remove block from list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) status = locks_delete_block(&block->b_call->a_args.lock.fl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) nlmsvc_remove_block(block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) static void nlmsvc_free_block(struct kref *kref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) struct nlm_block *block = container_of(kref, struct nlm_block, b_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) struct nlm_file *file = block->b_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) dprintk("lockd: freeing block %p...\n", block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) /* Remove block from file's list of blocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) list_del_init(&block->b_flist);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) mutex_unlock(&file->f_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) nlmsvc_freegrantargs(block->b_call);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) nlmsvc_release_call(block->b_call);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) nlm_release_file(block->b_file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) kfree(block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) static void nlmsvc_release_block(struct nlm_block *block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) if (block != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) kref_put_mutex(&block->b_count, nlmsvc_free_block, &block->b_file->f_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) * Loop over all blocks and delete blocks held by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) * a matching host.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) void nlmsvc_traverse_blocks(struct nlm_host *host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) struct nlm_file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) nlm_host_match_fn_t match)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) struct nlm_block *block, *next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) restart:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) mutex_lock(&file->f_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) list_for_each_entry_safe(block, next, &file->f_blocks, b_flist) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) if (!match(block->b_host, host))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) /* Do not destroy blocks that are not on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) * the global retry list - why? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) if (list_empty(&block->b_list))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) kref_get(&block->b_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) mutex_unlock(&file->f_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) nlmsvc_unlink_block(block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) nlmsvc_release_block(block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) goto restart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) mutex_unlock(&file->f_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) static struct nlm_lockowner *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) nlmsvc_get_lockowner(struct nlm_lockowner *lockowner)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) refcount_inc(&lockowner->count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) return lockowner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) static void nlmsvc_put_lockowner(struct nlm_lockowner *lockowner)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) if (!refcount_dec_and_lock(&lockowner->count, &lockowner->host->h_lock))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) list_del(&lockowner->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) spin_unlock(&lockowner->host->h_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) nlmsvc_release_host(lockowner->host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) kfree(lockowner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) static struct nlm_lockowner *__nlmsvc_find_lockowner(struct nlm_host *host, pid_t pid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) struct nlm_lockowner *lockowner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) list_for_each_entry(lockowner, &host->h_lockowners, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) if (lockowner->pid != pid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) return nlmsvc_get_lockowner(lockowner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) static struct nlm_lockowner *nlmsvc_find_lockowner(struct nlm_host *host, pid_t pid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) struct nlm_lockowner *res, *new = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) spin_lock(&host->h_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) res = __nlmsvc_find_lockowner(host, pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) if (res == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) spin_unlock(&host->h_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) new = kmalloc(sizeof(*res), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) spin_lock(&host->h_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) res = __nlmsvc_find_lockowner(host, pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) if (res == NULL && new != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) res = new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) /* fs/locks.c will manage the refcount through lock_ops */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) refcount_set(&new->count, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) new->pid = pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) new->host = nlm_get_host(host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) list_add(&new->list, &host->h_lockowners);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) new = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) spin_unlock(&host->h_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) kfree(new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) return res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) nlmsvc_release_lockowner(struct nlm_lock *lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) if (lock->fl.fl_owner)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) nlmsvc_put_lockowner(lock->fl.fl_owner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) void nlmsvc_locks_init_private(struct file_lock *fl, struct nlm_host *host,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) pid_t pid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) fl->fl_owner = nlmsvc_find_lockowner(host, pid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) * Initialize arguments for GRANTED call. The nlm_rqst structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) * has been cleared already.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) static int nlmsvc_setgrantargs(struct nlm_rqst *call, struct nlm_lock *lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) locks_copy_lock(&call->a_args.lock.fl, &lock->fl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) memcpy(&call->a_args.lock.fh, &lock->fh, sizeof(call->a_args.lock.fh));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) call->a_args.lock.caller = utsname()->nodename;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) call->a_args.lock.oh.len = lock->oh.len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) /* set default data area */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) call->a_args.lock.oh.data = call->a_owner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) call->a_args.lock.svid = ((struct nlm_lockowner *)lock->fl.fl_owner)->pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (lock->oh.len > NLMCLNT_OHSIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) void *data = kmalloc(lock->oh.len, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) if (!data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) call->a_args.lock.oh.data = (u8 *) data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) memcpy(call->a_args.lock.oh.data, lock->oh.data, lock->oh.len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) static void nlmsvc_freegrantargs(struct nlm_rqst *call)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) if (call->a_args.lock.oh.data != call->a_owner)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) kfree(call->a_args.lock.oh.data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) locks_release_private(&call->a_args.lock.fl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) * Deferred lock request handling for non-blocking lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) static __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) nlmsvc_defer_lock_rqst(struct svc_rqst *rqstp, struct nlm_block *block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) __be32 status = nlm_lck_denied_nolocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) block->b_flags |= B_QUEUED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) nlmsvc_insert_block(block, NLM_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) block->b_cache_req = &rqstp->rq_chandle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) if (rqstp->rq_chandle.defer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) block->b_deferred_req =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) rqstp->rq_chandle.defer(block->b_cache_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) if (block->b_deferred_req != NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) status = nlm_drop_reply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) dprintk("lockd: nlmsvc_defer_lock_rqst block %p flags %d status %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) block, block->b_flags, ntohl(status));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) * Attempt to establish a lock, and if it can't be granted, block it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) * if required.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) struct nlm_host *host, struct nlm_lock *lock, int wait,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) struct nlm_cookie *cookie, int reclaim)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) struct nlm_block *block = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) __be32 ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) dprintk("lockd: nlmsvc_lock(%s/%ld, ty=%d, pi=%d, %Ld-%Ld, bl=%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) locks_inode(file->f_file)->i_sb->s_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) locks_inode(file->f_file)->i_ino,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) lock->fl.fl_type, lock->fl.fl_pid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) (long long)lock->fl.fl_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) (long long)lock->fl.fl_end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) /* Lock file against concurrent access */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) mutex_lock(&file->f_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) /* Get existing block (in case client is busy-waiting)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) * or create new block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) block = nlmsvc_lookup_block(file, lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) if (block == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) block = nlmsvc_create_block(rqstp, host, file, lock, cookie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) ret = nlm_lck_denied_nolocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) if (block == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) lock = &block->b_call->a_args.lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) lock->fl.fl_flags &= ~FL_SLEEP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) if (block->b_flags & B_QUEUED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) dprintk("lockd: nlmsvc_lock deferred block %p flags %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) block, block->b_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) if (block->b_granted) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) nlmsvc_unlink_block(block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) ret = nlm_granted;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) if (block->b_flags & B_TIMED_OUT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) nlmsvc_unlink_block(block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) ret = nlm_lck_denied;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) ret = nlm_drop_reply;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) if (locks_in_grace(SVC_NET(rqstp)) && !reclaim) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) ret = nlm_lck_denied_grace_period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) if (reclaim && !locks_in_grace(SVC_NET(rqstp))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) ret = nlm_lck_denied_grace_period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) if (!wait)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) lock->fl.fl_flags &= ~FL_SLEEP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) error = vfs_lock_file(file->f_file, F_SETLK, &lock->fl, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) lock->fl.fl_flags &= ~FL_SLEEP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) dprintk("lockd: vfs_lock_file returned %d\n", error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) switch (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) ret = nlm_granted;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) case -EAGAIN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) * If this is a blocking request for an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) * already pending lock request then we need
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) * to put it back on lockd's block list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) if (wait)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) ret = nlm_lck_denied;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) case FILE_LOCK_DEFERRED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) if (wait)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) /* Filesystem lock operation is in progress
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) Add it to the queue waiting for callback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) ret = nlmsvc_defer_lock_rqst(rqstp, block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) case -EDEADLK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) ret = nlm_deadlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) default: /* includes ENOLCK */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) ret = nlm_lck_denied_nolocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) ret = nlm_lck_blocked;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) /* Append to list of blocked */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) nlmsvc_insert_block(block, NLM_NEVER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) mutex_unlock(&file->f_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) nlmsvc_release_block(block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) dprintk("lockd: nlmsvc_lock returned %u\n", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) * Test for presence of a conflicting lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) struct nlm_host *host, struct nlm_lock *lock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) struct nlm_lock *conflock, struct nlm_cookie *cookie)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) __be32 ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) struct nlm_lockowner *test_owner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) dprintk("lockd: nlmsvc_testlock(%s/%ld, ty=%d, %Ld-%Ld)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) locks_inode(file->f_file)->i_sb->s_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) locks_inode(file->f_file)->i_ino,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) lock->fl.fl_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) (long long)lock->fl.fl_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) (long long)lock->fl.fl_end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) if (locks_in_grace(SVC_NET(rqstp))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) ret = nlm_lck_denied_grace_period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) /* If there's a conflicting lock, remember to clean up the test lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) test_owner = (struct nlm_lockowner *)lock->fl.fl_owner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) error = vfs_test_lock(file->f_file, &lock->fl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) /* We can't currently deal with deferred test requests */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) if (error == FILE_LOCK_DEFERRED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) WARN_ON_ONCE(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) ret = nlm_lck_denied_nolocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) if (lock->fl.fl_type == F_UNLCK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) ret = nlm_granted;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) dprintk("lockd: conflicting lock(ty=%d, %Ld-%Ld)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) lock->fl.fl_type, (long long)lock->fl.fl_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) (long long)lock->fl.fl_end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) conflock->caller = "somehost"; /* FIXME */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) conflock->len = strlen(conflock->caller);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) conflock->oh.len = 0; /* don't return OH info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) conflock->svid = lock->fl.fl_pid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) conflock->fl.fl_type = lock->fl.fl_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) conflock->fl.fl_start = lock->fl.fl_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) conflock->fl.fl_end = lock->fl.fl_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) locks_release_private(&lock->fl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) /* Clean up the test lock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) lock->fl.fl_owner = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) nlmsvc_put_lockowner(test_owner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) ret = nlm_lck_denied;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) * Remove a lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) * This implies a CANCEL call: We send a GRANT_MSG, the client replies
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) * with a GRANT_RES call which gets lost, and calls UNLOCK immediately
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) * afterwards. In this case the block will still be there, and hence
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) * must be removed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) nlmsvc_unlock(struct net *net, struct nlm_file *file, struct nlm_lock *lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) dprintk("lockd: nlmsvc_unlock(%s/%ld, pi=%d, %Ld-%Ld)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) locks_inode(file->f_file)->i_sb->s_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) locks_inode(file->f_file)->i_ino,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) lock->fl.fl_pid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) (long long)lock->fl.fl_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) (long long)lock->fl.fl_end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) /* First, cancel any lock that might be there */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) nlmsvc_cancel_blocked(net, file, lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) lock->fl.fl_type = F_UNLCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) error = vfs_lock_file(file->f_file, F_SETLK, &lock->fl, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) return (error < 0)? nlm_lck_denied_nolocks : nlm_granted;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) * Cancel a previously blocked request.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) * A cancel request always overrides any grant that may currently
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) * be in progress.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) * The calling procedure must check whether the file can be closed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) __be32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) nlmsvc_cancel_blocked(struct net *net, struct nlm_file *file, struct nlm_lock *lock)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) struct nlm_block *block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) int status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) dprintk("lockd: nlmsvc_cancel(%s/%ld, pi=%d, %Ld-%Ld)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) locks_inode(file->f_file)->i_sb->s_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) locks_inode(file->f_file)->i_ino,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) lock->fl.fl_pid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) (long long)lock->fl.fl_start,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) (long long)lock->fl.fl_end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) if (locks_in_grace(net))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) return nlm_lck_denied_grace_period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) mutex_lock(&file->f_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) block = nlmsvc_lookup_block(file, lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) mutex_unlock(&file->f_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) if (block != NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) vfs_cancel_lock(block->b_file->f_file,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) &block->b_call->a_args.lock.fl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) status = nlmsvc_unlink_block(block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) nlmsvc_release_block(block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) return status ? nlm_lck_denied : nlm_granted;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) * This is a callback from the filesystem for VFS file lock requests.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) * It will be used if lm_grant is defined and the filesystem can not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) * respond to the request immediately.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) * For SETLK or SETLKW request it will get the local posix lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) * In all cases it will move the block to the head of nlm_blocked q where
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) * nlmsvc_retry_blocked() can send back a reply for SETLKW or revisit the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) * deferred rpc for GETLK and SETLK.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) nlmsvc_update_deferred_block(struct nlm_block *block, int result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) block->b_flags |= B_GOT_CALLBACK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) if (result == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) block->b_granted = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) block->b_flags |= B_TIMED_OUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) static int nlmsvc_grant_deferred(struct file_lock *fl, int result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) struct nlm_block *block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) int rc = -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) spin_lock(&nlm_blocked_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) list_for_each_entry(block, &nlm_blocked, b_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) if (nlm_compare_locks(&block->b_call->a_args.lock.fl, fl)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) dprintk("lockd: nlmsvc_notify_blocked block %p flags %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) block, block->b_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) if (block->b_flags & B_QUEUED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) if (block->b_flags & B_TIMED_OUT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) rc = -ENOLCK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) nlmsvc_update_deferred_block(block, result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) } else if (result == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) block->b_granted = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) nlmsvc_insert_block_locked(block, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) svc_wake_up(block->b_daemon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) spin_unlock(&nlm_blocked_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) if (rc == -ENOENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) printk(KERN_WARNING "lockd: grant for unknown block\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) * Unblock a blocked lock request. This is a callback invoked from the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) * VFS layer when a lock on which we blocked is removed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) * This function doesn't grant the blocked lock instantly, but rather moves
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) * the block to the head of nlm_blocked where it can be picked up by lockd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) nlmsvc_notify_blocked(struct file_lock *fl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) struct nlm_block *block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) dprintk("lockd: VFS unblock notification for block %p\n", fl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) spin_lock(&nlm_blocked_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) list_for_each_entry(block, &nlm_blocked, b_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) if (nlm_compare_locks(&block->b_call->a_args.lock.fl, fl)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) nlmsvc_insert_block_locked(block, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) spin_unlock(&nlm_blocked_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) svc_wake_up(block->b_daemon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) spin_unlock(&nlm_blocked_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) printk(KERN_WARNING "lockd: notification for unknown block!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) static fl_owner_t nlmsvc_get_owner(fl_owner_t owner)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) return nlmsvc_get_lockowner(owner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) static void nlmsvc_put_owner(fl_owner_t owner)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) nlmsvc_put_lockowner(owner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) const struct lock_manager_operations nlmsvc_lock_operations = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) .lm_notify = nlmsvc_notify_blocked,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) .lm_grant = nlmsvc_grant_deferred,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) .lm_get_owner = nlmsvc_get_owner,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) .lm_put_owner = nlmsvc_put_owner,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) * Try to claim a lock that was previously blocked.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) * Note that we use both the RPC_GRANTED_MSG call _and_ an async
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) * RPC thread when notifying the client. This seems like overkill...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) * Here's why:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) * - we don't want to use a synchronous RPC thread, otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) * we might find ourselves hanging on a dead portmapper.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) * - Some lockd implementations (e.g. HP) don't react to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) * RPC_GRANTED calls; they seem to insist on RPC_GRANTED_MSG calls.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) nlmsvc_grant_blocked(struct nlm_block *block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) struct nlm_file *file = block->b_file;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) struct nlm_lock *lock = &block->b_call->a_args.lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) loff_t fl_start, fl_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) dprintk("lockd: grant blocked lock %p\n", block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) kref_get(&block->b_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) /* Unlink block request from list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) nlmsvc_unlink_block(block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) /* If b_granted is true this means we've been here before.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) * Just retry the grant callback, possibly refreshing the RPC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) * binding */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) if (block->b_granted) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) nlm_rebind_host(block->b_host);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) goto callback;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) /* Try the lock operation again */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) /* vfs_lock_file() can mangle fl_start and fl_end, but we need
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) * them unchanged for the GRANT_MSG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) lock->fl.fl_flags |= FL_SLEEP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) fl_start = lock->fl.fl_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) fl_end = lock->fl.fl_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) error = vfs_lock_file(file->f_file, F_SETLK, &lock->fl, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) lock->fl.fl_flags &= ~FL_SLEEP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) lock->fl.fl_start = fl_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) lock->fl.fl_end = fl_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) switch (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) case 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) case FILE_LOCK_DEFERRED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) dprintk("lockd: lock still blocked error %d\n", error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) nlmsvc_insert_block(block, NLM_NEVER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) nlmsvc_release_block(block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) printk(KERN_WARNING "lockd: unexpected error %d in %s!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) -error, __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) nlmsvc_insert_block(block, 10 * HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) nlmsvc_release_block(block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) callback:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) /* Lock was granted by VFS. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) dprintk("lockd: GRANTing blocked lock.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) block->b_granted = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) /* keep block on the list, but don't reattempt until the RPC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) * completes or the submission fails
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) nlmsvc_insert_block(block, NLM_NEVER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) /* Call the client -- use a soft RPC task since nlmsvc_retry_blocked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) * will queue up a new one if this one times out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) error = nlm_async_call(block->b_call, NLMPROC_GRANTED_MSG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) &nlmsvc_grant_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) /* RPC submission failed, wait a bit and retry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) if (error < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) nlmsvc_insert_block(block, 10 * HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) * This is the callback from the RPC layer when the NLM_GRANTED_MSG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) * RPC call has succeeded or timed out.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) * Like all RPC callbacks, it is invoked by the rpciod process, so it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) * better not sleep. Therefore, we put the blocked lock on the nlm_blocked
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) * chain once more in order to have it removed by lockd itself (which can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) * then sleep on the file semaphore without disrupting e.g. the nfs client).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) static void nlmsvc_grant_callback(struct rpc_task *task, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) struct nlm_rqst *call = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) struct nlm_block *block = call->a_block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) unsigned long timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) dprintk("lockd: GRANT_MSG RPC callback\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) spin_lock(&nlm_blocked_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) /* if the block is not on a list at this point then it has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) * been invalidated. Don't try to requeue it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) * FIXME: it's possible that the block is removed from the list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) * after this check but before the nlmsvc_insert_block. In that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) * case it will be added back. Perhaps we need better locking
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) * for nlm_blocked?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) if (list_empty(&block->b_list))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) /* Technically, we should down the file semaphore here. Since we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) * move the block towards the head of the queue only, no harm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) * can be done, though. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) if (task->tk_status < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) /* RPC error: Re-insert for retransmission */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) timeout = 10 * HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) /* Call was successful, now wait for client callback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) timeout = 60 * HZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) nlmsvc_insert_block_locked(block, timeout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) svc_wake_up(block->b_daemon);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) spin_unlock(&nlm_blocked_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) * FIXME: nlmsvc_release_block() grabs a mutex. This is not allowed for an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) * .rpc_release rpc_call_op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) static void nlmsvc_grant_release(void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) struct nlm_rqst *call = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) nlmsvc_release_block(call->a_block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) static const struct rpc_call_ops nlmsvc_grant_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) .rpc_call_done = nlmsvc_grant_callback,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) .rpc_release = nlmsvc_grant_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) * We received a GRANT_RES callback. Try to find the corresponding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) * block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) nlmsvc_grant_reply(struct nlm_cookie *cookie, __be32 status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) struct nlm_block *block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) dprintk("grant_reply: looking for cookie %x, s=%d \n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) *(unsigned int *)(cookie->data), status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) if (!(block = nlmsvc_find_block(cookie)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) if (status == nlm_lck_denied_grace_period) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) /* Try again in a couple of seconds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) nlmsvc_insert_block(block, 10 * HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) * Lock is now held by client, or has been rejected.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) * In both cases, the block should be removed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) nlmsvc_unlink_block(block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) nlmsvc_release_block(block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) /* Helper function to handle retry of a deferred block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) * If it is a blocking lock, call grant_blocked.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) * For a non-blocking lock or test lock, revisit the request.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) retry_deferred_block(struct nlm_block *block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) if (!(block->b_flags & B_GOT_CALLBACK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) block->b_flags |= B_TIMED_OUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) nlmsvc_insert_block(block, NLM_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) dprintk("revisit block %p flags %d\n", block, block->b_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) if (block->b_deferred_req) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) block->b_deferred_req->revisit(block->b_deferred_req, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) block->b_deferred_req = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) * Retry all blocked locks that have been notified. This is where lockd
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) * picks up locks that can be granted, or grant notifications that must
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) * be retransmitted.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) unsigned long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) nlmsvc_retry_blocked(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) unsigned long timeout = MAX_SCHEDULE_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) struct nlm_block *block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) spin_lock(&nlm_blocked_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) while (!list_empty(&nlm_blocked) && !kthread_should_stop()) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) block = list_entry(nlm_blocked.next, struct nlm_block, b_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) if (block->b_when == NLM_NEVER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) if (time_after(block->b_when, jiffies)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) timeout = block->b_when - jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) spin_unlock(&nlm_blocked_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) dprintk("nlmsvc_retry_blocked(%p, when=%ld)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) block, block->b_when);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) if (block->b_flags & B_QUEUED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) dprintk("nlmsvc_retry_blocked delete block (%p, granted=%d, flags=%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) block, block->b_granted, block->b_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) retry_deferred_block(block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) nlmsvc_grant_blocked(block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) spin_lock(&nlm_blocked_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) spin_unlock(&nlm_blocked_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) return timeout;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) }