diff options
author | J. Bruce Fields <bfields@citi.umich.edu> | 2006-01-18 20:43:18 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-18 22:20:24 -0500 |
commit | 8a280510852959c0d51b1d625e90c0491c238368 (patch) | |
tree | e24b9167f5f979cc126f07ef32c851ab249a7766 /fs | |
parent | a6f6ef2f1d7329111fcad7db48fb7adba5062d0a (diff) |
[PATCH] nfsd4: fix nfsd4_lock cleanup on failure
release_state_owner also puts the lock owner on the close_lru. There's no
need for that, though; replays of the failed lock would be handled by the
openowner not the lockowner.
Also consolidate the cleanup a bit, fixing leaks that can happen if errors
occur between the time a new lock owner is allocated and the lock is done.
Remove a comment and dprintk that look a little redundant.
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Signed-off-by: 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')
-rw-r--r-- | fs/nfsd/nfs4state.c | 18 |
1 files changed, 4 insertions, 14 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 3d4a2ec97caa..5bf7fd3947ce 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -2744,10 +2744,8 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock | |||
2744 | if (lock_sop == NULL) | 2744 | if (lock_sop == NULL) |
2745 | goto out; | 2745 | goto out; |
2746 | lock_stp = alloc_init_lock_stateid(lock_sop, fp, open_stp); | 2746 | lock_stp = alloc_init_lock_stateid(lock_sop, fp, open_stp); |
2747 | if (lock_stp == NULL) { | 2747 | if (lock_stp == NULL) |
2748 | release_stateowner(lock_sop); | ||
2749 | goto out; | 2748 | goto out; |
2750 | } | ||
2751 | } else { | 2749 | } else { |
2752 | /* lock (lock owner + lock stateid) already exists */ | 2750 | /* lock (lock owner + lock stateid) already exists */ |
2753 | status = nfs4_preprocess_seqid_op(current_fh, | 2751 | status = nfs4_preprocess_seqid_op(current_fh, |
@@ -2815,7 +2813,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock | |||
2815 | status = nfserr_deadlock; | 2813 | status = nfserr_deadlock; |
2816 | default: | 2814 | default: |
2817 | dprintk("NFSD: nfsd4_lock: posix_lock_file() failed! status %d\n",status); | 2815 | dprintk("NFSD: nfsd4_lock: posix_lock_file() failed! status %d\n",status); |
2818 | goto out_destroy_new_stateid; | 2816 | goto out; |
2819 | } | 2817 | } |
2820 | 2818 | ||
2821 | conflicting_lock: | 2819 | conflicting_lock: |
@@ -2829,17 +2827,9 @@ conflicting_lock: | |||
2829 | goto out; | 2827 | goto out; |
2830 | } | 2828 | } |
2831 | nfs4_set_lock_denied(conflock, &lock->lk_denied); | 2829 | nfs4_set_lock_denied(conflock, &lock->lk_denied); |
2832 | |||
2833 | out_destroy_new_stateid: | ||
2834 | if (lock->lk_is_new) { | ||
2835 | dprintk("NFSD: nfsd4_lock: destroy new stateid!\n"); | ||
2836 | /* | ||
2837 | * An error encountered after instantiation of the new | ||
2838 | * stateid has forced us to destroy it. | ||
2839 | */ | ||
2840 | release_state_owner(lock_stp, LOCK_STATE); | ||
2841 | } | ||
2842 | out: | 2830 | out: |
2831 | if (status && lock->lk_is_new && lock_sop) | ||
2832 | release_stateowner(lock_sop); | ||
2843 | if (lock->lk_stateowner) { | 2833 | if (lock->lk_stateowner) { |
2844 | nfs4_get_stateowner(lock->lk_stateowner); | 2834 | nfs4_get_stateowner(lock->lk_stateowner); |
2845 | *replay_owner = lock->lk_stateowner; | 2835 | *replay_owner = lock->lk_stateowner; |