nfsd41: error out on repeated RECLAIM_COMPLETE
authorMi Jinlong <mijinlong@cn.fujitsu.com>
Wed, 27 Apr 2011 01:14:30 +0000 (09:14 +0800)
committerJ. Bruce Fields <bfields@redhat.com>
Sat, 30 Apr 2011 00:47:56 +0000 (20:47 -0400)
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>
fs/nfsd/nfs4state.c

index 3196dc38857846c719c44b9c1fe2b4b955a9ae4a..2bb03f86a037c223e8346a8c004362de34ff86f1 100644 (file)
@@ -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