Skip to content

Commit

Permalink
nfsd: allow open state ids to be revoked and then freed
Browse files Browse the repository at this point in the history
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: Jeff Layton <[email protected]>
Signed-off-by: NeilBrown <[email protected]>
Signed-off-by: Chuck Lever <[email protected]>
  • Loading branch information
neilbrown authored and chucklever committed Mar 1, 2024
1 parent 1c13bf9 commit 39657c7
Showing 1 changed file with 24 additions and 1 deletion.
25 changes: 24 additions & 1 deletion fs/nfsd/nfs4state.c
Original file line number Diff line number Diff line change
Expand Up @@ -1717,7 +1717,7 @@ void nfsd4_revoke_states(struct net *net, struct super_block *sb)
unsigned int idhashval;
unsigned int sc_types;

sc_types = SC_TYPE_LOCK;
sc_types = SC_TYPE_OPEN | SC_TYPE_LOCK;

spin_lock(&nn->client_lock);
for (idhashval = 0; idhashval < CLIENT_HASH_MASK; idhashval++) {
Expand All @@ -1732,6 +1732,22 @@ void nfsd4_revoke_states(struct net *net, struct super_block *sb)

spin_unlock(&nn->client_lock);
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:
stp = openlockstateid(stid);
mutex_lock_nested(&stp->st_mutex,
Expand Down Expand Up @@ -4663,6 +4679,13 @@ static void nfsd4_drop_revoked_stid(struct nfs4_stid *s)
bool unhashed;

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:
stp = openlockstateid(s);
unhashed = unhash_lock_stateid(stp);
Expand Down

0 comments on commit 39657c7

Please sign in to comment.