aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfs4state.c
diff options
context:
space:
mode:
authorAndy Adamson <andros@citi.umich.edu>2006-03-26 04:37:26 -0500
committerLinus Torvalds <torvalds@g5.osdl.org>2006-03-26 11:56:56 -0500
commiteb76b3fda1f7c2aa2d1523b36835048a15e5e5d2 (patch)
tree4a120685e7c1a3762a4da73d29327871f310a914 /fs/nfsd/nfs4state.c
parent5842add2f3b519111b6401f3a35862bd00a3aa7e (diff)
[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/nfs4state.c')
-rw-r--r--fs/nfsd/nfs4state.c38
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
2750 * Note: locks.c uses the BKL to protect the inode's lock list. 2750 * Note: locks.c uses the BKL to protect the inode's lock list.
2751 */ 2751 */
2752 2752
2753 status = posix_lock_file(filp, &file_lock); 2753 /* XXX?: Just to divert the locks_release_private at the start of
2754 dprintk("NFSD: nfsd4_lock: posix_lock_file status %d\n",status); 2754 * locks_copy_lock: */
2755 conflock.fl_ops = NULL;
2756 conflock.fl_lmops = NULL;
2757 status = posix_lock_file_conf(filp, &file_lock, &conflock);
2758 dprintk("NFSD: nfsd4_lock: posix_lock_file_conf status %d\n",status);
2755 switch (-status) { 2759 switch (-status) {
2756 case 0: /* success! */ 2760 case 0: /* success! */
2757 update_stateid(&lock_stp->st_stateid); 2761 update_stateid(&lock_stp->st_stateid);
2758 memcpy(&lock->lk_resp_stateid, &lock_stp->st_stateid, 2762 memcpy(&lock->lk_resp_stateid, &lock_stp->st_stateid,
2759 sizeof(stateid_t)); 2763 sizeof(stateid_t));
2760 goto out; 2764 break;
2761 case (EAGAIN): 2765 case (EAGAIN): /* conflock holds conflicting lock */
2762 goto conflicting_lock; 2766 status = nfserr_denied;
2767 dprintk("NFSD: nfsd4_lock: conflicting lock found!\n");
2768 nfs4_set_lock_denied(&conflock, &lock->lk_denied);
2769 break;
2763 case (EDEADLK): 2770 case (EDEADLK):
2764 status = nfserr_deadlock; 2771 status = nfserr_deadlock;
2765 dprintk("NFSD: nfsd4_lock: posix_lock_file() failed! status %d\n",status); 2772 break;
2766 goto out;
2767 default: 2773 default:
2768 status = nfserrno(status); 2774 dprintk("NFSD: nfsd4_lock: posix_lock_file_conf() failed! status %d\n",status);
2769 dprintk("NFSD: nfsd4_lock: posix_lock_file() failed! status %d\n",status); 2775 status = nfserr_resource;
2770 goto out; 2776 break;
2771 }
2772
2773conflicting_lock:
2774 dprintk("NFSD: nfsd4_lock: conflicting lock found!\n");
2775 status = nfserr_denied;
2776 /* XXX There is a race here. Future patch needed to provide
2777 * an atomic posix_lock_and_test_file
2778 */
2779 if (!posix_test_lock(filp, &file_lock, &conflock)) {
2780 status = nfserr_serverfault;
2781 goto out;
2782 } 2777 }
2783 nfs4_set_lock_denied(&conflock, &lock->lk_denied);
2784out: 2778out:
2785 if (status && lock->lk_is_new && lock_sop) 2779 if (status && lock->lk_is_new && lock_sop)
2786 release_stateowner(lock_sop); 2780 release_stateowner(lock_sop);