[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>
This commit is contained in:
committed by
Linus Torvalds
parent
a6f6ef2f1d
commit
8a28051085
@@ -2744,10 +2744,8 @@ nfsd4_lock(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfsd4_lock
|
|||||||
if (lock_sop == NULL)
|
if (lock_sop == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
lock_stp = alloc_init_lock_stateid(lock_sop, fp, open_stp);
|
lock_stp = alloc_init_lock_stateid(lock_sop, fp, open_stp);
|
||||||
if (lock_stp == NULL) {
|
if (lock_stp == NULL)
|
||||||
release_stateowner(lock_sop);
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
/* lock (lock owner + lock stateid) already exists */
|
/* lock (lock owner + lock stateid) already exists */
|
||||||
status = nfs4_preprocess_seqid_op(current_fh,
|
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
|
|||||||
status = nfserr_deadlock;
|
status = nfserr_deadlock;
|
||||||
default:
|
default:
|
||||||
dprintk("NFSD: nfsd4_lock: posix_lock_file() failed! status %d\n",status);
|
dprintk("NFSD: nfsd4_lock: posix_lock_file() failed! status %d\n",status);
|
||||||
goto out_destroy_new_stateid;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
conflicting_lock:
|
conflicting_lock:
|
||||||
@@ -2829,17 +2827,9 @@ conflicting_lock:
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
nfs4_set_lock_denied(conflock, &lock->lk_denied);
|
nfs4_set_lock_denied(conflock, &lock->lk_denied);
|
||||||
|
|
||||||
out_destroy_new_stateid:
|
|
||||||
if (lock->lk_is_new) {
|
|
||||||
dprintk("NFSD: nfsd4_lock: destroy new stateid!\n");
|
|
||||||
/*
|
|
||||||
* An error encountered after instantiation of the new
|
|
||||||
* stateid has forced us to destroy it.
|
|
||||||
*/
|
|
||||||
release_state_owner(lock_stp, LOCK_STATE);
|
|
||||||
}
|
|
||||||
out:
|
out:
|
||||||
|
if (status && lock->lk_is_new && lock_sop)
|
||||||
|
release_stateowner(lock_sop);
|
||||||
if (lock->lk_stateowner) {
|
if (lock->lk_stateowner) {
|
||||||
nfs4_get_stateowner(lock->lk_stateowner);
|
nfs4_get_stateowner(lock->lk_stateowner);
|
||||||
*replay_owner = lock->lk_stateowner;
|
*replay_owner = lock->lk_stateowner;
|
||||||
|
Reference in New Issue
Block a user