diff options
author | Jeff Layton <jlayton@primarydata.com> | 2014-07-30 03:34:26 +0200 |
---|---|---|
committer | J. Bruce Fields <bfields@redhat.com> | 2014-07-31 20:20:18 +0200 |
commit | 6b180f0b57af0295e8dc2602a7a4781241766340 (patch) | |
tree | cd27ba1d399d67714df6b3798f1512f2a3ef2504 /fs/nfsd/state.h | |
parent | nfsd: Migrate the stateid reference into nfs4_find_stateid_by_type() (diff) | |
download | linux-6b180f0b57af0295e8dc2602a7a4781241766340.tar.xz linux-6b180f0b57af0295e8dc2602a7a4781241766340.zip |
nfsd: Add reference counting to state owners
The way stateowners are managed today is somewhat awkward. They need to
be explicitly destroyed, even though the stateids reference them. This
will be particularly problematic when we remove the client_mutex.
We may create a new stateowner and attempt to open a file or set a lock,
and have that fail. In the meantime, another RPC may come in that uses
that same stateowner and succeed. We can't have the first task tearing
down the stateowner in that situation.
To fix this, we need to change how stateowners are tracked altogether.
Refcount them and only destroy them once all stateids that reference
them have been destroyed. This patch starts by adding the refcounting
necessary to do that.
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd/state.h')
-rw-r--r-- | fs/nfsd/state.h | 22 |
1 files changed, 15 insertions, 7 deletions
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index af1d9c42e939..dc725deb4aa8 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -331,16 +331,24 @@ struct nfs4_replay { char rp_ibuf[NFSD4_REPLAY_ISIZE]; }; +struct nfs4_stateowner; + +struct nfs4_stateowner_operations { + void (*so_free)(struct nfs4_stateowner *); +}; + struct nfs4_stateowner { - struct list_head so_strhash; /* hash by op_name */ - struct list_head so_stateids; - struct nfs4_client * so_client; + struct list_head so_strhash; + struct list_head so_stateids; + struct nfs4_client *so_client; + const struct nfs4_stateowner_operations *so_ops; /* after increment in ENCODE_SEQID_OP_TAIL, represents the next * sequence id expected from the client: */ - u32 so_seqid; - struct xdr_netobj so_owner; /* open owner name */ - struct nfs4_replay so_replay; - bool so_is_open_owner; + atomic_t so_count; + u32 so_seqid; + struct xdr_netobj so_owner; /* open owner name */ + struct nfs4_replay so_replay; + bool so_is_open_owner; }; struct nfs4_openowner { |