nfsd4: remove redundant encode buffer size checking
authorJ. Bruce Fields <bfields@redhat.com>
Sat, 8 Mar 2014 22:19:55 +0000 (17:19 -0500)
committerJ. Bruce Fields <bfields@redhat.com>
Fri, 30 May 2014 21:31:52 +0000 (17:31 -0400)
Now that all op encoders can handle running out of space, we no longer
need to check the remaining size for every operation; only nonidempotent
operations need that check, and that can be done by
nfsd4_check_resp_size.

Signed-off-by: J. Bruce Fields <bfields@redhat.com>
fs/nfsd/nfs4proc.c
fs/nfsd/nfs4xdr.c

index 6a5b701..a5b666c 100644 (file)
@@ -1279,7 +1279,6 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
        struct nfsd4_compound_state *cstate = &resp->cstate;
        struct svc_fh *current_fh = &cstate->current_fh;
        struct svc_fh *save_fh = &cstate->save_fh;
-       int             slack_bytes;
        u32             plen = 0;
        __be32          status;
 
@@ -1333,19 +1332,6 @@ nfsd4_proc_compound(struct svc_rqst *rqstp,
                        goto encode_op;
                }
 
-               /* We must be able to encode a successful response to
-                * this operation, with enough room left over to encode a
-                * failed response to the next operation.  If we don't
-                * have enough room, fail with ERR_RESOURCE.
-                */
-               slack_bytes = (char *)resp->xdr.end - (char *)resp->xdr.p;
-               if (slack_bytes < COMPOUND_SLACK_SPACE
-                               + COMPOUND_ERR_SLACK_SPACE) {
-                       BUG_ON(slack_bytes < COMPOUND_ERR_SLACK_SPACE);
-                       op->status = nfserr_resource;
-                       goto encode_op;
-               }
-
                opdesc = OPDESC(op);
 
                if (!current_fh->fh_dentry) {
index 89c65a3..df643e0 100644 (file)
@@ -3753,20 +3753,24 @@ static nfsd4_enc nfsd4_enc_ops[] = {
 __be32 nfsd4_check_resp_size(struct nfsd4_compoundres *resp, u32 pad)
 {
        struct xdr_buf *buf = &resp->rqstp->rq_res;
-       struct nfsd4_session *session = NULL;
+       struct nfsd4_session *session = resp->cstate.session;
        struct nfsd4_slot *slot = resp->cstate.slot;
+       int slack_bytes = (char *)resp->xdr.end - (char *)resp->xdr.p;
 
-       if (!nfsd4_has_session(&resp->cstate))
-               return 0;
+       if (nfsd4_has_session(&resp->cstate)) {
 
-       session = resp->cstate.session;
+               if (buf->len + pad > session->se_fchannel.maxresp_sz)
+                       return nfserr_rep_too_big;
 
-       if (buf->len + pad > session->se_fchannel.maxresp_sz)
-               return nfserr_rep_too_big;
+               if ((slot->sl_flags & NFSD4_SLOT_CACHETHIS) &&
+                   buf->len + pad > session->se_fchannel.maxresp_cached)
+                       return nfserr_rep_too_big_to_cache;
+       }
 
-       if ((slot->sl_flags & NFSD4_SLOT_CACHETHIS) &&
-           buf->len + pad > session->se_fchannel.maxresp_cached)
-               return nfserr_rep_too_big_to_cache;
+       if (pad > slack_bytes) {
+               WARN_ON_ONCE(nfsd4_has_session(&resp->cstate));
+               return nfserr_resource;
+       }
 
        return 0;
 }