aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@redhat.com>2012-12-10 18:01:37 -0500
committerJ. Bruce Fields <bfields@redhat.com>2012-12-17 22:00:16 -0500
commitafc59400d6c65bad66d4ad0b2daf879cbff8e23e (patch)
treecc4c1c4dcf01106259d4f18d637cb2d1115ef980
parent79f77bf9a4e3dd5ead006b8f17e7c4ff07d8374e (diff)
nfsd4: cleanup: replace rq_resused count by rq_next_page pointer
It may be a matter of personal taste, but I find this makes the code clearer. Signed-off-by: J. Bruce Fields <bfields@redhat.com>
-rw-r--r--fs/nfsd/nfs2acl.c2
-rw-r--r--fs/nfsd/nfs3acl.c2
-rw-r--r--fs/nfsd/nfs3proc.c6
-rw-r--r--fs/nfsd/nfs3xdr.c33
-rw-r--r--fs/nfsd/nfs4xdr.c24
-rw-r--r--fs/nfsd/nfsxdr.c11
-rw-r--r--fs/nfsd/vfs.c18
-rw-r--r--include/linux/sunrpc/svc.h6
-rw-r--r--net/sunrpc/svc.c2
-rw-r--r--net/sunrpc/svcsock.c2
-rw-r--r--net/sunrpc/xprtrdma/svc_rdma_recvfrom.c10
-rw-r--r--net/sunrpc/xprtrdma/svc_rdma_sendto.c4
12 files changed, 61 insertions, 59 deletions
diff --git a/fs/nfsd/nfs2acl.c b/fs/nfsd/nfs2acl.c
index b314888825d5..9170861c804a 100644
--- a/fs/nfsd/nfs2acl.c
+++ b/fs/nfsd/nfs2acl.c
@@ -253,7 +253,7 @@ static int nfsaclsvc_encode_getaclres(struct svc_rqst *rqstp, __be32 *p,
253 (resp->mask & NFS_ACL) ? resp->acl_access : NULL, 253 (resp->mask & NFS_ACL) ? resp->acl_access : NULL,
254 (resp->mask & NFS_DFACL) ? resp->acl_default : NULL); 254 (resp->mask & NFS_DFACL) ? resp->acl_default : NULL);
255 while (w > 0) { 255 while (w > 0) {
256 if (!rqstp->rq_respages[rqstp->rq_resused++]) 256 if (!*(rqstp->rq_next_page++))
257 return 0; 257 return 0;
258 w -= PAGE_SIZE; 258 w -= PAGE_SIZE;
259 } 259 }
diff --git a/fs/nfsd/nfs3acl.c b/fs/nfsd/nfs3acl.c
index a596e9d987e4..9cbc1a841f87 100644
--- a/fs/nfsd/nfs3acl.c
+++ b/fs/nfsd/nfs3acl.c
@@ -184,7 +184,7 @@ static int nfs3svc_encode_getaclres(struct svc_rqst *rqstp, __be32 *p,
184 (resp->mask & NFS_ACL) ? resp->acl_access : NULL, 184 (resp->mask & NFS_ACL) ? resp->acl_access : NULL,
185 (resp->mask & NFS_DFACL) ? resp->acl_default : NULL); 185 (resp->mask & NFS_DFACL) ? resp->acl_default : NULL);
186 while (w > 0) { 186 while (w > 0) {
187 if (!rqstp->rq_respages[rqstp->rq_resused++]) 187 if (!*(rqstp->rq_next_page++))
188 return 0; 188 return 0;
189 w -= PAGE_SIZE; 189 w -= PAGE_SIZE;
190 } 190 }
diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c
index 97d90d1c8608..1fc02dfdc5c4 100644
--- a/fs/nfsd/nfs3proc.c
+++ b/fs/nfsd/nfs3proc.c
@@ -460,7 +460,7 @@ nfsd3_proc_readdirplus(struct svc_rqst *rqstp, struct nfsd3_readdirargs *argp,
460 __be32 nfserr; 460 __be32 nfserr;
461 int count = 0; 461 int count = 0;
462 loff_t offset; 462 loff_t offset;
463 int i; 463 struct page **p;
464 caddr_t page_addr = NULL; 464 caddr_t page_addr = NULL;
465 465
466 dprintk("nfsd: READDIR+(3) %s %d bytes at %d\n", 466 dprintk("nfsd: READDIR+(3) %s %d bytes at %d\n",
@@ -484,8 +484,8 @@ nfsd3_proc_readdirplus(struct svc_rqst *rqstp, struct nfsd3_readdirargs *argp,
484 &resp->common, 484 &resp->common,
485 nfs3svc_encode_entry_plus); 485 nfs3svc_encode_entry_plus);
486 memcpy(resp->verf, argp->verf, 8); 486 memcpy(resp->verf, argp->verf, 8);
487 for (i=1; i<rqstp->rq_resused ; i++) { 487 for (p = rqstp->rq_respages + 1; p < rqstp->rq_next_page; p++) {
488 page_addr = page_address(rqstp->rq_respages[i]); 488 page_addr = page_address(*p);
489 489
490 if (((caddr_t)resp->buffer >= page_addr) && 490 if (((caddr_t)resp->buffer >= page_addr) &&
491 ((caddr_t)resp->buffer < page_addr + PAGE_SIZE)) { 491 ((caddr_t)resp->buffer < page_addr + PAGE_SIZE)) {
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index 2b8618de6c27..324c0baf7cda 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -325,7 +325,7 @@ nfs3svc_decode_readargs(struct svc_rqst *rqstp, __be32 *p,
325 struct nfsd3_readargs *args) 325 struct nfsd3_readargs *args)
326{ 326{
327 unsigned int len; 327 unsigned int len;
328 int v,pn; 328 int v;
329 u32 max_blocksize = svc_max_payload(rqstp); 329 u32 max_blocksize = svc_max_payload(rqstp);
330 330
331 if (!(p = decode_fh(p, &args->fh))) 331 if (!(p = decode_fh(p, &args->fh)))
@@ -340,8 +340,9 @@ nfs3svc_decode_readargs(struct svc_rqst *rqstp, __be32 *p,
340 /* set up the kvec */ 340 /* set up the kvec */
341 v=0; 341 v=0;
342 while (len > 0) { 342 while (len > 0) {
343 pn = rqstp->rq_resused++; 343 struct page *p = *(rqstp->rq_next_page++);
344 rqstp->rq_vec[v].iov_base = page_address(rqstp->rq_respages[pn]); 344
345 rqstp->rq_vec[v].iov_base = page_address(p);
345 rqstp->rq_vec[v].iov_len = len < PAGE_SIZE? len : PAGE_SIZE; 346 rqstp->rq_vec[v].iov_len = len < PAGE_SIZE? len : PAGE_SIZE;
346 len -= rqstp->rq_vec[v].iov_len; 347 len -= rqstp->rq_vec[v].iov_len;
347 v++; 348 v++;
@@ -463,8 +464,7 @@ nfs3svc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p,
463 len = ntohl(*p++); 464 len = ntohl(*p++);
464 if (len == 0 || len > NFS3_MAXPATHLEN || len >= PAGE_SIZE) 465 if (len == 0 || len > NFS3_MAXPATHLEN || len >= PAGE_SIZE)
465 return 0; 466 return 0;
466 args->tname = new = 467 args->tname = new = page_address(*(rqstp->rq_next_page++));
467 page_address(rqstp->rq_respages[rqstp->rq_resused++]);
468 args->tlen = len; 468 args->tlen = len;
469 /* first copy and check from the first page */ 469 /* first copy and check from the first page */
470 old = (char*)p; 470 old = (char*)p;
@@ -535,8 +535,7 @@ nfs3svc_decode_readlinkargs(struct svc_rqst *rqstp, __be32 *p,
535{ 535{
536 if (!(p = decode_fh(p, &args->fh))) 536 if (!(p = decode_fh(p, &args->fh)))
537 return 0; 537 return 0;
538 args->buffer = 538 args->buffer = page_address(*(rqstp->rq_next_page++));
539 page_address(rqstp->rq_respages[rqstp->rq_resused++]);
540 539
541 return xdr_argsize_check(rqstp, p); 540 return xdr_argsize_check(rqstp, p);
542} 541}
@@ -567,8 +566,7 @@ nfs3svc_decode_readdirargs(struct svc_rqst *rqstp, __be32 *p,
567 if (args->count > PAGE_SIZE) 566 if (args->count > PAGE_SIZE)
568 args->count = PAGE_SIZE; 567 args->count = PAGE_SIZE;
569 568
570 args->buffer = 569 args->buffer = page_address(*(rqstp->rq_next_page++));
571 page_address(rqstp->rq_respages[rqstp->rq_resused++]);
572 570
573 return xdr_argsize_check(rqstp, p); 571 return xdr_argsize_check(rqstp, p);
574} 572}
@@ -577,7 +575,7 @@ int
577nfs3svc_decode_readdirplusargs(struct svc_rqst *rqstp, __be32 *p, 575nfs3svc_decode_readdirplusargs(struct svc_rqst *rqstp, __be32 *p,
578 struct nfsd3_readdirargs *args) 576 struct nfsd3_readdirargs *args)
579{ 577{
580 int len, pn; 578 int len;
581 u32 max_blocksize = svc_max_payload(rqstp); 579 u32 max_blocksize = svc_max_payload(rqstp);
582 580
583 if (!(p = decode_fh(p, &args->fh))) 581 if (!(p = decode_fh(p, &args->fh)))
@@ -592,9 +590,9 @@ nfs3svc_decode_readdirplusargs(struct svc_rqst *rqstp, __be32 *p,
592 args->count = len; 590 args->count = len;
593 591
594 while (len > 0) { 592 while (len > 0) {
595 pn = rqstp->rq_resused++; 593 struct page *p = *(rqstp->rq_next_page++);
596 if (!args->buffer) 594 if (!args->buffer)
597 args->buffer = page_address(rqstp->rq_respages[pn]); 595 args->buffer = page_address(p);
598 len -= PAGE_SIZE; 596 len -= PAGE_SIZE;
599 } 597 }
600 598
@@ -880,7 +878,7 @@ encode_entry(struct readdir_cd *ccd, const char *name, int namlen,
880 common); 878 common);
881 __be32 *p = cd->buffer; 879 __be32 *p = cd->buffer;
882 caddr_t curr_page_addr = NULL; 880 caddr_t curr_page_addr = NULL;
883 int pn; /* current page number */ 881 struct page ** page;
884 int slen; /* string (name) length */ 882 int slen; /* string (name) length */
885 int elen; /* estimated entry length in words */ 883 int elen; /* estimated entry length in words */
886 int num_entry_words = 0; /* actual number of words */ 884 int num_entry_words = 0; /* actual number of words */
@@ -917,8 +915,9 @@ encode_entry(struct readdir_cd *ccd, const char *name, int namlen,
917 } 915 }
918 916
919 /* determine which page in rq_respages[] we are currently filling */ 917 /* determine which page in rq_respages[] we are currently filling */
920 for (pn=1; pn < cd->rqstp->rq_resused; pn++) { 918 for (page = cd->rqstp->rq_respages + 1;
921 curr_page_addr = page_address(cd->rqstp->rq_respages[pn]); 919 page < cd->rqstp->rq_next_page; page++) {
920 curr_page_addr = page_address(*page);
922 921
923 if (((caddr_t)cd->buffer >= curr_page_addr) && 922 if (((caddr_t)cd->buffer >= curr_page_addr) &&
924 ((caddr_t)cd->buffer < curr_page_addr + PAGE_SIZE)) 923 ((caddr_t)cd->buffer < curr_page_addr + PAGE_SIZE))
@@ -933,14 +932,14 @@ encode_entry(struct readdir_cd *ccd, const char *name, int namlen,
933 if (plus) 932 if (plus)
934 p = encode_entryplus_baggage(cd, p, name, namlen); 933 p = encode_entryplus_baggage(cd, p, name, namlen);
935 num_entry_words = p - cd->buffer; 934 num_entry_words = p - cd->buffer;
936 } else if (cd->rqstp->rq_respages[pn+1] != NULL) { 935 } else if (*(page+1) != NULL) {
937 /* temporarily encode entry into next page, then move back to 936 /* temporarily encode entry into next page, then move back to
938 * current and next page in rq_respages[] */ 937 * current and next page in rq_respages[] */
939 __be32 *p1, *tmp; 938 __be32 *p1, *tmp;
940 int len1, len2; 939 int len1, len2;
941 940
942 /* grab next page for temporary storage of entry */ 941 /* grab next page for temporary storage of entry */
943 p1 = tmp = page_address(cd->rqstp->rq_respages[pn+1]); 942 p1 = tmp = page_address(*(page+1));
944 943
945 p1 = encode_entry_baggage(cd, p1, name, namlen, ino); 944 p1 = encode_entry_baggage(cd, p1, name, namlen, ino);
946 945
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index d7a3be5ab777..0dc11586682f 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -2906,7 +2906,8 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
2906 struct nfsd4_read *read) 2906 struct nfsd4_read *read)
2907{ 2907{
2908 u32 eof; 2908 u32 eof;
2909 int v, pn; 2909 int v;
2910 struct page *page;
2910 unsigned long maxcount; 2911 unsigned long maxcount;
2911 long len; 2912 long len;
2912 __be32 *p; 2913 __be32 *p;
@@ -2925,16 +2926,15 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
2925 len = maxcount; 2926 len = maxcount;
2926 v = 0; 2927 v = 0;
2927 while (len > 0) { 2928 while (len > 0) {
2928 pn = resp->rqstp->rq_resused; 2929 page = *(resp->rqstp->rq_next_page);
2929 if (!resp->rqstp->rq_respages[pn]) { /* ran out of pages */ 2930 if (!page) { /* ran out of pages */
2930 maxcount -= len; 2931 maxcount -= len;
2931 break; 2932 break;
2932 } 2933 }
2933 resp->rqstp->rq_vec[v].iov_base = 2934 resp->rqstp->rq_vec[v].iov_base = page_address(page);
2934 page_address(resp->rqstp->rq_respages[pn]);
2935 resp->rqstp->rq_vec[v].iov_len = 2935 resp->rqstp->rq_vec[v].iov_len =
2936 len < PAGE_SIZE ? len : PAGE_SIZE; 2936 len < PAGE_SIZE ? len : PAGE_SIZE;
2937 resp->rqstp->rq_resused++; 2937 resp->rqstp->rq_next_page++;
2938 v++; 2938 v++;
2939 len -= PAGE_SIZE; 2939 len -= PAGE_SIZE;
2940 } 2940 }
@@ -2980,10 +2980,10 @@ nfsd4_encode_readlink(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd
2980 return nfserr; 2980 return nfserr;
2981 if (resp->xbuf->page_len) 2981 if (resp->xbuf->page_len)
2982 return nfserr_resource; 2982 return nfserr_resource;
2983 if (!resp->rqstp->rq_respages[resp->rqstp->rq_resused]) 2983 if (!*resp->rqstp->rq_next_page)
2984 return nfserr_resource; 2984 return nfserr_resource;
2985 2985
2986 page = page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused++]); 2986 page = page_address(*(resp->rqstp->rq_next_page++));
2987 2987
2988 maxcount = PAGE_SIZE; 2988 maxcount = PAGE_SIZE;
2989 RESERVE_SPACE(4); 2989 RESERVE_SPACE(4);
@@ -3031,7 +3031,7 @@ nfsd4_encode_readdir(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4
3031 return nfserr; 3031 return nfserr;
3032 if (resp->xbuf->page_len) 3032 if (resp->xbuf->page_len)
3033 return nfserr_resource; 3033 return nfserr_resource;
3034 if (!resp->rqstp->rq_respages[resp->rqstp->rq_resused]) 3034 if (!*resp->rqstp->rq_next_page)
3035 return nfserr_resource; 3035 return nfserr_resource;
3036 3036
3037 RESERVE_SPACE(NFS4_VERIFIER_SIZE); 3037 RESERVE_SPACE(NFS4_VERIFIER_SIZE);
@@ -3059,7 +3059,7 @@ nfsd4_encode_readdir(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4
3059 goto err_no_verf; 3059 goto err_no_verf;
3060 } 3060 }
3061 3061
3062 page = page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused++]); 3062 page = page_address(*(resp->rqstp->rq_next_page++));
3063 readdir->common.err = 0; 3063 readdir->common.err = 0;
3064 readdir->buflen = maxcount; 3064 readdir->buflen = maxcount;
3065 readdir->buffer = page; 3065 readdir->buffer = page;
@@ -3082,8 +3082,8 @@ nfsd4_encode_readdir(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4
3082 p = readdir->buffer; 3082 p = readdir->buffer;
3083 *p++ = 0; /* no more entries */ 3083 *p++ = 0; /* no more entries */
3084 *p++ = htonl(readdir->common.err == nfserr_eof); 3084 *p++ = htonl(readdir->common.err == nfserr_eof);
3085 resp->xbuf->page_len = ((char*)p) - (char*)page_address( 3085 resp->xbuf->page_len = ((char*)p) -
3086 resp->rqstp->rq_respages[resp->rqstp->rq_resused-1]); 3086 (char*)page_address(*(resp->rqstp->rq_next_page-1));
3087 3087
3088 /* Use rest of head for padding and remaining ops: */ 3088 /* Use rest of head for padding and remaining ops: */
3089 resp->xbuf->tail[0].iov_base = tailbase; 3089 resp->xbuf->tail[0].iov_base = tailbase;
diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c
index 65ec595e2226..979b42106979 100644
--- a/fs/nfsd/nfsxdr.c
+++ b/fs/nfsd/nfsxdr.c
@@ -246,7 +246,7 @@ nfssvc_decode_readargs(struct svc_rqst *rqstp, __be32 *p,
246 struct nfsd_readargs *args) 246 struct nfsd_readargs *args)
247{ 247{
248 unsigned int len; 248 unsigned int len;
249 int v,pn; 249 int v;
250 if (!(p = decode_fh(p, &args->fh))) 250 if (!(p = decode_fh(p, &args->fh)))
251 return 0; 251 return 0;
252 252
@@ -262,8 +262,9 @@ nfssvc_decode_readargs(struct svc_rqst *rqstp, __be32 *p,
262 */ 262 */
263 v=0; 263 v=0;
264 while (len > 0) { 264 while (len > 0) {
265 pn = rqstp->rq_resused++; 265 struct page *p = *(rqstp->rq_next_page++);
266 rqstp->rq_vec[v].iov_base = page_address(rqstp->rq_respages[pn]); 266
267 rqstp->rq_vec[v].iov_base = page_address(p);
267 rqstp->rq_vec[v].iov_len = len < PAGE_SIZE?len:PAGE_SIZE; 268 rqstp->rq_vec[v].iov_len = len < PAGE_SIZE?len:PAGE_SIZE;
268 len -= rqstp->rq_vec[v].iov_len; 269 len -= rqstp->rq_vec[v].iov_len;
269 v++; 270 v++;
@@ -355,7 +356,7 @@ nfssvc_decode_readlinkargs(struct svc_rqst *rqstp, __be32 *p, struct nfsd_readli
355{ 356{
356 if (!(p = decode_fh(p, &args->fh))) 357 if (!(p = decode_fh(p, &args->fh)))
357 return 0; 358 return 0;
358 args->buffer = page_address(rqstp->rq_respages[rqstp->rq_resused++]); 359 args->buffer = page_address(*(rqstp->rq_next_page++));
359 360
360 return xdr_argsize_check(rqstp, p); 361 return xdr_argsize_check(rqstp, p);
361} 362}
@@ -396,7 +397,7 @@ nfssvc_decode_readdirargs(struct svc_rqst *rqstp, __be32 *p,
396 if (args->count > PAGE_SIZE) 397 if (args->count > PAGE_SIZE)
397 args->count = PAGE_SIZE; 398 args->count = PAGE_SIZE;
398 399
399 args->buffer = page_address(rqstp->rq_respages[rqstp->rq_resused++]); 400 args->buffer = page_address(*(rqstp->rq_next_page++));
400 401
401 return xdr_argsize_check(rqstp, p); 402 return xdr_argsize_check(rqstp, p);
402} 403}
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index b31e46eeb026..f0a6d88d7fff 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -886,7 +886,7 @@ nfsd_splice_actor(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
886 struct splice_desc *sd) 886 struct splice_desc *sd)
887{ 887{
888 struct svc_rqst *rqstp = sd->u.data; 888 struct svc_rqst *rqstp = sd->u.data;
889 struct page **pp = rqstp->rq_respages + rqstp->rq_resused; 889 struct page **pp = rqstp->rq_next_page;
890 struct page *page = buf->page; 890 struct page *page = buf->page;
891 size_t size; 891 size_t size;
892 892
@@ -894,17 +894,15 @@ nfsd_splice_actor(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
894 894
895 if (rqstp->rq_res.page_len == 0) { 895 if (rqstp->rq_res.page_len == 0) {
896 get_page(page); 896 get_page(page);
897 put_page(*pp); 897 put_page(*rqstp->rq_next_page);
898 *pp = page; 898 *(rqstp->rq_next_page++) = page;
899 rqstp->rq_resused++;
900 rqstp->rq_res.page_base = buf->offset; 899 rqstp->rq_res.page_base = buf->offset;
901 rqstp->rq_res.page_len = size; 900 rqstp->rq_res.page_len = size;
902 } else if (page != pp[-1]) { 901 } else if (page != pp[-1]) {
903 get_page(page); 902 get_page(page);
904 if (*pp) 903 if (*rqstp->rq_next_page)
905 put_page(*pp); 904 put_page(*rqstp->rq_next_page);
906 *pp = page; 905 *(rqstp->rq_next_page++) = page;
907 rqstp->rq_resused++;
908 rqstp->rq_res.page_len += size; 906 rqstp->rq_res.page_len += size;
909 } else 907 } else
910 rqstp->rq_res.page_len += size; 908 rqstp->rq_res.page_len += size;
@@ -936,8 +934,8 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
936 .u.data = rqstp, 934 .u.data = rqstp,
937 }; 935 };
938 936
939 WARN_ON_ONCE(rqstp->rq_resused != 1); 937 WARN_ON_ONCE(rqstp->rq_next_page != rqstp->rq_respages + 1);
940 rqstp->rq_resused = 1; 938 rqstp->rq_next_page = rqstp->rq_respages + 1;
941 host_err = splice_direct_to_actor(file, &sd, nfsd_direct_splice_actor); 939 host_err = splice_direct_to_actor(file, &sd, nfsd_direct_splice_actor);
942 } else { 940 } else {
943 oldfs = get_fs(); 941 oldfs = get_fs();
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
index d83db800fe02..676ddf53b3ee 100644
--- a/include/linux/sunrpc/svc.h
+++ b/include/linux/sunrpc/svc.h
@@ -243,6 +243,7 @@ struct svc_rqst {
243 struct page * rq_pages[RPCSVC_MAXPAGES]; 243 struct page * rq_pages[RPCSVC_MAXPAGES];
244 struct page * *rq_respages; /* points into rq_pages */ 244 struct page * *rq_respages; /* points into rq_pages */
245 int rq_resused; /* number of pages used for result */ 245 int rq_resused; /* number of pages used for result */
246 struct page * *rq_next_page; /* next reply page to use */
246 247
247 struct kvec rq_vec[RPCSVC_MAXPAGES]; /* generally useful.. */ 248 struct kvec rq_vec[RPCSVC_MAXPAGES]; /* generally useful.. */
248 249
@@ -338,9 +339,8 @@ xdr_ressize_check(struct svc_rqst *rqstp, __be32 *p)
338 339
339static inline void svc_free_res_pages(struct svc_rqst *rqstp) 340static inline void svc_free_res_pages(struct svc_rqst *rqstp)
340{ 341{
341 while (rqstp->rq_resused) { 342 while (rqstp->rq_next_page != rqstp->rq_respages) {
342 struct page **pp = (rqstp->rq_respages + 343 struct page **pp = --rqstp->rq_next_page;
343 --rqstp->rq_resused);
344 if (*pp) { 344 if (*pp) {
345 put_page(*pp); 345 put_page(*pp);
346 *pp = NULL; 346 *pp = NULL;
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
index 529400d59755..c6abf1a6ba95 100644
--- a/net/sunrpc/svc.c
+++ b/net/sunrpc/svc.c
@@ -1297,7 +1297,7 @@ svc_process(struct svc_rqst *rqstp)
1297 * Setup response xdr_buf. 1297 * Setup response xdr_buf.
1298 * Initially it has just one page 1298 * Initially it has just one page
1299 */ 1299 */
1300 rqstp->rq_resused = 1; 1300 rqstp->rq_next_page = &rqstp->rq_respages[1];
1301 resv->iov_base = page_address(rqstp->rq_respages[0]); 1301 resv->iov_base = page_address(rqstp->rq_respages[0]);
1302 resv->iov_len = 0; 1302 resv->iov_len = 0;
1303 rqstp->rq_res.pages = rqstp->rq_respages + 1; 1303 rqstp->rq_res.pages = rqstp->rq_respages + 1;
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
index d8e5adfeac30..dcd5669c5154 100644
--- a/net/sunrpc/svcsock.c
+++ b/net/sunrpc/svcsock.c
@@ -601,6 +601,7 @@ static int svc_udp_recvfrom(struct svc_rqst *rqstp)
601 rqstp->rq_respages = rqstp->rq_pages + 1 + 601 rqstp->rq_respages = rqstp->rq_pages + 1 +
602 DIV_ROUND_UP(rqstp->rq_arg.page_len, PAGE_SIZE); 602 DIV_ROUND_UP(rqstp->rq_arg.page_len, PAGE_SIZE);
603 } 603 }
604 rqstp->rq_next_page = rqstp->rq_respages+1;
604 605
605 if (serv->sv_stats) 606 if (serv->sv_stats)
606 serv->sv_stats->netudpcnt++; 607 serv->sv_stats->netudpcnt++;
@@ -1066,6 +1067,7 @@ static int svc_tcp_recvfrom(struct svc_rqst *rqstp)
1066 svsk->sk_datalen + want); 1067 svsk->sk_datalen + want);
1067 1068
1068 rqstp->rq_respages = &rqstp->rq_pages[pnum]; 1069 rqstp->rq_respages = &rqstp->rq_pages[pnum];
1070 rqstp->rq_next_page = rqstp->rq_respages + 1;
1069 1071
1070 /* Now receive data */ 1072 /* Now receive data */
1071 len = svc_partial_recvfrom(rqstp, vec, pnum, want, base); 1073 len = svc_partial_recvfrom(rqstp, vec, pnum, want, base);
diff --git a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
index 41cb63b623df..0ce75524ed21 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
@@ -521,11 +521,11 @@ next_sge:
521 rqstp->rq_pages[ch_no] = NULL; 521 rqstp->rq_pages[ch_no] = NULL;
522 522
523 /* 523 /*
524 * Detach res pages. svc_release must see a resused count of 524 * Detach res pages. If svc_release sees any it will attempt to
525 * zero or it will attempt to put them. 525 * put them.
526 */ 526 */
527 while (rqstp->rq_resused) 527 while (rqstp->rq_next_page != rqstp->rq_respages)
528 rqstp->rq_respages[--rqstp->rq_resused] = NULL; 528 *(--rqstp->rq_next_page) = NULL;
529 529
530 return err; 530 return err;
531} 531}
@@ -550,7 +550,7 @@ static int rdma_read_complete(struct svc_rqst *rqstp,
550 550
551 /* rq_respages starts after the last arg page */ 551 /* rq_respages starts after the last arg page */
552 rqstp->rq_respages = &rqstp->rq_arg.pages[page_no]; 552 rqstp->rq_respages = &rqstp->rq_arg.pages[page_no];
553 rqstp->rq_resused = 0; 553 rqstp->rq_next_page = &rqstp->rq_arg.pages[page_no];
554 554
555 /* Rebuild rq_arg head and tail. */ 555 /* Rebuild rq_arg head and tail. */
556 rqstp->rq_arg.head[0] = head->arg.head[0]; 556 rqstp->rq_arg.head[0] = head->arg.head[0];
diff --git a/net/sunrpc/xprtrdma/svc_rdma_sendto.c b/net/sunrpc/xprtrdma/svc_rdma_sendto.c
index 42eb7ba0b903..c1d124dc772b 100644
--- a/net/sunrpc/xprtrdma/svc_rdma_sendto.c
+++ b/net/sunrpc/xprtrdma/svc_rdma_sendto.c
@@ -548,6 +548,7 @@ static int send_reply(struct svcxprt_rdma *rdma,
548 int sge_no; 548 int sge_no;
549 int sge_bytes; 549 int sge_bytes;
550 int page_no; 550 int page_no;
551 int pages;
551 int ret; 552 int ret;
552 553
553 /* Post a recv buffer to handle another request. */ 554 /* Post a recv buffer to handle another request. */
@@ -611,7 +612,8 @@ static int send_reply(struct svcxprt_rdma *rdma,
611 * respages array. They are our pages until the I/O 612 * respages array. They are our pages until the I/O
612 * completes. 613 * completes.
613 */ 614 */
614 for (page_no = 0; page_no < rqstp->rq_resused; page_no++) { 615 pages = rqstp->rq_next_page - rqstp->rq_respages;
616 for (page_no = 0; page_no < pages; page_no++) {
615 ctxt->pages[page_no+1] = rqstp->rq_respages[page_no]; 617 ctxt->pages[page_no+1] = rqstp->rq_respages[page_no];
616 ctxt->count++; 618 ctxt->count++;
617 rqstp->rq_respages[page_no] = NULL; 619 rqstp->rq_respages[page_no] = NULL;