diff options
Diffstat (limited to 'fs/lockd')
| -rw-r--r-- | fs/lockd/lockd.h | 8 | ||||
| -rw-r--r-- | fs/lockd/svc4proc.c | 19 | ||||
| -rw-r--r-- | fs/lockd/svcproc.c | 2 | ||||
| -rw-r--r-- | fs/lockd/svcsubs.c | 7 |
4 files changed, 25 insertions, 11 deletions
diff --git a/fs/lockd/lockd.h b/fs/lockd/lockd.h index 1db6cb352542..9aa6acb43f9a 100644 --- a/fs/lockd/lockd.h +++ b/fs/lockd/lockd.h @@ -52,6 +52,14 @@ */ #define LOCKD_DFLT_TIMEO 10 +/* + * Number of leading bytes of nfs_fh.data that file_hash() + * digests when bucketing nlm_files[]. Sized for historical + * NFSv2 handles; nfs_fh.data must be initialized at least + * this far before lookup, regardless of fh.size. + */ +#define LOCKD_FH_HASH_SIZE 32 + /* error codes new to NLMv4 */ #define nlm4_deadlock cpu_to_be32(NLM_DEADLCK) #define nlm4_rofs cpu_to_be32(NLM_ROFS) diff --git a/fs/lockd/svc4proc.c b/fs/lockd/svc4proc.c index 41cab858de57..f3ba2615ae77 100644 --- a/fs/lockd/svc4proc.c +++ b/fs/lockd/svc4proc.c @@ -157,6 +157,9 @@ nlm4svc_lookup_file(struct svc_rqst *rqstp, struct nlm_host *host, return nlm_lck_denied_nolocks; lock->fh.size = xdr_lock->fh.len; memcpy(lock->fh.data, xdr_lock->fh.data, xdr_lock->fh.len); + if (xdr_lock->fh.len < LOCKD_FH_HASH_SIZE) + memset(lock->fh.data + xdr_lock->fh.len, 0, + LOCKD_FH_HASH_SIZE - xdr_lock->fh.len); lock->oh.len = xdr_lock->oh.len; lock->oh.data = xdr_lock->oh.data; @@ -513,12 +516,12 @@ out: * nlm4_res NLMPROC4_GRANTED(nlm4_testargs) = 5; * * Permissible procedure status codes: - * %NLM4_GRANTED: The requested lock was granted. - * %NLM4_DENIED: The server could not allocate the resources - * needed to process the request. - * %NLM4_DENIED_GRACE_PERIOD: The server has recently restarted and is - * re-establishing existing locks, and is not - * yet ready to accept normal service requests. + * %NLM4_GRANTED: The granted lock was accepted. + * %NLM4_DENIED: The procedure failed, possibly due to + * internal resource constraints. + * %NLM4_DENIED_GRACE_PERIOD: The client host recently restarted and + * its NLM is re-establishing existing locks, + * so it is not yet ready to accept callbacks. */ static __be32 nlm4svc_proc_granted(struct svc_rqst *rqstp) @@ -669,6 +672,8 @@ __nlm4svc_proc_lock_msg(struct svc_rqst *rqstp, struct nlm_res *resp) resp->status = nlmsvc_lock(rqstp, file, host, &argp->lock, argp->xdrgen.block, &resp->cookie, argp->xdrgen.reclaim); + if (resp->status == nlm__int__deadlock) + resp->status = nlm4_deadlock; nlmsvc_release_lockowner(&argp->lock); out: @@ -697,7 +702,7 @@ static __be32 nlm4svc_proc_lock_msg(struct svc_rqst *rqstp) struct nlm4_lockargs_wrapper *argp = rqstp->rq_argp; struct nlm_host *host; - host = nlm4svc_lookup_host(rqstp, argp->xdrgen.alock.caller_name, true); + host = nlm4svc_lookup_host(rqstp, argp->xdrgen.alock.caller_name, false); if (!host) return rpc_system_err; diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c index c0a3487719e2..110e186802b6 100644 --- a/fs/lockd/svcproc.c +++ b/fs/lockd/svcproc.c @@ -49,7 +49,7 @@ static inline __be32 cast_status(__be32 status) status = nlm_lck_denied_nolocks; break; default: - if (be32_to_cpu(status) >= 30000) + if (be32_to_cpu(status) > be32_to_cpu(nlm__int__drop_reply)) pr_warn_once("lockd: unhandled internal status %u\n", be32_to_cpu(status)); break; diff --git a/fs/lockd/svcsubs.c b/fs/lockd/svcsubs.c index 9da9d6e0b42e..c7945282d479 100644 --- a/fs/lockd/svcsubs.c +++ b/fs/lockd/svcsubs.c @@ -17,7 +17,6 @@ #include <linux/sunrpc/addr.h> #include <linux/module.h> #include <linux/mount.h> -#include <uapi/linux/nfs2.h> #include "lockd.h" #include "share.h" @@ -67,7 +66,7 @@ static inline unsigned int file_hash(struct nfs_fh *f) { unsigned int tmp=0; int i; - for (i=0; i<NFS2_FHSIZE;i++) + for (i = 0; i < LOCKD_FH_HASH_SIZE; i++) tmp += f->data[i]; return tmp & (FILE_NRHASH - 1); } @@ -150,6 +149,8 @@ nlm_lookup_file(struct svc_rqst *rqstp, struct nlm_file **result, mutex_lock(&file->f_mutex); nfserr = nlm_do_fopen(rqstp, file, mode); mutex_unlock(&file->f_mutex); + if (nfserr) + goto out_unlock; goto found; } nlm_debug_print_fh("creating file for", &lock->fh); @@ -166,7 +167,7 @@ nlm_lookup_file(struct svc_rqst *rqstp, struct nlm_file **result, nfserr = nlm_do_fopen(rqstp, file, mode); if (nfserr) - goto out_unlock; + goto out_free; hlist_add_head(&file->f_list, &nlm_files[hash]); |
