On Mon, 2024-01-29 at 14:29 +1100, NeilBrown wrote: > 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. > > Signed-off-by: NeilBrown <neilb@xxxxxxx> > --- > fs/nfsd/nfs4state.c | 40 +++++++++++++++++++++++++++++++++++++++- > 1 file changed, 39 insertions(+), 1 deletion(-) > > diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c > index 900d295bd570..a5c17dab8bdb 100644 > --- a/fs/nfsd/nfs4state.c > +++ b/fs/nfsd/nfs4state.c > @@ -1717,7 +1717,7 @@ void nfsd4_revoke_states(struct net *net, struct super_block *sb) > unsigned int idhashval; > unsigned int sc_types; > > - sc_types = 0; > + sc_types = SC_TYPE_LOCK; > > spin_lock(&nn->client_lock); > 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, > sc_types); > if (stid) { > + struct nfs4_ol_stateid *stp; > + > spin_unlock(&nn->client_lock); > 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); > spin_lock(&nn->client_lock); > @@ -4629,8 +4657,18 @@ static void nfsd4_drop_revoked_stid(struct nfs4_stid *s) > __releases(&s->sc_client->cl_lock) > { > struct nfs4_client *cl = s->sc_client; > + LIST_HEAD(reaplist); > + struct nfs4_ol_stateid *stp; > + bool unhashed; > > 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: > spin_unlock(&cl->cl_lock); > } Reviewed-by: Jeff Layton <jlayton@xxxxxxxxxx>