summaryrefslogtreecommitdiffstats
path: root/fs/nfsd
diff options
context:
space:
mode:
authorMi Jinlong <mijinlong@cn.fujitsu.com>2011-04-27 03:14:30 +0200
committerJ. Bruce Fields <bfields@redhat.com>2011-04-30 02:47:56 +0200
commitbcecf1ccc336200ee488e8eb68acdafc4b0dbd1a (patch)
treeb3376aa05de0925490c04a19edfdabf87c4507d6 /fs/nfsd
parentnfsd41: compare request's opcnt with session's maxops at nfsd4_sequence (diff)
downloadlinux-bcecf1ccc336200ee488e8eb68acdafc4b0dbd1a.tar.xz
linux-bcecf1ccc336200ee488e8eb68acdafc4b0dbd1a.zip
nfsd41: error out on repeated RECLAIM_COMPLETE
Servers are supposed to return nfserr_complete_already to clients that attempt to send multiple RECLAIM_COMPLETEs. Signed-off-by: Mi Jinlong <mijinlong@cn.fujitsu.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd')
-rw-r--r--fs/nfsd/nfs4state.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 3196dc388578..2bb03f86a037 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -1818,6 +1818,8 @@ out:
__be32
nfsd4_reclaim_complete(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_reclaim_complete *rc)
{
+ int status = 0;
+
if (rc->rca_one_fs) {
if (!cstate->current_fh.fh_dentry)
return nfserr_nofilehandle;
@@ -1827,9 +1829,14 @@ nfsd4_reclaim_complete(struct svc_rqst *rqstp, struct nfsd4_compound_state *csta
*/
return nfs_ok;
}
+
nfs4_lock_state();
- if (is_client_expired(cstate->session->se_client)) {
- nfs4_unlock_state();
+ status = nfserr_complete_already;
+ if (cstate->session->se_client->cl_firststate)
+ goto out;
+
+ status = nfserr_stale_clientid;
+ if (is_client_expired(cstate->session->se_client))
/*
* The following error isn't really legal.
* But we only get here if the client just explicitly
@@ -1837,11 +1844,13 @@ nfsd4_reclaim_complete(struct svc_rqst *rqstp, struct nfsd4_compound_state *csta
* error it gets back on an operation for the dead
* client.
*/
- return nfserr_stale_clientid;
- }
+ goto out;
+
+ status = nfs_ok;
nfsd4_create_clid_dir(cstate->session->se_client);
+out:
nfs4_unlock_state();
- return nfs_ok;
+ return status;
}
__be32