Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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) }