nfsd4: fix buflen calculation after read encoding
authorJ. Bruce Fields <bfields@redhat.com>
Mon, 19 May 2014 20:18:23 +0000 (16:18 -0400)
committerJ. Bruce Fields <bfields@redhat.com>
Fri, 30 May 2014 21:32:00 +0000 (17:32 -0400)
We don't necessarily want to assume that the buflen is the same
as the number of bytes available in the pages.  We may have some reason
to set it to something less (for example, later patches will use a
smaller buflen to enforce session limits).

So, calculate the buflen relative to the previous buflen instead of
recalculating it from scratch.

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

index 0eeba2199c8c34aed4b18fc437e6fe92657d8bd7..1278d98a923c9cbe0534dfe735c888705be0a319 100644 (file)
@@ -3053,6 +3053,7 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
        unsigned long maxcount; 
        struct xdr_stream *xdr = &resp->xdr;
        int starting_len = xdr->buf->len;
+       int space_left;
        long len;
        __be32 *p;
 
@@ -3117,7 +3118,6 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
        resp->xdr.buf->page_len = maxcount;
        xdr->buf->len += maxcount;
        xdr->page_ptr += v;
-       xdr->buf->buflen = maxcount + PAGE_SIZE - 2 * RPC_MAX_AUTH_SIZE;
        xdr->iov = xdr->buf->tail;
 
        /* Use rest of head for padding and remaining ops: */
@@ -3130,6 +3130,12 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
                resp->xdr.buf->tail[0].iov_len = 4 - (maxcount&3);
                xdr->buf->len -= (maxcount&3);
        }
+
+       space_left = min_t(int, (void *)xdr->end - (void *)xdr->p,
+                               xdr->buf->buflen - xdr->buf->len);
+       xdr->buf->buflen = xdr->buf->len + space_left;
+       xdr->end = (__be32 *)((void *)xdr->end + space_left);
+
        return 0;
 }