* Re: NLM lock reclaim failure
@ 2006-10-13 5:43 Marc Eshel
2006-10-13 7:08 ` Neil Brown
0 siblings, 1 reply; 5+ messages in thread
From: Marc Eshel @ 2006-10-13 5:43 UTC (permalink / raw)
To: Linux NFS Mailing List
Hi Trond,
Attached is a tested patch for the bug I posted in the following mail
Marc.
nfs-bounces@lists.sourceforge.net wrote on 10/11/2006 04:28:16 PM:
> I see an NLM lock reclaim failure (using 2.6.17). Let me describe
> the simple case first.
>
> 1. Client gets an NLM lock
> 2. Server reboots
> 3. Client sends lock reclaim request
> 4. On server, nlm_open() gets return code nfserr_dropit; error gets
> converted to nlm_lck_denied by nlm_lookup_file().
> 5. Client gets status=1, the lock reclaim failed
>
> This happens _only_ when the first call to nfsd (fh_verify -> exp_find)
> comes from lockd trying to find the file. Subsequent calls seem to work.
>
> nlm_lookup_file() -> nlm_fopen() -> nfsd_open() -> fh_verify() ->
> exp_find() returns nfserr_dropit
>
> This problem may be related to the following commit to lockd (Trond's
> tree):
> commit: 26bcbf965f857c710adafd16cf424f043006b5dd
> lockd: stop abusing file_lock_list
>
> The client earlier retained the list of outstanding locks regardless of
> reclaim return code. The change above removes all locks from the list
> and only adds them back after a successful reclaim. Since the reclaim
> fails, it is removed from the list; so the client will not try to
> reclaim the lock on a second failure.
>
> Note that the problem is not on the client side - it seems the server
> that should drop the rpc when it gets nfserr_dropit error and not
> convert it to an nlm_lck_denied.
>
> It get even more complicated - when the server doesn't respond
> immediately to the reclaim, client will retry the rpc, on the second
> reclaim call, the server will grant the lock to the client but since the
> client already got the nlm_lck_denied from the first call, it has
> dropped it from it list. So now we have a lock on the server for a
> client that doesn't know that it holds the lock.
>
> Marc.
>
Index: lockd/svc.c
===================================================================
RCS file: /cvs/nfsv4/cvs/pnfs/fs/lockd/svc.c,v
retrieving revision 1.1.1.4
diff -u -r1.1.1.4 svc.c
--- lockd/svc.c 12 Jul 2006 19:53:39 -0000 1.1.1.4
+++ lockd/svc.c 13 Oct 2006 04:03:13 -0000
@@ -34,6 +34,7 @@
#include <linux/sunrpc/svcsock.h>
#include <linux/lockd/lockd.h>
#include <linux/nfs.h>
+#include <linux/nfsd/nfsd.h>
#define NLMDBG_FACILITY NLMDBG_SVC
#define LOCKD_BUFSIZE (1024 + NLMSVC_XDRSIZE)
@@ -320,6 +321,43 @@
}
EXPORT_SYMBOL(lockd_down);
+int
+nlmsvc_dispatch(struct svc_rqst *rqstp, u32 *statp)
+{
+ struct svc_procedure *procp;
+ kxdrproc_t xdr;
+ struct kvec * argv = &rqstp->rq_arg.head[0];
+ struct kvec * resv = &rqstp->rq_res.head[0];
+
+ dprintk("lockd: nlmsvc_dispatch vers %d proc %d\n",
+ rqstp->rq_vers, rqstp->rq_proc);
+
+ procp = rqstp->rq_procinfo;
+
+ /* Decode arguments */
+ xdr = procp->pc_decode;
+
+ if (xdr && !xdr(rqstp, argv->iov_base, rqstp->rq_argp)) {
+ dprintk("lockd: failed to decode arguments!\n");
+ *statp = rpc_garbage_args;
+ return 1;
+ }
+ /* Now call the procedure handler, and encode status. */
+ *statp = procp->pc_func(rqstp, rqstp->rq_argp, rqstp->rq_resp);
+ if (((struct nlm_res *)(rqstp->rq_resp))->status == nfserr_dropit) {
+ dprintk("lockd: dropping request!\n");
+ return 0;
+ }
+ /* Encode reply */
+ if (*statp == rpc_success && (xdr = procp->pc_encode)
+ && !xdr(rqstp, resv->iov_base+resv->iov_len, rqstp->rq_resp)) {
+ dprintk("lockd: failed to encode reply\n");
+ /* serv->sv_stats->rpcsystemerr++; */
+ *statp = rpc_system_err;
+ }
+ return 1;
+}
+
/*
* Sysctl parameters (same as module parameters, different interface).
*/
@@ -484,12 +522,14 @@
.vs_vers = 1,
.vs_nproc = 17,
.vs_proc = nlmsvc_procedures,
+ .vs_dispatch = nlmsvc_dispatch,
.vs_xdrsize = NLMSVC_XDRSIZE,
};
static struct svc_version nlmsvc_version3 = {
.vs_vers = 3,
.vs_nproc = 24,
.vs_proc = nlmsvc_procedures,
+ .vs_dispatch = nlmsvc_dispatch,
.vs_xdrsize = NLMSVC_XDRSIZE,
};
#ifdef CONFIG_LOCKD_V4
@@ -497,6 +537,7 @@
.vs_vers = 4,
.vs_nproc = 24,
.vs_proc = nlmsvc_procedures4,
+ .vs_dispatch = nlmsvc_dispatch,
.vs_xdrsize = NLMSVC_XDRSIZE,
};
#endif
Index: lockd/svcsubs.c
===================================================================
RCS file: /cvs/nfsv4/cvs/pnfs/fs/lockd/svcsubs.c,v
retrieving revision 1.1.1.4
diff -u -r1.1.1.4 svcsubs.c
--- lockd/svcsubs.c 12 Jul 2006 19:53:39 -0000 1.1.1.4
+++ lockd/svcsubs.c 13 Oct 2006 04:03:13 -0000
@@ -16,6 +16,7 @@
#include <linux/sunrpc/clnt.h>
#include <linux/nfsd/nfsfh.h>
#include <linux/nfsd/export.h>
+#include <linux/nfsd/nfsd.h>
#include <linux/lockd/lockd.h>
#include <linux/lockd/share.h>
#include <linux/lockd/sm_inter.h>
@@ -136,12 +137,14 @@
out_free:
kfree(file);
+ if (nfserr != nfserr_dropit) {
#ifdef CONFIG_LOCKD_V4
- if (nfserr == 1)
- nfserr = nlm4_stale_fh;
- else
+ if (nfserr == 1)
+ nfserr = nlm4_stale_fh;
+ else
#endif
- nfserr = nlm_lck_denied;
+ nfserr = nlm_lck_denied;
+ }
goto out_unlock;
}
Index: nfsd/lockd.c
===================================================================
RCS file: /cvs/nfsv4/cvs/pnfs/fs/nfsd/lockd.c,v
retrieving revision 1.1.1.3
diff -u -r1.1.1.3 lockd.c
--- nfsd/lockd.c 4 Apr 2006 17:55:25 -0000 1.1.1.3
+++ nfsd/lockd.c 13 Oct 2006 04:03:14 -0000
@@ -49,6 +49,8 @@
return 0;
case nfserr_stale:
return 1;
+ case nfserr_dropit:
+ return nfserr;
default:
return 2;
}
-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
NFS maillist - NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: NLM lock reclaim failure 2006-10-13 5:43 NLM lock reclaim failure Marc Eshel @ 2006-10-13 7:08 ` Neil Brown 2006-10-13 18:22 ` Marc Eshel 0 siblings, 1 reply; 5+ messages in thread From: Neil Brown @ 2006-10-13 7:08 UTC (permalink / raw) To: Marc Eshel; +Cc: Linux NFS Mailing List On Thursday October 12, eshel@almaden.ibm.com wrote: > Hi Trond, > Attached is a tested patch for the bug I posted in the following mail > Marc. Thanks for this patch, for the discovering/understanding the bug. There are a couple of aspects of that patch that I don't really like. One is adding the nlmsvc_dispatch function just to gain a little bit of functionality that the sunrpc layer should probably provide directly. The other is that blurring of nfsd and nlm error codes. The following patch addresses these issues and is essentially a rewrite of you patch. Would you be able to review/test it? It fixed nfsv2 as well which needed and extra little fix. Thanks a lot, NeilBrown ------------------ Allow lockd to drop replys as appropriate. Signed-off-by: Neil Brown <neilb@suse.de> ### Diffstat output ./fs/lockd/svc4proc.c | 12 ++++++------ ./fs/lockd/svcproc.c | 16 +++++++++------- ./fs/lockd/svcsubs.c | 5 ++++- ./fs/nfsd/lockd.c | 3 +++ ./include/linux/lockd/xdr.h | 2 ++ ./include/linux/sunrpc/msg_prot.h | 4 +++- ./include/linux/sunrpc/xdr.h | 1 + ./net/sunrpc/svc.c | 5 +++++ 8 files changed, 33 insertions(+), 15 deletions(-) diff .prev/fs/lockd/svc4proc.c ./fs/lockd/svc4proc.c --- .prev/fs/lockd/svc4proc.c 2006-10-13 17:01:33.000000000 +1000 +++ ./fs/lockd/svc4proc.c 2006-10-13 17:02:43.000000000 +1000 @@ -96,7 +96,7 @@ nlm4svc_proc_test(struct svc_rqst *rqstp /* Obtain client and file */ if ((resp->status = nlm4svc_retrieve_args(rqstp, argp, &host, &file))) - return rpc_success; + return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; /* Now check for conflicting locks */ resp->status = nlmsvc_testlock(file, &argp->lock, &resp->lock); @@ -126,7 +126,7 @@ nlm4svc_proc_lock(struct svc_rqst *rqstp /* Obtain client and file */ if ((resp->status = nlm4svc_retrieve_args(rqstp, argp, &host, &file))) - return rpc_success; + return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; #if 0 /* If supplied state doesn't match current state, we assume it's @@ -169,7 +169,7 @@ nlm4svc_proc_cancel(struct svc_rqst *rqs /* Obtain client and file */ if ((resp->status = nlm4svc_retrieve_args(rqstp, argp, &host, &file))) - return rpc_success; + return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; /* Try to cancel request. */ resp->status = nlmsvc_cancel_blocked(file, &argp->lock); @@ -202,7 +202,7 @@ nlm4svc_proc_unlock(struct svc_rqst *rqs /* Obtain client and file */ if ((resp->status = nlm4svc_retrieve_args(rqstp, argp, &host, &file))) - return rpc_success; + return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; /* Now try to remove the lock */ resp->status = nlmsvc_unlock(file, &argp->lock); @@ -339,7 +339,7 @@ nlm4svc_proc_share(struct svc_rqst *rqst /* Obtain client and file */ if ((resp->status = nlm4svc_retrieve_args(rqstp, argp, &host, &file))) - return rpc_success; + return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; /* Now try to create the share */ resp->status = nlmsvc_share_file(host, file, argp); @@ -372,7 +372,7 @@ nlm4svc_proc_unshare(struct svc_rqst *rq /* Obtain client and file */ if ((resp->status = nlm4svc_retrieve_args(rqstp, argp, &host, &file))) - return rpc_success; + return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; /* Now try to lock the file */ resp->status = nlmsvc_unshare_file(host, file, argp); diff .prev/fs/lockd/svcproc.c ./fs/lockd/svcproc.c --- .prev/fs/lockd/svcproc.c 2006-10-13 17:01:33.000000000 +1000 +++ ./fs/lockd/svcproc.c 2006-10-13 17:02:43.000000000 +1000 @@ -59,7 +59,7 @@ nlmsvc_retrieve_args(struct svc_rqst *rq struct nlm_host *host = NULL; struct nlm_file *file = NULL; struct nlm_lock *lock = &argp->lock; - u32 error; + u32 error = 0; /* nfsd callbacks must have been installed for this procedure */ if (!nlmsvc_ops) @@ -88,6 +88,8 @@ nlmsvc_retrieve_args(struct svc_rqst *rq no_locks: if (host) nlm_release_host(host); + if (error) + return error; return nlm_lck_denied_nolocks; } @@ -122,7 +124,7 @@ nlmsvc_proc_test(struct svc_rqst *rqstp, /* Obtain client and file */ if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file))) - return rpc_success; + return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; /* Now check for conflicting locks */ resp->status = cast_status(nlmsvc_testlock(file, &argp->lock, &resp->lock)); @@ -153,7 +155,7 @@ nlmsvc_proc_lock(struct svc_rqst *rqstp, /* Obtain client and file */ if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file))) - return rpc_success; + return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; #if 0 /* If supplied state doesn't match current state, we assume it's @@ -196,7 +198,7 @@ nlmsvc_proc_cancel(struct svc_rqst *rqst /* Obtain client and file */ if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file))) - return rpc_success; + return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; /* Try to cancel request. */ resp->status = cast_status(nlmsvc_cancel_blocked(file, &argp->lock)); @@ -229,7 +231,7 @@ nlmsvc_proc_unlock(struct svc_rqst *rqst /* Obtain client and file */ if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file))) - return rpc_success; + return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; /* Now try to remove the lock */ resp->status = cast_status(nlmsvc_unlock(file, &argp->lock)); @@ -368,7 +370,7 @@ nlmsvc_proc_share(struct svc_rqst *rqstp /* Obtain client and file */ if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file))) - return rpc_success; + return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; /* Now try to create the share */ resp->status = cast_status(nlmsvc_share_file(host, file, argp)); @@ -401,7 +403,7 @@ nlmsvc_proc_unshare(struct svc_rqst *rqs /* Obtain client and file */ if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file))) - return rpc_success; + return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; /* Now try to unshare the file */ resp->status = cast_status(nlmsvc_unshare_file(host, file, argp)); diff .prev/fs/lockd/svcsubs.c ./fs/lockd/svcsubs.c --- .prev/fs/lockd/svcsubs.c 2006-10-13 17:02:07.000000000 +1000 +++ ./fs/lockd/svcsubs.c 2006-10-13 17:02:43.000000000 +1000 @@ -140,7 +140,10 @@ out_free: nfserr = nlm4_stale_fh; else #endif - nfserr = nlm_lck_denied; + if (nfserr == 3) + nfserr = nlm_drop_reply; + else + nfserr = nlm_lck_denied; goto out_unlock; } diff .prev/fs/nfsd/lockd.c ./fs/nfsd/lockd.c --- .prev/fs/nfsd/lockd.c 2006-10-13 17:01:33.000000000 +1000 +++ ./fs/nfsd/lockd.c 2006-10-13 17:02:43.000000000 +1000 @@ -43,12 +43,15 @@ nlm_fopen(struct svc_rqst *rqstp, struct * we invent: 0 = no error * 1 = stale file handle * 2 = other error + * 3 = try again later */ switch (nfserr) { case nfs_ok: return 0; case nfserr_stale: return 1; + case nfserr_dropit: + return 3; default: return 2; } diff .prev/include/linux/lockd/xdr.h ./include/linux/lockd/xdr.h --- .prev/include/linux/lockd/xdr.h 2006-10-13 17:01:33.000000000 +1000 +++ ./include/linux/lockd/xdr.h 2006-10-13 17:02:43.000000000 +1000 @@ -22,6 +22,8 @@ #define nlm_lck_blocked __constant_htonl(NLM_LCK_BLOCKED) #define nlm_lck_denied_grace_period __constant_htonl(NLM_LCK_DENIED_GRACE_PERIOD) +#define nlm_drop_reply __constant_htonl(30000) + /* Lock info passed via NLM */ struct nlm_lock { char * caller; diff .prev/include/linux/sunrpc/msg_prot.h ./include/linux/sunrpc/msg_prot.h --- .prev/include/linux/sunrpc/msg_prot.h 2006-10-13 17:01:33.000000000 +1000 +++ ./include/linux/sunrpc/msg_prot.h 2006-10-13 17:02:43.000000000 +1000 @@ -56,7 +56,9 @@ enum rpc_accept_stat { RPC_PROG_MISMATCH = 2, RPC_PROC_UNAVAIL = 3, RPC_GARBAGE_ARGS = 4, - RPC_SYSTEM_ERR = 5 + RPC_SYSTEM_ERR = 5, + /* internal use only */ + RPC_DROP_REPLY = 60000, }; enum rpc_reject_stat { diff .prev/include/linux/sunrpc/xdr.h ./include/linux/sunrpc/xdr.h --- .prev/include/linux/sunrpc/xdr.h 2006-10-13 17:01:33.000000000 +1000 +++ ./include/linux/sunrpc/xdr.h 2006-10-13 17:02:43.000000000 +1000 @@ -74,6 +74,7 @@ struct xdr_buf { #define rpc_proc_unavail __constant_htonl(RPC_PROC_UNAVAIL) #define rpc_garbage_args __constant_htonl(RPC_GARBAGE_ARGS) #define rpc_system_err __constant_htonl(RPC_SYSTEM_ERR) +#define rpc_drop_reply __constant_htonl(RPC_DROP_REPLY) #define rpc_auth_ok __constant_htonl(RPC_AUTH_OK) #define rpc_autherr_badcred __constant_htonl(RPC_AUTH_BADCRED) diff .prev/net/sunrpc/svc.c ./net/sunrpc/svc.c --- .prev/net/sunrpc/svc.c 2006-10-13 17:01:33.000000000 +1000 +++ ./net/sunrpc/svc.c 2006-10-13 17:02:43.000000000 +1000 @@ -825,6 +825,11 @@ svc_process(struct svc_rqst *rqstp) *statp = procp->pc_func(rqstp, rqstp->rq_argp, rqstp->rq_resp); /* Encode reply */ + if (*statp == rpc_drop_reply) { + if (procp->pc_release) + procp->pc_release(rqstp, NULL, rqstp->rq_resp); + goto dropit; + } if (*statp == rpc_success && (xdr = procp->pc_encode) && !xdr(rqstp, resv->iov_base+resv->iov_len, rqstp->rq_resp)) { dprintk("svc: failed to encode reply\n"); ------------------------------------------------------------------------- Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 _______________________________________________ NFS maillist - NFS@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/nfs ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: NLM lock reclaim failure 2006-10-13 7:08 ` Neil Brown @ 2006-10-13 18:22 ` Marc Eshel 2006-10-16 23:17 ` Neil Brown 0 siblings, 1 reply; 5+ messages in thread From: Marc Eshel @ 2006-10-13 18:22 UTC (permalink / raw) To: Neil Brown; +Cc: Linux NFS Mailing List nfs-bounces@lists.sourceforge.net wrote on 10/13/2006 12:08:39 AM: > On Thursday October 12, eshel@almaden.ibm.com wrote: > > Hi Trond, > > Attached is a tested patch for the bug I posted in the following mail > > Marc. > > Thanks for this patch, for the discovering/understanding the bug. > > There are a couple of aspects of that patch that I don't really like. > > One is adding the nlmsvc_dispatch function just to gain a little bit > of functionality that the sunrpc layer should probably provide > directly. > > The other is that blurring of nfsd and nlm error codes. Your patch is much cleaner with exception of using hard coded return codes in nlm_fopen(). > > The following patch addresses these issues and is essentially a > rewrite of you patch. > > Would you be able to review/test it? > Yes, I tested it and it fixes the problem. hope to see it in the kernel soon. Thanks, Marc > It fixed nfsv2 as well which needed and extra little fix. > > Thanks a lot, > NeilBrown > > ------------------ > Allow lockd to drop replys as appropriate. > > Signed-off-by: Neil Brown <neilb@suse.de> > > ### Diffstat output > ./fs/lockd/svc4proc.c | 12 ++++++------ > ./fs/lockd/svcproc.c | 16 +++++++++------- > ./fs/lockd/svcsubs.c | 5 ++++- > ./fs/nfsd/lockd.c | 3 +++ > ./include/linux/lockd/xdr.h | 2 ++ > ./include/linux/sunrpc/msg_prot.h | 4 +++- > ./include/linux/sunrpc/xdr.h | 1 + > ./net/sunrpc/svc.c | 5 +++++ > 8 files changed, 33 insertions(+), 15 deletions(-) > > diff .prev/fs/lockd/svc4proc.c ./fs/lockd/svc4proc.c > --- .prev/fs/lockd/svc4proc.c 2006-10-13 17:01:33.000000000 +1000 > +++ ./fs/lockd/svc4proc.c 2006-10-13 17:02:43.000000000 +1000 > @@ -96,7 +96,7 @@ nlm4svc_proc_test(struct svc_rqst *rqstp > > /* Obtain client and file */ > if ((resp->status = nlm4svc_retrieve_args(rqstp, argp, &host, &file))) > - return rpc_success; > + return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; > > /* Now check for conflicting locks */ > resp->status = nlmsvc_testlock(file, &argp->lock, &resp->lock); > @@ -126,7 +126,7 @@ nlm4svc_proc_lock(struct svc_rqst *rqstp > > /* Obtain client and file */ > if ((resp->status = nlm4svc_retrieve_args(rqstp, argp, &host, &file))) > - return rpc_success; > + return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; > > #if 0 > /* If supplied state doesn't match current state, we assume it's > @@ -169,7 +169,7 @@ nlm4svc_proc_cancel(struct svc_rqst *rqs > > /* Obtain client and file */ > if ((resp->status = nlm4svc_retrieve_args(rqstp, argp, &host, &file))) > - return rpc_success; > + return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; > > /* Try to cancel request. */ > resp->status = nlmsvc_cancel_blocked(file, &argp->lock); > @@ -202,7 +202,7 @@ nlm4svc_proc_unlock(struct svc_rqst *rqs > > /* Obtain client and file */ > if ((resp->status = nlm4svc_retrieve_args(rqstp, argp, &host, &file))) > - return rpc_success; > + return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; > > /* Now try to remove the lock */ > resp->status = nlmsvc_unlock(file, &argp->lock); > @@ -339,7 +339,7 @@ nlm4svc_proc_share(struct svc_rqst *rqst > > /* Obtain client and file */ > if ((resp->status = nlm4svc_retrieve_args(rqstp, argp, &host, &file))) > - return rpc_success; > + return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; > > /* Now try to create the share */ > resp->status = nlmsvc_share_file(host, file, argp); > @@ -372,7 +372,7 @@ nlm4svc_proc_unshare(struct svc_rqst *rq > > /* Obtain client and file */ > if ((resp->status = nlm4svc_retrieve_args(rqstp, argp, &host, &file))) > - return rpc_success; > + return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; > > /* Now try to lock the file */ > resp->status = nlmsvc_unshare_file(host, file, argp); > > diff .prev/fs/lockd/svcproc.c ./fs/lockd/svcproc.c > --- .prev/fs/lockd/svcproc.c 2006-10-13 17:01:33.000000000 +1000 > +++ ./fs/lockd/svcproc.c 2006-10-13 17:02:43.000000000 +1000 > @@ -59,7 +59,7 @@ nlmsvc_retrieve_args(struct svc_rqst *rq > struct nlm_host *host = NULL; > struct nlm_file *file = NULL; > struct nlm_lock *lock = &argp->lock; > - u32 error; > + u32 error = 0; > > /* nfsd callbacks must have been installed for this procedure */ > if (!nlmsvc_ops) > @@ -88,6 +88,8 @@ nlmsvc_retrieve_args(struct svc_rqst *rq > no_locks: > if (host) > nlm_release_host(host); > + if (error) > + return error; > return nlm_lck_denied_nolocks; > } > > @@ -122,7 +124,7 @@ nlmsvc_proc_test(struct svc_rqst *rqstp, > > /* Obtain client and file */ > if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file))) > - return rpc_success; > + return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; > > /* Now check for conflicting locks */ > resp->status = cast_status(nlmsvc_testlock(file, &argp->lock, > &resp->lock)); > @@ -153,7 +155,7 @@ nlmsvc_proc_lock(struct svc_rqst *rqstp, > > /* Obtain client and file */ > if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file))) > - return rpc_success; > + return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; > > #if 0 > /* If supplied state doesn't match current state, we assume it's > @@ -196,7 +198,7 @@ nlmsvc_proc_cancel(struct svc_rqst *rqst > > /* Obtain client and file */ > if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file))) > - return rpc_success; > + return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; > > /* Try to cancel request. */ > resp->status = cast_status(nlmsvc_cancel_blocked(file, &argp->lock)); > @@ -229,7 +231,7 @@ nlmsvc_proc_unlock(struct svc_rqst *rqst > > /* Obtain client and file */ > if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file))) > - return rpc_success; > + return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; > > /* Now try to remove the lock */ > resp->status = cast_status(nlmsvc_unlock(file, &argp->lock)); > @@ -368,7 +370,7 @@ nlmsvc_proc_share(struct svc_rqst *rqstp > > /* Obtain client and file */ > if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file))) > - return rpc_success; > + return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; > > /* Now try to create the share */ > resp->status = cast_status(nlmsvc_share_file(host, file, argp)); > @@ -401,7 +403,7 @@ nlmsvc_proc_unshare(struct svc_rqst *rqs > > /* Obtain client and file */ > if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file))) > - return rpc_success; > + return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; > > /* Now try to unshare the file */ > resp->status = cast_status(nlmsvc_unshare_file(host, file, argp)); > > diff .prev/fs/lockd/svcsubs.c ./fs/lockd/svcsubs.c > --- .prev/fs/lockd/svcsubs.c 2006-10-13 17:02:07.000000000 +1000 > +++ ./fs/lockd/svcsubs.c 2006-10-13 17:02:43.000000000 +1000 > @@ -140,7 +140,10 @@ out_free: > nfserr = nlm4_stale_fh; > else > #endif > - nfserr = nlm_lck_denied; > + if (nfserr == 3) > + nfserr = nlm_drop_reply; > + else > + nfserr = nlm_lck_denied; > goto out_unlock; > } > > > diff .prev/fs/nfsd/lockd.c ./fs/nfsd/lockd.c > --- .prev/fs/nfsd/lockd.c 2006-10-13 17:01:33.000000000 +1000 > +++ ./fs/nfsd/lockd.c 2006-10-13 17:02:43.000000000 +1000 > @@ -43,12 +43,15 @@ nlm_fopen(struct svc_rqst *rqstp, struct > * we invent: 0 = no error > * 1 = stale file handle > * 2 = other error > + * 3 = try again later > */ > switch (nfserr) { > case nfs_ok: > return 0; > case nfserr_stale: > return 1; > + case nfserr_dropit: > + return 3; > default: > return 2; > } > > diff .prev/include/linux/lockd/xdr.h ./include/linux/lockd/xdr.h > --- .prev/include/linux/lockd/xdr.h 2006-10-13 17:01:33.000000000 +1000 > +++ ./include/linux/lockd/xdr.h 2006-10-13 17:02:43.000000000 +1000 > @@ -22,6 +22,8 @@ > #define nlm_lck_blocked __constant_htonl(NLM_LCK_BLOCKED) > #define nlm_lck_denied_grace_period > __constant_htonl(NLM_LCK_DENIED_GRACE_PERIOD) > > +#define nlm_drop_reply __constant_htonl(30000) > + > /* Lock info passed via NLM */ > struct nlm_lock { > char * caller; > > diff .prev/include/linux/sunrpc/msg_prot.h ./include/linux/sunrpc/msg_prot.h > --- .prev/include/linux/sunrpc/msg_prot.h 2006-10-13 17:01:33. > 000000000 +1000 > +++ ./include/linux/sunrpc/msg_prot.h 2006-10-13 17:02:43.000000000 +1000 > @@ -56,7 +56,9 @@ enum rpc_accept_stat { > RPC_PROG_MISMATCH = 2, > RPC_PROC_UNAVAIL = 3, > RPC_GARBAGE_ARGS = 4, > - RPC_SYSTEM_ERR = 5 > + RPC_SYSTEM_ERR = 5, > + /* internal use only */ > + RPC_DROP_REPLY = 60000, > }; > > enum rpc_reject_stat { > > diff .prev/include/linux/sunrpc/xdr.h ./include/linux/sunrpc/xdr.h > --- .prev/include/linux/sunrpc/xdr.h 2006-10-13 17:01:33.000000000 +1000 > +++ ./include/linux/sunrpc/xdr.h 2006-10-13 17:02:43.000000000 +1000 > @@ -74,6 +74,7 @@ struct xdr_buf { > #define rpc_proc_unavail __constant_htonl(RPC_PROC_UNAVAIL) > #define rpc_garbage_args __constant_htonl(RPC_GARBAGE_ARGS) > #define rpc_system_err __constant_htonl(RPC_SYSTEM_ERR) > +#define rpc_drop_reply __constant_htonl(RPC_DROP_REPLY) > > #define rpc_auth_ok __constant_htonl(RPC_AUTH_OK) > #define rpc_autherr_badcred __constant_htonl(RPC_AUTH_BADCRED) > > diff .prev/net/sunrpc/svc.c ./net/sunrpc/svc.c > --- .prev/net/sunrpc/svc.c 2006-10-13 17:01:33.000000000 +1000 > +++ ./net/sunrpc/svc.c 2006-10-13 17:02:43.000000000 +1000 > @@ -825,6 +825,11 @@ svc_process(struct svc_rqst *rqstp) > *statp = procp->pc_func(rqstp, rqstp->rq_argp, rqstp->rq_resp); > > /* Encode reply */ > + if (*statp == rpc_drop_reply) { > + if (procp->pc_release) > + procp->pc_release(rqstp, NULL, rqstp->rq_resp); > + goto dropit; > + } > if (*statp == rpc_success && (xdr = procp->pc_encode) > && !xdr(rqstp, resv->iov_base+resv->iov_len, rqstp->rq_resp)) { > dprintk("svc: failed to encode reply\n"); > > ------------------------------------------------------------------------- > Using Tomcat but need to do more? Need to support web services, security? > Get stuff done quickly with pre-integrated technology to make your job easier > Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo > http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 > _______________________________________________ > NFS maillist - NFS@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/nfs ------------------------------------------------------------------------- Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 _______________________________________________ NFS maillist - NFS@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/nfs ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: NLM lock reclaim failure 2006-10-13 18:22 ` Marc Eshel @ 2006-10-16 23:17 ` Neil Brown 0 siblings, 0 replies; 5+ messages in thread From: Neil Brown @ 2006-10-16 23:17 UTC (permalink / raw) To: Marc Eshel; +Cc: Linux NFS Mailing List On Friday October 13, eshel@almaden.ibm.com wrote: > > > > The other is that blurring of nfsd and nlm error codes. > > Your patch is much cleaner with exception of using hard coded return codes > in nlm_fopen(). > Yes.. fair comment. I'll change nlm_fopen to return nlm error codes. That makes it much nicer. > > > > The following patch addresses these issues and is essentially a > > rewrite of you patch. > > > > Would you be able to review/test it? > > > > Yes, I tested it and it fixes the problem. hope to see it in the kernel > soon. > Thanks, Marc Thanks. I'll send it to Andrew shortly. NeilBrown ------------------------------------------------------------------------- Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 _______________________________________________ NFS maillist - NFS@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/nfs ^ permalink raw reply [flat|nested] 5+ messages in thread
* NLM lock reclaim failure @ 2006-10-11 23:28 Marc Eshel 0 siblings, 0 replies; 5+ messages in thread From: Marc Eshel @ 2006-10-11 23:28 UTC (permalink / raw) To: Linux NFS Mailing List I see an NLM lock reclaim failure (using 2.6.17). Let me describe the simple case first. 1. Client gets an NLM lock 2. Server reboots 3. Client sends lock reclaim request 4. On server, nlm_open() gets return code nfserr_dropit; error gets converted to nlm_lck_denied by nlm_lookup_file(). 5. Client gets status=1, the lock reclaim failed This happens _only_ when the first call to nfsd (fh_verify -> exp_find) comes from lockd trying to find the file. Subsequent calls seem to work. nlm_lookup_file() -> nlm_fopen() -> nfsd_open() -> fh_verify() -> exp_find() returns nfserr_dropit This problem may be related to the following commit to lockd (Trond's tree): commit: 26bcbf965f857c710adafd16cf424f043006b5dd lockd: stop abusing file_lock_list The client earlier retained the list of outstanding locks regardless of reclaim return code. The change above removes all locks from the list and only adds them back after a successful reclaim. Since the reclaim fails, it is removed from the list; so the client will not try to reclaim the lock on a second failure. Note that the problem is not on the client side - it seems the server that should drop the rpc when it gets nfserr_dropit error and not convert it to an nlm_lck_denied. It get even more complicated - when the server doesn't respond immediately to the reclaim, client will retry the rpc, on the second reclaim call, the server will grant the lock to the client but since the client already got the nlm_lck_denied from the first call, it has dropped it from it list. So now we have a lock on the server for a client that doesn't know that it holds the lock. Marc. ------------------------------------------------------------------------- Using Tomcat but need to do more? Need to support web services, security? Get stuff done quickly with pre-integrated technology to make your job easier Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642 _______________________________________________ NFS maillist - NFS@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/nfs ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2006-10-16 23:17 UTC | newest] Thread overview: 5+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2006-10-13 5:43 NLM lock reclaim failure Marc Eshel 2006-10-13 7:08 ` Neil Brown 2006-10-13 18:22 ` Marc Eshel 2006-10-16 23:17 ` Neil Brown -- strict thread matches above, loose matches on Subject: below -- 2006-10-11 23:28 Marc Eshel
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox