From: Trond Myklebust 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 _