Skip to content

Commit

Permalink
nfsd: Ensure stateids remain unique until they are freed
Browse files Browse the repository at this point in the history
Add an extra delegation state to allow the stateid to remain in the idr
tree until the last reference has been released. This will be necessary
to ensure uniqueness once the client_mutex is removed.

[jlayton: reset the sc_type under the state_lock in unhash_delegation]

Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
  • Loading branch information
Trond Myklebust authored and J. Bruce Fields committed Jul 17, 2014
1 parent d564fbe commit b0fc29d
Show file tree
Hide file tree
Showing 2 changed files with 5 additions and 4 deletions.
8 changes: 4 additions & 4 deletions fs/nfsd/nfs4state.c
Original file line number Diff line number Diff line change
Expand Up @@ -616,6 +616,7 @@ void
nfs4_put_delegation(struct nfs4_delegation *dp)
{
if (atomic_dec_and_test(&dp->dl_count)) {
remove_stid(&dp->dl_stid);
nfs4_free_stid(deleg_slab, &dp->dl_stid);
num_delegations--;
}
Expand Down Expand Up @@ -657,6 +658,7 @@ unhash_delegation(struct nfs4_delegation *dp)
struct nfs4_file *fp = dp->dl_file;

spin_lock(&state_lock);
dp->dl_stid.sc_type = NFS4_CLOSED_DELEG_STID;
list_del_init(&dp->dl_perclnt);
list_del_init(&dp->dl_recall_lru);
spin_lock(&fp->fi_lock);
Expand All @@ -670,19 +672,15 @@ unhash_delegation(struct nfs4_delegation *dp)
}
}



static void destroy_revoked_delegation(struct nfs4_delegation *dp)
{
list_del_init(&dp->dl_recall_lru);
remove_stid(&dp->dl_stid);
nfs4_put_delegation(dp);
}

static void destroy_delegation(struct nfs4_delegation *dp)
{
unhash_delegation(dp);
remove_stid(&dp->dl_stid);
nfs4_put_delegation(dp);
}

Expand Down Expand Up @@ -4036,7 +4034,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;
}
}
Expand Down
1 change: 1 addition & 0 deletions fs/nfsd/state.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,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;
Expand Down

0 comments on commit b0fc29d

Please sign in to comment.