Commit 5adfd885 authored by Jeff Layton's avatar Jeff Layton Committed by J. Bruce Fields

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: default avatarJeff Layton <jlayton@primarydata.com>
Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
parent e4f1dd7f
...@@ -933,7 +933,7 @@ static void nfs4_free_lock_stateid(struct nfs4_stid *stid) ...@@ -933,7 +933,7 @@ static void nfs4_free_lock_stateid(struct nfs4_stid *stid)
nfs4_free_ol_stateid(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); struct nfs4_openowner *oo = openowner(stp->st_openstp->st_stateowner);
...@@ -957,7 +957,7 @@ static void release_lockowner_stateids(struct nfs4_lockowner *lo) ...@@ -957,7 +957,7 @@ static void release_lockowner_stateids(struct nfs4_lockowner *lo)
while (!list_empty(&lo->lo_owner.so_stateids)) { while (!list_empty(&lo->lo_owner.so_stateids)) {
stp = list_first_entry(&lo->lo_owner.so_stateids, stp = list_first_entry(&lo->lo_owner.so_stateids,
struct nfs4_ol_stateid, st_perstateowner); 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) ...@@ -968,21 +968,6 @@ static void release_lockowner(struct nfs4_lockowner *lo)
nfs4_put_stateowner(&lo->lo_owner); 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) static void release_open_stateid_locks(struct nfs4_ol_stateid *open_stp)
__releases(&open_stp->st_stateowner->so_client->cl_lock) __releases(&open_stp->st_stateowner->so_client->cl_lock)
__acquires(&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) ...@@ -4323,7 +4308,7 @@ nfsd4_free_lock_stateid(struct nfs4_ol_stateid *stp)
if (check_for_locks(stp->st_stid.sc_file, lo)) if (check_for_locks(stp->st_stid.sc_file, lo))
return nfserr_locks_held; return nfserr_locks_held;
release_lockowner_if_empty(lo); release_lock_stateid(stp);
return nfs_ok; return nfs_ok;
} }
...@@ -4938,8 +4923,6 @@ lookup_or_create_lock_state(struct nfsd4_compound_state *cstate, ...@@ -4938,8 +4923,6 @@ lookup_or_create_lock_state(struct nfsd4_compound_state *cstate,
lo = alloc_init_lock_stateowner(strhashval, cl, ost, lock); lo = alloc_init_lock_stateowner(strhashval, cl, ost, lock);
if (lo == NULL) if (lo == NULL)
return nfserr_jukebox; return nfserr_jukebox;
/* FIXME: extra reference for new lockowners for the client */
atomic_inc(&lo->lo_owner.so_count);
} else { } else {
/* with an existing lockowner, seqids must be the same */ /* with an existing lockowner, seqids must be the same */
status = nfserr_bad_seqid; status = nfserr_bad_seqid;
...@@ -4950,7 +4933,6 @@ lookup_or_create_lock_state(struct nfsd4_compound_state *cstate, ...@@ -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); *lst = find_or_create_lock_stateid(lo, fi, inode, ost, new);
if (*lst == NULL) { if (*lst == NULL) {
release_lockowner_if_empty(lo);
status = nfserr_jukebox; status = nfserr_jukebox;
goto out; goto out;
} }
...@@ -5379,6 +5361,7 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp, ...@@ -5379,6 +5361,7 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp,
continue; continue;
if (same_owner_str(tmp, owner, clid)) { if (same_owner_str(tmp, owner, clid)) {
sop = tmp; sop = tmp;
atomic_inc(&sop->so_count);
break; break;
} }
} }
...@@ -5392,8 +5375,10 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp, ...@@ -5392,8 +5375,10 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp,
lo = lockowner(sop); lo = lockowner(sop);
/* see if there are still any locks associated with it */ /* see if there are still any locks associated with it */
list_for_each_entry(stp, &sop->so_stateids, st_perstateowner) { 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; goto out;
}
} }
status = nfs_ok; status = nfs_ok;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment