mirror of
https://github.com/torvalds/linux.git
synced 2026-09-26 01:52:03 +02:00
nfsd: allow lock state ids to be revoked and then freed
Revoking state through 'unlock_filesystem' now revokes any lock states found. When the stateids are then freed by the client, the revoked stateids will be cleaned up correctly. Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: NeilBrown <neilb@suse.de> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
This commit is contained in:
parent
d688d8585e
commit
1c13bf9f2e
|
|
@ -1717,7 +1717,7 @@ void nfsd4_revoke_states(struct net *net, struct super_block *sb)
|
||||||
unsigned int idhashval;
|
unsigned int idhashval;
|
||||||
unsigned int sc_types;
|
unsigned int sc_types;
|
||||||
|
|
||||||
sc_types = 0;
|
sc_types = SC_TYPE_LOCK;
|
||||||
|
|
||||||
spin_lock(&nn->client_lock);
|
spin_lock(&nn->client_lock);
|
||||||
for (idhashval = 0; idhashval < CLIENT_HASH_MASK; idhashval++) {
|
for (idhashval = 0; idhashval < CLIENT_HASH_MASK; idhashval++) {
|
||||||
|
|
@ -1728,8 +1728,36 @@ void nfsd4_revoke_states(struct net *net, struct super_block *sb)
|
||||||
struct nfs4_stid *stid = find_one_sb_stid(clp, sb,
|
struct nfs4_stid *stid = find_one_sb_stid(clp, sb,
|
||||||
sc_types);
|
sc_types);
|
||||||
if (stid) {
|
if (stid) {
|
||||||
|
struct nfs4_ol_stateid *stp;
|
||||||
|
|
||||||
spin_unlock(&nn->client_lock);
|
spin_unlock(&nn->client_lock);
|
||||||
switch (stid->sc_type) {
|
switch (stid->sc_type) {
|
||||||
|
case SC_TYPE_LOCK:
|
||||||
|
stp = openlockstateid(stid);
|
||||||
|
mutex_lock_nested(&stp->st_mutex,
|
||||||
|
LOCK_STATEID_MUTEX);
|
||||||
|
spin_lock(&clp->cl_lock);
|
||||||
|
if (stid->sc_status == 0) {
|
||||||
|
struct nfs4_lockowner *lo =
|
||||||
|
lockowner(stp->st_stateowner);
|
||||||
|
struct nfsd_file *nf;
|
||||||
|
|
||||||
|
stid->sc_status |=
|
||||||
|
SC_STATUS_ADMIN_REVOKED;
|
||||||
|
atomic_inc(&clp->cl_admin_revoked);
|
||||||
|
spin_unlock(&clp->cl_lock);
|
||||||
|
nf = find_any_file(stp->st_stid.sc_file);
|
||||||
|
if (nf) {
|
||||||
|
get_file(nf->nf_file);
|
||||||
|
filp_close(nf->nf_file,
|
||||||
|
(fl_owner_t)lo);
|
||||||
|
nfsd_file_put(nf);
|
||||||
|
}
|
||||||
|
release_all_access(stp);
|
||||||
|
} else
|
||||||
|
spin_unlock(&clp->cl_lock);
|
||||||
|
mutex_unlock(&stp->st_mutex);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
nfs4_put_stid(stid);
|
nfs4_put_stid(stid);
|
||||||
spin_lock(&nn->client_lock);
|
spin_lock(&nn->client_lock);
|
||||||
|
|
@ -4630,8 +4658,18 @@ static void nfsd4_drop_revoked_stid(struct nfs4_stid *s)
|
||||||
__releases(&s->sc_client->cl_lock)
|
__releases(&s->sc_client->cl_lock)
|
||||||
{
|
{
|
||||||
struct nfs4_client *cl = s->sc_client;
|
struct nfs4_client *cl = s->sc_client;
|
||||||
|
LIST_HEAD(reaplist);
|
||||||
|
struct nfs4_ol_stateid *stp;
|
||||||
|
bool unhashed;
|
||||||
|
|
||||||
switch (s->sc_type) {
|
switch (s->sc_type) {
|
||||||
|
case SC_TYPE_LOCK:
|
||||||
|
stp = openlockstateid(s);
|
||||||
|
unhashed = unhash_lock_stateid(stp);
|
||||||
|
spin_unlock(&cl->cl_lock);
|
||||||
|
if (unhashed)
|
||||||
|
nfs4_put_stid(s);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
spin_unlock(&cl->cl_lock);
|
spin_unlock(&cl->cl_lock);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user