@@ -596,6 +596,7 @@ static void remove_stid(struct nfs4_stid *s)
static void nfs4_free_stid(struct kmem_cache *slab, struct nfs4_stid *s)
{
+ remove_stid(s);
if (s->sc_file)
put_nfs4_file(s->sc_file);
kmem_cache_free(slab, s);
@@ -666,7 +667,7 @@ unhash_delegation(struct nfs4_delegation *dp)
static void destroy_delegation(struct nfs4_delegation *dp)
{
- remove_stid(&dp->dl_stid);
+ dp->dl_stid.sc_type = NFS4_CLOSED_DELEG_STID;
nfs4_put_delegation(dp);
}
@@ -679,7 +680,7 @@ static void unhash_and_destroy_delegation(struct nfs4_delegation *dp)
static void destroy_revoked_delegation(struct nfs4_delegation *dp)
{
list_del_init(&dp->dl_recall_lru);
- destroy_delegation(dp);
+ nfs4_put_delegation(dp);
}
static void revoke_delegation(struct nfs4_delegation *dp)
@@ -854,7 +855,6 @@ static void put_generic_stateid(struct nfs4_ol_stateid *stp)
{
if (!atomic_dec_and_test(&stp->st_stid.sc_count))
return;
- remove_stid(&stp->st_stid);
nfs4_free_stid(stateid_slab, &stp->st_stid);
}
@@ -4029,7 +4029,9 @@ static __be32 nfsd4_validate_stateid(struct nfs4_client *cl, stateid_t *stateid)
return nfs_ok;
default:
printk("unknown stateid type %x\n", s->sc_type);
+ /* Fallthrough */
case NFS4_CLOSED_STID:
+ case NFS4_CLOSED_DELEG_STID:
return nfserr_bad_stateid;
}
}
@@ -81,6 +81,7 @@ struct nfs4_stid {
#define NFS4_CLOSED_STID 8
/* For a deleg stateid kept around only to process free_stateid's: */
#define NFS4_REVOKED_DELEG_STID 16
+#define NFS4_CLOSED_DELEG_STID 32
unsigned char sc_type;
stateid_t sc_stateid;
struct nfs4_client *sc_client;