Commit 39657c74 authored by NeilBrown's avatar NeilBrown Committed by Chuck Lever

nfsd: allow open state ids to be revoked and then freed

Revoking state through 'unlock_filesystem' now revokes any open states
found.  When the stateids are then freed by the client, the revoked
stateids will be cleaned up correctly.

Possibly the related lock states should be revoked too, but a
subsequent patch will do that for all lock state on the superblock.
Reviewed-by: default avatarJeff Layton <jlayton@kernel.org>
Signed-off-by: default avatarNeilBrown <neilb@suse.de>
Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
parent 1c13bf9f
...@@ -1717,7 +1717,7 @@ void nfsd4_revoke_states(struct net *net, struct super_block *sb) ...@@ -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 = SC_TYPE_LOCK; sc_types = SC_TYPE_OPEN | 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++) {
...@@ -1732,6 +1732,22 @@ void nfsd4_revoke_states(struct net *net, struct super_block *sb) ...@@ -1732,6 +1732,22 @@ void nfsd4_revoke_states(struct net *net, struct super_block *sb)
spin_unlock(&nn->client_lock); spin_unlock(&nn->client_lock);
switch (stid->sc_type) { switch (stid->sc_type) {
case SC_TYPE_OPEN:
stp = openlockstateid(stid);
mutex_lock_nested(&stp->st_mutex,
OPEN_STATEID_MUTEX);
spin_lock(&clp->cl_lock);
if (stid->sc_status == 0) {
stid->sc_status |=
SC_STATUS_ADMIN_REVOKED;
atomic_inc(&clp->cl_admin_revoked);
spin_unlock(&clp->cl_lock);
release_all_access(stp);
} else
spin_unlock(&clp->cl_lock);
mutex_unlock(&stp->st_mutex);
break;
case SC_TYPE_LOCK: case SC_TYPE_LOCK:
stp = openlockstateid(stid); stp = openlockstateid(stid);
mutex_lock_nested(&stp->st_mutex, mutex_lock_nested(&stp->st_mutex,
...@@ -4663,6 +4679,13 @@ static void nfsd4_drop_revoked_stid(struct nfs4_stid *s) ...@@ -4663,6 +4679,13 @@ static void nfsd4_drop_revoked_stid(struct nfs4_stid *s)
bool unhashed; bool unhashed;
switch (s->sc_type) { switch (s->sc_type) {
case SC_TYPE_OPEN:
stp = openlockstateid(s);
if (unhash_open_stateid(stp, &reaplist))
put_ol_stateid_locked(stp, &reaplist);
spin_unlock(&cl->cl_lock);
free_ol_stateid_reaplist(&reaplist);
break;
case SC_TYPE_LOCK: case SC_TYPE_LOCK:
stp = openlockstateid(s); stp = openlockstateid(s);
unhashed = unhash_lock_stateid(stp); unhashed = unhash_lock_stateid(stp);
......
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