diff options
author | Andy Adamson <andros@citi.umich.edu> | 2006-03-26 04:37:26 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-03-26 11:56:56 -0500 |
commit | eb76b3fda1f7c2aa2d1523b36835048a15e5e5d2 (patch) | |
tree | 4a120685e7c1a3762a4da73d29327871f310a914 /fs/nfsd/nfs4state.c | |
parent | 5842add2f3b519111b6401f3a35862bd00a3aa7e (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.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 | |||
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 | |||
2773 | conflicting_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); | ||
2784 | out: | 2778 | out: |
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); |