diff options
author | Jeff Layton <jlayton@primarydata.com> | 2014-07-29 21:34:37 -0400 |
---|---|---|
committer | J. Bruce Fields <bfields@redhat.com> | 2014-07-31 14:20:27 -0400 |
commit | 882e9d25e11d644b24e578866c688d3f8f0d3712 (patch) | |
tree | 06f0f66a6f78fd2f93d326dd81af0da143b15ab0 | |
parent | d4f0489f38512027fdf5190d5d1d8007e155e88f (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.c | 49 |
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); | ||
5481 | out: | 5470 | out: |
5482 | if (sop) | ||
5483 | nfs4_put_stateowner(sop); | ||
5484 | nfs4_unlock_state(); | 5471 | nfs4_unlock_state(); |
5485 | return status; | 5472 | return status; |
5486 | } | 5473 | } |