Commit 6ac90391 authored by J. Bruce Fields's avatar J. Bruce Fields

nfsd4: keep xdr buf length updated

Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
parent dd97fdde
...@@ -1262,6 +1262,8 @@ static void svcxdr_init_encode(struct svc_rqst *rqstp, ...@@ -1262,6 +1262,8 @@ static void svcxdr_init_encode(struct svc_rqst *rqstp,
xdr->iov = head; xdr->iov = head;
xdr->p = head->iov_base + head->iov_len; xdr->p = head->iov_base + head->iov_len;
xdr->end = head->iov_base + PAGE_SIZE - 2 * RPC_MAX_AUTH_SIZE; xdr->end = head->iov_base + PAGE_SIZE - 2 * RPC_MAX_AUTH_SIZE;
/* Tail and page_len should be zero at this point: */
buf->len = buf->head[0].iov_len;
} }
/* /*
......
...@@ -3046,6 +3046,7 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr, ...@@ -3046,6 +3046,7 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
if (nfserr) { if (nfserr) {
xdr->p -= 2; xdr->p -= 2;
xdr->iov->iov_len -= 8; xdr->iov->iov_len -= 8;
xdr->buf->len -= 8;
return nfserr; return nfserr;
} }
eof = (read->rd_offset + maxcount >= eof = (read->rd_offset + maxcount >=
...@@ -3053,9 +3054,10 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr, ...@@ -3053,9 +3054,10 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
WRITE32(eof); WRITE32(eof);
WRITE32(maxcount); WRITE32(maxcount);
resp->xdr.buf->head[0].iov_len = (char *)p WARN_ON_ONCE(resp->xdr.buf->head[0].iov_len != (char *)p
- (char *)resp->xdr.buf->head[0].iov_base; - (char *)resp->xdr.buf->head[0].iov_base);
resp->xdr.buf->page_len = maxcount; resp->xdr.buf->page_len = maxcount;
xdr->buf->len += maxcount;
xdr->iov = xdr->buf->tail; xdr->iov = xdr->buf->tail;
/* Use rest of head for padding and remaining ops: */ /* Use rest of head for padding and remaining ops: */
...@@ -3066,6 +3068,7 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr, ...@@ -3066,6 +3068,7 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
WRITE32(0); WRITE32(0);
resp->xdr.buf->tail[0].iov_base += maxcount&3; resp->xdr.buf->tail[0].iov_base += maxcount&3;
resp->xdr.buf->tail[0].iov_len = 4 - (maxcount&3); resp->xdr.buf->tail[0].iov_len = 4 - (maxcount&3);
xdr->buf->len -= (maxcount&3);
} }
return 0; return 0;
} }
...@@ -3102,6 +3105,7 @@ nfsd4_encode_readlink(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd ...@@ -3102,6 +3105,7 @@ nfsd4_encode_readlink(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd
if (nfserr) { if (nfserr) {
xdr->p--; xdr->p--;
xdr->iov->iov_len -= 4; xdr->iov->iov_len -= 4;
xdr->buf->len -= 4;
return nfserr; return nfserr;
} }
...@@ -3109,6 +3113,7 @@ nfsd4_encode_readlink(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd ...@@ -3109,6 +3113,7 @@ nfsd4_encode_readlink(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd
resp->xdr.buf->head[0].iov_len = (char *)p resp->xdr.buf->head[0].iov_len = (char *)p
- (char *)resp->xdr.buf->head[0].iov_base; - (char *)resp->xdr.buf->head[0].iov_base;
resp->xdr.buf->page_len = maxcount; resp->xdr.buf->page_len = maxcount;
xdr->buf->len += maxcount;
xdr->iov = xdr->buf->tail; xdr->iov = xdr->buf->tail;
/* Use rest of head for padding and remaining ops: */ /* Use rest of head for padding and remaining ops: */
...@@ -3189,6 +3194,7 @@ nfsd4_encode_readdir(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4 ...@@ -3189,6 +3194,7 @@ nfsd4_encode_readdir(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4
*p++ = htonl(readdir->common.err == nfserr_eof); *p++ = htonl(readdir->common.err == nfserr_eof);
resp->xdr.buf->page_len = ((char *)p) - resp->xdr.buf->page_len = ((char *)p) -
(char*)page_address(*(resp->rqstp->rq_next_page-1)); (char*)page_address(*(resp->rqstp->rq_next_page-1));
xdr->buf->len += xdr->buf->page_len;
xdr->iov = xdr->buf->tail; xdr->iov = xdr->buf->tail;
...@@ -3204,6 +3210,7 @@ nfsd4_encode_readdir(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4 ...@@ -3204,6 +3210,7 @@ nfsd4_encode_readdir(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4
xdr->p = savep; xdr->p = savep;
xdr->iov->iov_len = ((char *)resp->xdr.p) xdr->iov->iov_len = ((char *)resp->xdr.p)
- (char *)resp->xdr.buf->head[0].iov_base; - (char *)resp->xdr.buf->head[0].iov_base;
xdr->buf->len = xdr->iov->iov_len;
return nfserr; return nfserr;
} }
...@@ -3789,6 +3796,10 @@ nfs4svc_encode_compoundres(struct svc_rqst *rqstp, __be32 *p, struct nfsd4_compo ...@@ -3789,6 +3796,10 @@ nfs4svc_encode_compoundres(struct svc_rqst *rqstp, __be32 *p, struct nfsd4_compo
* All that remains is to write the tag and operation count... * All that remains is to write the tag and operation count...
*/ */
struct nfsd4_compound_state *cs = &resp->cstate; struct nfsd4_compound_state *cs = &resp->cstate;
struct xdr_buf *buf = resp->xdr.buf;
WARN_ON_ONCE(buf->len != buf->head[0].iov_len + buf->page_len +
buf->tail[0].iov_len);
p = resp->tagp; p = resp->tagp;
*p++ = htonl(resp->taglen); *p++ = htonl(resp->taglen);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment