Commit 467cb27b authored by Neil Brown's avatar Neil Brown Committed by James Bottomley

[PATCH] Keep track of which page is the 'tail' of an NFSd reply

NFS replies can have a 'tail' after a 'data' component
(for read, readlink, readdir).

For nfsv2 and v3 this tail is in the same page as the head.
For nfsv4, this tail is in a separate page.

We need to keep track of which page so that it right one
gets sent.  This patch does that.
parent 2aeb0311
......@@ -667,6 +667,7 @@ nfs3svc_encode_readlinkres(struct svc_rqst *rqstp, u32 *p,
rqstp->rq_res.page_len = resp->len;
if (resp->len & 3) {
/* need to pad the tail */
rqstp->rq_restailpage = 0;
rqstp->rq_res.tail[0].iov_base = p;
*p = 0;
rqstp->rq_res.tail[0].iov_len = 4 - (resp->len&3);
......@@ -691,6 +692,7 @@ nfs3svc_encode_readres(struct svc_rqst *rqstp, u32 *p,
rqstp->rq_res.page_len = resp->count;
if (resp->count & 3) {
/* need to pad the tail */
rqstp->rq_restailpage = 0;
rqstp->rq_res.tail[0].iov_base = p;
*p = 0;
rqstp->rq_res.tail[0].iov_len = 4 - (resp->count & 3);
......
......@@ -1735,6 +1735,7 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_read
svc_take_page(resp->rqstp);
resp->xbuf->tail[0].iov_base =
page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused-1]);
resp->rqstp->rq_restailpage = resp->rqstp->rq_resused-1;
resp->xbuf->tail[0].iov_len = 0;
resp->p = resp->xbuf->tail[0].iov_base;
resp->end = resp->p + PAGE_SIZE/4;
......@@ -1782,6 +1783,7 @@ nfsd4_encode_readlink(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_r
svc_take_page(resp->rqstp);
resp->xbuf->tail[0].iov_base =
page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused-1]);
resp->rqstp->rq_restailpage = resp->rqstp->rq_resused-1;
resp->xbuf->tail[0].iov_len = 0;
resp->p = resp->xbuf->tail[0].iov_base;
resp->end = resp->p + PAGE_SIZE/4;
......@@ -1859,6 +1861,7 @@ nfsd4_encode_readdir(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_re
svc_take_page(resp->rqstp);
resp->xbuf->tail[0].iov_base =
page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused-1]);
resp->rqstp->rq_restailpage = resp->rqstp->rq_resused-1;
resp->xbuf->tail[0].iov_len = 0;
resp->p = resp->xbuf->tail[0].iov_base;
resp->end = resp->p + PAGE_SIZE/4;
......
......@@ -396,6 +396,7 @@ nfssvc_encode_readlinkres(struct svc_rqst *rqstp, u32 *p,
rqstp->rq_res.page_len = resp->len;
if (resp->len & 3) {
/* need to pad the tail */
rqstp->rq_restailpage = 0;
rqstp->rq_res.tail[0].iov_base = p;
*p = 0;
rqstp->rq_res.tail[0].iov_len = 4 - (resp->len&3);
......@@ -415,6 +416,7 @@ nfssvc_encode_readres(struct svc_rqst *rqstp, u32 *p,
rqstp->rq_res.page_len = resp->count;
if (resp->count & 3) {
/* need to pad the tail */
rqstp->rq_restailpage = 0;
rqstp->rq_res.tail[0].iov_base = p;
*p = 0;
rqstp->rq_res.tail[0].iov_len = 4 - (resp->count&3);
......
......@@ -114,6 +114,7 @@ struct svc_rqst {
struct xdr_buf rq_res;
struct page * rq_argpages[RPCSVC_MAXPAGES];
struct page * rq_respages[RPCSVC_MAXPAGES];
int rq_restailpage;
short rq_argused; /* pages used for argument */
short rq_arghi; /* pages available in argument page list */
short rq_resused; /* pages used for result */
......
......@@ -388,7 +388,7 @@ svc_sendto(struct svc_rqst *rqstp, struct xdr_buf *xdr)
/* send tail */
if (xdr->tail[0].iov_len) {
/* The tail *will* be in respages[0]; */
result = sock->ops->sendpage(sock, rqstp->rq_respages[0],
result = sock->ops->sendpage(sock, rqstp->rq_respages[rqstp->rq_restailpage],
((unsigned long)xdr->tail[0].iov_base)& (PAGE_SIZE-1),
xdr->tail[0].iov_len, 0);
......
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