mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-19 10:44:14 +08:00
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>
This commit is contained in:
parent
e4f1dd7fc2
commit
5adfd8850b
@ -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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
|
|
||||||
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,
|
|||||||
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,
|
|||||||
|
|
||||||
*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,
|
|||||||
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,
|
|||||||
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;
|
||||||
|
Loading…
Reference in New Issue
Block a user