diff options
author | Jeff Layton | 2014-07-30 08:27:14 -0400 |
---|---|---|
committer | J. Bruce Fields | 2014-08-05 10:55:01 -0400 |
commit | fd699b8a48c0ca36e782cf705794358b3e4b8c25 (patch) | |
tree | 4e38b16b1b979e75f157b3dbe0f03d5beccfe8ca /fs/nfsd | |
parent | fb94d766af0571ab82d5f63e871a73d985d6d6b0 (diff) |
nfsd: don't destroy clients that are busy
It's possible that we'll have an in-progress call on some of the clients
while a rogue EXCHANGE_ID or DESTROY_CLIENTID call comes in. Be sure to
try and mark the client expired first, so that the refcount is
respected.
This will only be a problem once the client_mutex is removed.
Signed-off-by: Jeff Layton <jlayton@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd')
-rw-r--r-- | fs/nfsd/nfs4state.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 028ae55e5f7a..037bb924ce63 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -2267,8 +2267,11 @@ nfsd4_exchange_id(struct svc_rqst *rqstp, /* case 1 (normal case) */ out_new: - if (conf) - unhash_client_locked(conf); + if (conf) { + status = mark_client_expired_locked(conf); + if (status) + goto out; + } new->cl_minorversion = cstate->minorversion; new->cl_mach_cred = (exid->spa_how == SP4_MACH_CRED); @@ -2881,6 +2884,9 @@ nfsd4_destroy_clientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *csta status = nfserr_clientid_busy; goto out; } + status = mark_client_expired_locked(conf); + if (status) + goto out; clp = conf; } else if (unconf) clp = unconf; |