summaryrefslogtreecommitdiff
path: root/fs/nfsd/nfs4state.c
diff options
context:
space:
mode:
authorJeff Layton <jlayton@primarydata.com>2014-07-30 05:34:31 +0400
committerJ. Bruce Fields <bfields@redhat.com>2014-07-31 22:20:22 +0400
commit5adfd8850ba1463fe675c2df1829fb439e7c7b0f (patch)
tree6dd91ae3921337410f1f4cdd4f92041b61db4fbb /fs/nfsd/nfs4state.c
parente4f1dd7fc23f92efdaaa07d001b3dd5391505580 (diff)
downloadlinux-5adfd8850ba1463fe675c2df1829fb439e7c7b0f.tar.xz
nfsd: clean up refcounting for lockowners
Ensure that lockowner references are only held by lockstateids and operations that are in-progress. With this, we can get rid of release_lockowner_if_empty, which will be racy once we remove client_mutex protection. Signed-off-by: Jeff Layton <jlayton@primarydata.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd/nfs4state.c')
-rw-r--r--fs/nfsd/nfs4state.c29
1 files changed, 7 insertions, 22 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 88225f0bbc12..c86fe66254b0 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -933,7 +933,7 @@ static void nfs4_free_lock_stateid(struct nfs4_stid *stid)
nfs4_free_ol_stateid(stid);
}
-static void __release_lock_stateid(struct nfs4_ol_stateid *stp)
+static void release_lock_stateid(struct nfs4_ol_stateid *stp)
{
struct nfs4_openowner *oo = openowner(stp->st_openstp->st_stateowner);
@@ -957,7 +957,7 @@ static void release_lockowner_stateids(struct nfs4_lockowner *lo)
while (!list_empty(&lo->lo_owner.so_stateids)) {
stp = list_first_entry(&lo->lo_owner.so_stateids,
struct nfs4_ol_stateid, st_perstateowner);
- __release_lock_stateid(stp);
+ release_lock_stateid(stp);
}
}
@@ -968,21 +968,6 @@ static void release_lockowner(struct nfs4_lockowner *lo)
nfs4_put_stateowner(&lo->lo_owner);
}
-static void release_lockowner_if_empty(struct nfs4_lockowner *lo)
-{
- if (list_empty(&lo->lo_owner.so_stateids))
- release_lockowner(lo);
-}
-
-static void release_lock_stateid(struct nfs4_ol_stateid *stp)
-{
- struct nfs4_lockowner *lo;
-
- lo = lockowner(stp->st_stateowner);
- __release_lock_stateid(stp);
- release_lockowner_if_empty(lo);
-}
-
static void release_open_stateid_locks(struct nfs4_ol_stateid *open_stp)
__releases(&open_stp->st_stateowner->so_client->cl_lock)
__acquires(&open_stp->st_stateowner->so_client->cl_lock)
@@ -4323,7 +4308,7 @@ nfsd4_free_lock_stateid(struct nfs4_ol_stateid *stp)
if (check_for_locks(stp->st_stid.sc_file, lo))
return nfserr_locks_held;
- release_lockowner_if_empty(lo);
+ release_lock_stateid(stp);
return nfs_ok;
}
@@ -4938,8 +4923,6 @@ lookup_or_create_lock_state(struct nfsd4_compound_state *cstate,
lo = alloc_init_lock_stateowner(strhashval, cl, ost, lock);
if (lo == NULL)
return nfserr_jukebox;
- /* FIXME: extra reference for new lockowners for the client */
- atomic_inc(&lo->lo_owner.so_count);
} else {
/* with an existing lockowner, seqids must be the same */
status = nfserr_bad_seqid;
@@ -4950,7 +4933,6 @@ lookup_or_create_lock_state(struct nfsd4_compound_state *cstate,
*lst = find_or_create_lock_stateid(lo, fi, inode, ost, new);
if (*lst == NULL) {
- release_lockowner_if_empty(lo);
status = nfserr_jukebox;
goto out;
}
@@ -5379,6 +5361,7 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp,
continue;
if (same_owner_str(tmp, owner, clid)) {
sop = tmp;
+ atomic_inc(&sop->so_count);
break;
}
}
@@ -5392,8 +5375,10 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp,
lo = lockowner(sop);
/* see if there are still any locks associated with it */
list_for_each_entry(stp, &sop->so_stateids, st_perstateowner) {
- if (check_for_locks(stp->st_stid.sc_file, lo))
+ if (check_for_locks(stp->st_stid.sc_file, lo)) {
+ nfs4_put_stateowner(sop);
goto out;
+ }
}
status = nfs_ok;