diff options
author | J. Bruce Fields <bfields@redhat.com> | 2013-04-01 22:23:49 -0400 |
---|---|---|
committer | J. Bruce Fields <bfields@redhat.com> | 2013-04-03 11:48:39 -0400 |
commit | 221a68766973d7a3afe40a05abd8258b5de016a0 (patch) | |
tree | ce1770ad1f1cc7227d8b8819101875b8f36a449b /fs/nfsd/state.h | |
parent | 4f6e6c17733ecf01c05a693ced8349ccf8101fd8 (diff) |
nfsd4: don't destroy in-use clients
When a setclientid_confirm or create_session confirms a client after a
client reboot, it also destroys any previous state held by that client.
The shutdown of that previous state must be careful not to free the
client out from under threads processing other requests that refer to
the client.
This is a particular problem in the NFSv4.1 case when we hold a
reference to a session (hence a client) throughout compound processing.
The server attempts to handle this by unhashing the client at the time
it's destroyed, then delaying the final free to the end. But this still
leaves some races in the current code.
I believe it's simpler just to fail the attempt to destroy the client by
returning NFS4ERR_DELAY. This is a case that should never happen
anyway.
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd/state.h')
-rw-r--r-- | fs/nfsd/state.h | 16 |
1 files changed, 3 insertions, 13 deletions
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index 327552bb6dba..07f8a822a6ce 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -209,6 +209,8 @@ struct nfsd4_session { struct nfsd4_slot *se_slots[]; /* forward channel slots */ }; +extern void nfsd4_put_session(struct nfsd4_session *ses); + /* formatted contents of nfs4_sessionid */ struct nfsd4_sessionid { clientid_t clientid; @@ -284,18 +286,6 @@ struct nfs4_client { struct net *net; }; -static inline void -mark_client_expired(struct nfs4_client *clp) -{ - clp->cl_time = 0; -} - -static inline bool -is_client_expired(struct nfs4_client *clp) -{ - return clp->cl_time == 0; -} - /* struct nfs4_client_reset * one per old client. Populates reset_str_hashtbl. Filled from conf_id_hashtbl * upon lease reset, or from upcall to state_daemon (to read in state @@ -484,7 +474,7 @@ extern void nfs4_put_delegation(struct nfs4_delegation *dp); extern struct nfs4_client_reclaim *nfs4_client_to_reclaim(const char *name, struct nfsd_net *nn); extern bool nfs4_has_reclaimed_state(const char *name, struct nfsd_net *nn); -extern void release_session_client(struct nfsd4_session *); +extern void put_client_renew(struct nfs4_client *clp); extern void nfsd4_purge_closed_stateid(struct nfs4_stateowner *); /* nfs4recover operations */ |