From: Trond Myklebust <trond.myklebust@fys.uio.no>

NFSv2/v3 locking: Patch by Patrice Dumas to ensure that the server index
blocks uniquely by using the client address in addition to the value of the
NLM cookie field.


---

 fs/lockd/svc4proc.c         |    2 +-
 fs/lockd/svclock.c          |   26 +++++++++++++++++---------
 fs/lockd/svcproc.c          |    2 +-
 include/linux/lockd/lockd.h |    2 +-
 4 files changed, 20 insertions(+), 12 deletions(-)

diff -puN fs/lockd/svc4proc.c~nfs-lockd-sync-03 fs/lockd/svc4proc.c
--- 25/fs/lockd/svc4proc.c~nfs-lockd-sync-03	2004-02-29 14:55:43.000000000 -0800
+++ 25-akpm/fs/lockd/svc4proc.c	2004-02-29 14:55:43.000000000 -0800
@@ -464,7 +464,7 @@ nlm4svc_proc_granted_res(struct svc_rqst
 
         dprintk("lockd: GRANTED_RES   called\n");
 
-        nlmsvc_grant_reply(&argp->cookie, argp->status);
+        nlmsvc_grant_reply(rqstp, &argp->cookie, argp->status);
         return rpc_success;
 }
 
diff -puN fs/lockd/svclock.c~nfs-lockd-sync-03 fs/lockd/svclock.c
--- 25/fs/lockd/svclock.c~nfs-lockd-sync-03	2004-02-29 14:55:43.000000000 -0800
+++ 25-akpm/fs/lockd/svclock.c	2004-02-29 14:55:43.000000000 -0800
@@ -143,14 +143,15 @@ static inline int nlm_cookie_match(struc
  * Find a block with a given NLM cookie.
  */
 static inline struct nlm_block *
-nlmsvc_find_block(struct nlm_cookie *cookie)
+nlmsvc_find_block(struct nlm_cookie *cookie,  struct sockaddr_in *sin)
 {
 	struct nlm_block *block;
 
 	for (block = nlm_blocked; block; block = block->b_next) {
 		dprintk("cookie: head of blocked queue %p, block %p\n", 
 			nlm_blocked, block);
-		if (nlm_cookie_match(&block->b_call.a_args.cookie,cookie))
+		if (nlm_cookie_match(&block->b_call.a_args.cookie,cookie)
+				&& nlm_cmp_addr(sin, &block->b_host->h_addr))
 			break;
 	}
 
@@ -566,12 +567,16 @@ nlmsvc_grant_callback(struct rpc_task *t
 	struct nlm_rqst		*call = (struct nlm_rqst *) task->tk_calldata;
 	struct nlm_block	*block;
 	unsigned long		timeout;
+	struct sockaddr_in	*peer_addr = RPC_PEERADDR(task->tk_client);
 
 	dprintk("lockd: GRANT_MSG RPC callback\n");
-	dprintk("callback: looking for cookie %x \n", 
-		*(unsigned int *)(call->a_args.cookie.data));
-	if (!(block = nlmsvc_find_block(&call->a_args.cookie))) {
-		dprintk("lockd: no block for cookie %x\n", *(u32 *)(call->a_args.cookie.data));
+	dprintk("callback: looking for cookie %x, host (%08x)\n",
+		*(unsigned int *)(call->a_args.cookie.data),
+		ntohl(peer_addr->sin_addr.s_addr));
+	if (!(block = nlmsvc_find_block(&call->a_args.cookie, peer_addr))) {
+		dprintk("lockd: no block for cookie %x, host (%08x)\n",
+			*(u32 *)(call->a_args.cookie.data),
+			ntohl(peer_addr->sin_addr.s_addr));
 		return;
 	}
 
@@ -600,18 +605,21 @@ nlmsvc_grant_callback(struct rpc_task *t
  * block.
  */
 void
-nlmsvc_grant_reply(struct nlm_cookie *cookie, u32 status)
+nlmsvc_grant_reply(struct svc_rqst *rqstp, struct nlm_cookie *cookie, u32 status)
 {
 	struct nlm_block	*block;
 	struct nlm_file		*file;
 
-	if (!(block = nlmsvc_find_block(cookie)))
+	dprintk("grant_reply: looking for cookie %x, host (%08x), s=%d \n",
+		*(unsigned int *)(cookie->data),
+		ntohl(rqstp->rq_addr.sin_addr.s_addr), status);
+	if (!(block = nlmsvc_find_block(cookie, &rqstp->rq_addr)))
 		return;
 	file = block->b_file;
 
 	file->f_count++;
 	down(&file->f_sema);
-	if ((block = nlmsvc_find_block(cookie)) != NULL) {
+	if ((block = nlmsvc_find_block(cookie,&rqstp->rq_addr)) != NULL) {
 		if (status == NLM_LCK_DENIED_GRACE_PERIOD) {
 			/* Try again in a couple of seconds */
 			nlmsvc_insert_block(block, 10 * HZ);
diff -puN fs/lockd/svcproc.c~nfs-lockd-sync-03 fs/lockd/svcproc.c
--- 25/fs/lockd/svcproc.c~nfs-lockd-sync-03	2004-02-29 14:55:43.000000000 -0800
+++ 25-akpm/fs/lockd/svcproc.c	2004-02-29 14:55:43.000000000 -0800
@@ -490,7 +490,7 @@ nlmsvc_proc_granted_res(struct svc_rqst 
 
 	dprintk("lockd: GRANTED_RES   called\n");
 
-	nlmsvc_grant_reply(&argp->cookie, argp->status);
+	nlmsvc_grant_reply(rqstp, &argp->cookie, argp->status);
 	return rpc_success;
 }
 
diff -puN include/linux/lockd/lockd.h~nfs-lockd-sync-03 include/linux/lockd/lockd.h
--- 25/include/linux/lockd/lockd.h~nfs-lockd-sync-03	2004-02-29 14:55:43.000000000 -0800
+++ 25-akpm/include/linux/lockd/lockd.h	2004-02-29 14:55:43.000000000 -0800
@@ -165,7 +165,7 @@ u32		  nlmsvc_cancel_blocked(struct nlm_
 unsigned long	  nlmsvc_retry_blocked(void);
 int		  nlmsvc_traverse_blocks(struct nlm_host *, struct nlm_file *,
 					int action);
-void	  nlmsvc_grant_reply(struct nlm_cookie *cookie, u32 status);
+void	  nlmsvc_grant_reply(struct svc_rqst *, struct nlm_cookie *, u32);
 
 /*
  * File handling for the server personality

_