aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Layton <jlayton@primarydata.com>2014-07-29 21:34:37 -0400
committerJ. Bruce Fields <bfields@redhat.com>2014-07-31 14:20:27 -0400
commit882e9d25e11d644b24e578866c688d3f8f0d3712 (patch)
tree06f0f66a6f78fd2f93d326dd81af0da143b15ab0
parentd4f0489f38512027fdf5190d5d1d8007e155e88f (diff)
nfsd: clean up and reorganize release_lockowner
Do more within the main loop, and simplify the function a bit. Also, there's no need to take a stateowner reference unless we're going to call release_lockowner. Signed-off-by: Jeff Layton <jlayton@primarydata.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
-rw-r--r--fs/nfsd/nfs4state.c49
1 files changed, 18 insertions, 31 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 4af4e5eff491..cd7d7df03afa 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -5424,8 +5424,8 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp,
5424 struct nfsd4_release_lockowner *rlockowner) 5424 struct nfsd4_release_lockowner *rlockowner)
5425{ 5425{
5426 clientid_t *clid = &rlockowner->rl_clientid; 5426 clientid_t *clid = &rlockowner->rl_clientid;
5427 struct nfs4_stateowner *sop = NULL, *tmp; 5427 struct nfs4_stateowner *sop;
5428 struct nfs4_lockowner *lo; 5428 struct nfs4_lockowner *lo = NULL;
5429 struct nfs4_ol_stateid *stp; 5429 struct nfs4_ol_stateid *stp;
5430 struct xdr_netobj *owner = &rlockowner->rl_owner; 5430 struct xdr_netobj *owner = &rlockowner->rl_owner;
5431 unsigned int hashval = ownerstr_hashval(owner); 5431 unsigned int hashval = ownerstr_hashval(owner);
@@ -5442,45 +5442,32 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp,
5442 if (status) 5442 if (status)
5443 goto out; 5443 goto out;
5444 5444
5445 status = nfserr_locks_held;
5446
5447 clp = cstate->clp; 5445 clp = cstate->clp;
5448 /* Find the matching lock stateowner */ 5446 /* Find the matching lock stateowner */
5449 spin_lock(&clp->cl_lock); 5447 spin_lock(&clp->cl_lock);
5450 list_for_each_entry(tmp, &clp->cl_ownerstr_hashtbl[hashval], 5448 list_for_each_entry(sop, &clp->cl_ownerstr_hashtbl[hashval],
5451 so_strhash) { 5449 so_strhash) {
5452 if (tmp->so_is_open_owner)
5453 continue;
5454 if (same_owner_str(tmp, owner)) {
5455 sop = tmp;
5456 atomic_inc(&sop->so_count);
5457 break;
5458 }
5459 }
5460 5450
5461 /* No matching owner found, maybe a replay? Just declare victory... */ 5451 if (sop->so_is_open_owner || !same_owner_str(sop, owner))
5462 if (!sop) { 5452 continue;
5463 spin_unlock(&clp->cl_lock);
5464 status = nfs_ok;
5465 goto out;
5466 }
5467 5453
5468 lo = lockowner(sop); 5454 /* see if there are still any locks associated with it */
5469 /* see if there are still any locks associated with it */ 5455 lo = lockowner(sop);
5470 list_for_each_entry(stp, &sop->so_stateids, st_perstateowner) { 5456 list_for_each_entry(stp, &sop->so_stateids, st_perstateowner) {
5471 if (check_for_locks(stp->st_stid.sc_file, lo)) { 5457 if (check_for_locks(stp->st_stid.sc_file, lo)) {
5472 spin_unlock(&clp->cl_lock); 5458 status = nfserr_locks_held;
5473 goto out; 5459 spin_unlock(&clp->cl_lock);
5460 goto out;
5461 }
5474 } 5462 }
5463
5464 atomic_inc(&sop->so_count);
5465 break;
5475 } 5466 }
5476 spin_unlock(&clp->cl_lock); 5467 spin_unlock(&clp->cl_lock);
5477 5468 if (lo)
5478 status = nfs_ok; 5469 release_lockowner(lo);
5479 sop = NULL;
5480 release_lockowner(lo);
5481out: 5470out:
5482 if (sop)
5483 nfs4_put_stateowner(sop);
5484 nfs4_unlock_state(); 5471 nfs4_unlock_state();
5485 return status; 5472 return status;
5486} 5473}