summaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfs4xdr.c
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@redhat.com>2013-04-01 22:23:49 -0400
committerJ. Bruce Fields <bfields@redhat.com>2013-04-03 11:48:39 -0400
commit221a68766973d7a3afe40a05abd8258b5de016a0 (patch)
treece1770ad1f1cc7227d8b8819101875b8f36a449b /fs/nfsd/nfs4xdr.c
parent4f6e6c17733ecf01c05a693ced8349ccf8101fd8 (diff)
downloadlinux-stable-221a68766973d7a3afe40a05abd8258b5de016a0.tar.gz
linux-stable-221a68766973d7a3afe40a05abd8258b5de016a0.tar.bz2
linux-stable-221a68766973d7a3afe40a05abd8258b5de016a0.zip
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/nfs4xdr.c')
-rw-r--r--fs/nfsd/nfs4xdr.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 9b02b6652f2b..700de0192834 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -3684,7 +3684,8 @@ nfs4svc_encode_compoundres(struct svc_rqst *rqstp, __be32 *p, struct nfsd4_compo
cs->slot->sl_flags &= ~NFSD4_SLOT_INUSE;
}
/* Renew the clientid on success and on replay */
- release_session_client(cs->session);
+ put_client_renew(cs->session->se_client);
+ nfsd4_put_session(cs->session);
}
return 1;
}