Skip to content

Commit 1c13bf9

Browse files
neilbrownchucklever
authored andcommitted
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>
1 parent d688d85 commit 1c13bf9

1 file changed

Lines changed: 39 additions & 1 deletion

File tree

fs/nfsd/nfs4state.c

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1717,7 +1717,7 @@ void nfsd4_revoke_states(struct net *net, struct super_block *sb)
17171717
unsigned int idhashval;
17181718
unsigned int sc_types;
17191719

1720-
sc_types = 0;
1720+
sc_types = SC_TYPE_LOCK;
17211721

17221722
spin_lock(&nn->client_lock);
17231723
for (idhashval = 0; idhashval < CLIENT_HASH_MASK; idhashval++) {
@@ -1728,8 +1728,36 @@ void nfsd4_revoke_states(struct net *net, struct super_block *sb)
17281728
struct nfs4_stid *stid = find_one_sb_stid(clp, sb,
17291729
sc_types);
17301730
if (stid) {
1731+
struct nfs4_ol_stateid *stp;
1732+
17311733
spin_unlock(&nn->client_lock);
17321734
switch (stid->sc_type) {
1735+
case SC_TYPE_LOCK:
1736+
stp = openlockstateid(stid);
1737+
mutex_lock_nested(&stp->st_mutex,
1738+
LOCK_STATEID_MUTEX);
1739+
spin_lock(&clp->cl_lock);
1740+
if (stid->sc_status == 0) {
1741+
struct nfs4_lockowner *lo =
1742+
lockowner(stp->st_stateowner);
1743+
struct nfsd_file *nf;
1744+
1745+
stid->sc_status |=
1746+
SC_STATUS_ADMIN_REVOKED;
1747+
atomic_inc(&clp->cl_admin_revoked);
1748+
spin_unlock(&clp->cl_lock);
1749+
nf = find_any_file(stp->st_stid.sc_file);
1750+
if (nf) {
1751+
get_file(nf->nf_file);
1752+
filp_close(nf->nf_file,
1753+
(fl_owner_t)lo);
1754+
nfsd_file_put(nf);
1755+
}
1756+
release_all_access(stp);
1757+
} else
1758+
spin_unlock(&clp->cl_lock);
1759+
mutex_unlock(&stp->st_mutex);
1760+
break;
17331761
}
17341762
nfs4_put_stid(stid);
17351763
spin_lock(&nn->client_lock);
@@ -4630,8 +4658,18 @@ static void nfsd4_drop_revoked_stid(struct nfs4_stid *s)
46304658
__releases(&s->sc_client->cl_lock)
46314659
{
46324660
struct nfs4_client *cl = s->sc_client;
4661+
LIST_HEAD(reaplist);
4662+
struct nfs4_ol_stateid *stp;
4663+
bool unhashed;
46334664

46344665
switch (s->sc_type) {
4666+
case SC_TYPE_LOCK:
4667+
stp = openlockstateid(s);
4668+
unhashed = unhash_lock_stateid(stp);
4669+
spin_unlock(&cl->cl_lock);
4670+
if (unhashed)
4671+
nfs4_put_stid(s);
4672+
break;
46354673
default:
46364674
spin_unlock(&cl->cl_lock);
46374675
}

0 commit comments

Comments
 (0)