diff options
author | 2006-03-26 01:37:26 -0800 | |
---|---|---|
committer | 2006-03-26 08:56:56 -0800 | |
commit | eb76b3fda1f7c2aa2d1523b36835048a15e5e5d2 (patch) | |
tree | 4a120685e7c1a3762a4da73d29327871f310a914 /fs/nfsd | |
parent | [PATCH] VFS,fs/locks.c,NFSD4: add race_free posix_lock_file_conf() interface (diff) | |
download | linux-eb76b3fda1f7c2aa2d1523b36835048a15e5e5d2.tar.gz linux-eb76b3fda1f7c2aa2d1523b36835048a15e5e5d2.tar.bz2 linux-eb76b3fda1f7c2aa2d1523b36835048a15e5e5d2.zip |
[PATCH] NFSD4: return conflict lock without races
Update the NFSv4 server to use the new posix_lock_file_conf() interface.
Remove unnecessary (and race-prone) posix_test_file() calls.
Signed-off-by: Andy Adamson <andros@citi.umich.edu>
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Cc: Neil Brown <neilb@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/nfsd')
-rw-r--r-- | fs/nfsd/nfs4state.c | 38 |
1 files changed, 16 insertions, 22 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index c7b87e92f91b..47ec112b266c 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -2750,37 +2750,31 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock * Note: locks.c uses the BKL to protect the inode's lock list. */ - status = posix_lock_file(filp, &file_lock); - dprintk("NFSD: nfsd4_lock: posix_lock_file status %d\n",status); + /* XXX?: Just to divert the locks_release_private at the start of + * locks_copy_lock: */ + conflock.fl_ops = NULL; + conflock.fl_lmops = NULL; + status = posix_lock_file_conf(filp, &file_lock, &conflock); + dprintk("NFSD: nfsd4_lock: posix_lock_file_conf status %d\n",status); switch (-status) { case 0: /* success! */ update_stateid(&lock_stp->st_stateid); memcpy(&lock->lk_resp_stateid, &lock_stp->st_stateid, sizeof(stateid_t)); - goto out; - case (EAGAIN): - goto conflicting_lock; + break; + case (EAGAIN): /* conflock holds conflicting lock */ + status = nfserr_denied; + dprintk("NFSD: nfsd4_lock: conflicting lock found!\n"); + nfs4_set_lock_denied(&conflock, &lock->lk_denied); + break; case (EDEADLK): status = nfserr_deadlock; - dprintk("NFSD: nfsd4_lock: posix_lock_file() failed! status %d\n",status); - goto out; + break; default: - status = nfserrno(status); - dprintk("NFSD: nfsd4_lock: posix_lock_file() failed! status %d\n",status); - goto out; - } - -conflicting_lock: - dprintk("NFSD: nfsd4_lock: conflicting lock found!\n"); - status = nfserr_denied; - /* XXX There is a race here. Future patch needed to provide - * an atomic posix_lock_and_test_file - */ - if (!posix_test_lock(filp, &file_lock, &conflock)) { - status = nfserr_serverfault; - goto out; + dprintk("NFSD: nfsd4_lock: posix_lock_file_conf() failed! status %d\n",status); + status = nfserr_resource; + break; } - nfs4_set_lock_denied(&conflock, &lock->lk_denied); out: if (status && lock->lk_is_new && lock_sop) release_stateowner(lock_sop); |