diff options
| -rw-r--r-- | fs/nfsd/nfs2acl.c | 2 | ||||
| -rw-r--r-- | fs/nfsd/nfs3acl.c | 2 | ||||
| -rw-r--r-- | fs/nfsd/nfs3xdr.c | 23 | ||||
| -rw-r--r-- | fs/nfsd/nfs4xdr.c | 27 | ||||
| -rw-r--r-- | fs/nfsd/nfsxdr.c | 13 | ||||
| -rw-r--r-- | fs/nfsd/vfs.c | 16 | ||||
| -rw-r--r-- | include/linux/sunrpc/svc.h | 69 | ||||
| -rw-r--r-- | net/sunrpc/auth_gss/svcauth_gss.c | 4 | ||||
| -rw-r--r-- | net/sunrpc/svc.c | 21 | ||||
| -rw-r--r-- | net/sunrpc/svcsock.c | 41 |
10 files changed, 77 insertions, 141 deletions
diff --git a/fs/nfsd/nfs2acl.c b/fs/nfsd/nfs2acl.c index fe56b38364cc..71108da2e54e 100644 --- a/fs/nfsd/nfs2acl.c +++ b/fs/nfsd/nfs2acl.c | |||
| @@ -241,7 +241,7 @@ static int nfsaclsvc_encode_getaclres(struct svc_rqst *rqstp, u32 *p, | |||
| 241 | 241 | ||
| 242 | rqstp->rq_res.page_len = w; | 242 | rqstp->rq_res.page_len = w; |
| 243 | while (w > 0) { | 243 | while (w > 0) { |
| 244 | if (!svc_take_res_page(rqstp)) | 244 | if (!rqstp->rq_respages[rqstp->rq_resused++]) |
| 245 | return 0; | 245 | return 0; |
| 246 | w -= PAGE_SIZE; | 246 | w -= PAGE_SIZE; |
| 247 | } | 247 | } |
diff --git a/fs/nfsd/nfs3acl.c b/fs/nfsd/nfs3acl.c index 16e10c170aed..f813b054f4a1 100644 --- a/fs/nfsd/nfs3acl.c +++ b/fs/nfsd/nfs3acl.c | |||
| @@ -185,7 +185,7 @@ static int nfs3svc_encode_getaclres(struct svc_rqst *rqstp, u32 *p, | |||
| 185 | 185 | ||
| 186 | rqstp->rq_res.page_len = w; | 186 | rqstp->rq_res.page_len = w; |
| 187 | while (w > 0) { | 187 | while (w > 0) { |
| 188 | if (!svc_take_res_page(rqstp)) | 188 | if (!rqstp->rq_respages[rqstp->rq_resused++]) |
| 189 | return 0; | 189 | return 0; |
| 190 | w -= PAGE_SIZE; | 190 | w -= PAGE_SIZE; |
| 191 | } | 191 | } |
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c index 243d94b9653a..20ba728a4642 100644 --- a/fs/nfsd/nfs3xdr.c +++ b/fs/nfsd/nfs3xdr.c | |||
| @@ -343,8 +343,7 @@ nfs3svc_decode_readargs(struct svc_rqst *rqstp, u32 *p, | |||
| 343 | /* set up the kvec */ | 343 | /* set up the kvec */ |
| 344 | v=0; | 344 | v=0; |
| 345 | while (len > 0) { | 345 | while (len > 0) { |
| 346 | pn = rqstp->rq_resused; | 346 | pn = rqstp->rq_resused++; |
| 347 | svc_take_page(rqstp); | ||
| 348 | args->vec[v].iov_base = page_address(rqstp->rq_respages[pn]); | 347 | args->vec[v].iov_base = page_address(rqstp->rq_respages[pn]); |
| 349 | args->vec[v].iov_len = len < PAGE_SIZE? len : PAGE_SIZE; | 348 | args->vec[v].iov_len = len < PAGE_SIZE? len : PAGE_SIZE; |
| 350 | len -= args->vec[v].iov_len; | 349 | len -= args->vec[v].iov_len; |
| @@ -382,7 +381,7 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, u32 *p, | |||
| 382 | while (len > args->vec[v].iov_len) { | 381 | while (len > args->vec[v].iov_len) { |
| 383 | len -= args->vec[v].iov_len; | 382 | len -= args->vec[v].iov_len; |
| 384 | v++; | 383 | v++; |
| 385 | args->vec[v].iov_base = page_address(rqstp->rq_argpages[v]); | 384 | args->vec[v].iov_base = page_address(rqstp->rq_pages[v]); |
| 386 | args->vec[v].iov_len = PAGE_SIZE; | 385 | args->vec[v].iov_len = PAGE_SIZE; |
| 387 | } | 386 | } |
| 388 | args->vec[v].iov_len = len; | 387 | args->vec[v].iov_len = len; |
| @@ -446,11 +445,11 @@ nfs3svc_decode_symlinkargs(struct svc_rqst *rqstp, u32 *p, | |||
| 446 | * This page appears in the rq_res.pages list, but as pages_len is always | 445 | * This page appears in the rq_res.pages list, but as pages_len is always |
| 447 | * 0, it won't get in the way | 446 | * 0, it won't get in the way |
| 448 | */ | 447 | */ |
| 449 | svc_take_page(rqstp); | ||
| 450 | len = ntohl(*p++); | 448 | len = ntohl(*p++); |
| 451 | if (len == 0 || len > NFS3_MAXPATHLEN || len >= PAGE_SIZE) | 449 | if (len == 0 || len > NFS3_MAXPATHLEN || len >= PAGE_SIZE) |
| 452 | return 0; | 450 | return 0; |
| 453 | args->tname = new = page_address(rqstp->rq_respages[rqstp->rq_resused-1]); | 451 | args->tname = new = |
| 452 | page_address(rqstp->rq_respages[rqstp->rq_resused++]); | ||
| 454 | args->tlen = len; | 453 | args->tlen = len; |
| 455 | /* first copy and check from the first page */ | 454 | /* first copy and check from the first page */ |
| 456 | old = (char*)p; | 455 | old = (char*)p; |
| @@ -522,8 +521,8 @@ nfs3svc_decode_readlinkargs(struct svc_rqst *rqstp, u32 *p, | |||
| 522 | { | 521 | { |
| 523 | if (!(p = decode_fh(p, &args->fh))) | 522 | if (!(p = decode_fh(p, &args->fh))) |
| 524 | return 0; | 523 | return 0; |
| 525 | svc_take_page(rqstp); | 524 | args->buffer = |
| 526 | args->buffer = page_address(rqstp->rq_respages[rqstp->rq_resused-1]); | 525 | page_address(rqstp->rq_respages[rqstp->rq_resused++]); |
| 527 | 526 | ||
| 528 | return xdr_argsize_check(rqstp, p); | 527 | return xdr_argsize_check(rqstp, p); |
| 529 | } | 528 | } |
| @@ -554,8 +553,8 @@ nfs3svc_decode_readdirargs(struct svc_rqst *rqstp, u32 *p, | |||
| 554 | if (args->count > PAGE_SIZE) | 553 | if (args->count > PAGE_SIZE) |
| 555 | args->count = PAGE_SIZE; | 554 | args->count = PAGE_SIZE; |
| 556 | 555 | ||
| 557 | svc_take_page(rqstp); | 556 | args->buffer = |
| 558 | args->buffer = page_address(rqstp->rq_respages[rqstp->rq_resused-1]); | 557 | page_address(rqstp->rq_respages[rqstp->rq_resused++]); |
| 559 | 558 | ||
| 560 | return xdr_argsize_check(rqstp, p); | 559 | return xdr_argsize_check(rqstp, p); |
| 561 | } | 560 | } |
| @@ -578,8 +577,7 @@ nfs3svc_decode_readdirplusargs(struct svc_rqst *rqstp, u32 *p, | |||
| 578 | args->count = len; | 577 | args->count = len; |
| 579 | 578 | ||
| 580 | while (len > 0) { | 579 | while (len > 0) { |
| 581 | pn = rqstp->rq_resused; | 580 | pn = rqstp->rq_resused++; |
| 582 | svc_take_page(rqstp); | ||
| 583 | if (!args->buffer) | 581 | if (!args->buffer) |
| 584 | args->buffer = page_address(rqstp->rq_respages[pn]); | 582 | args->buffer = page_address(rqstp->rq_respages[pn]); |
| 585 | len -= PAGE_SIZE; | 583 | len -= PAGE_SIZE; |
| @@ -668,7 +666,6 @@ nfs3svc_encode_readlinkres(struct svc_rqst *rqstp, u32 *p, | |||
| 668 | rqstp->rq_res.page_len = resp->len; | 666 | rqstp->rq_res.page_len = resp->len; |
| 669 | if (resp->len & 3) { | 667 | if (resp->len & 3) { |
| 670 | /* need to pad the tail */ | 668 | /* need to pad the tail */ |
| 671 | rqstp->rq_restailpage = 0; | ||
| 672 | rqstp->rq_res.tail[0].iov_base = p; | 669 | rqstp->rq_res.tail[0].iov_base = p; |
| 673 | *p = 0; | 670 | *p = 0; |
| 674 | rqstp->rq_res.tail[0].iov_len = 4 - (resp->len&3); | 671 | rqstp->rq_res.tail[0].iov_len = 4 - (resp->len&3); |
| @@ -693,7 +690,6 @@ nfs3svc_encode_readres(struct svc_rqst *rqstp, u32 *p, | |||
| 693 | rqstp->rq_res.page_len = resp->count; | 690 | rqstp->rq_res.page_len = resp->count; |
| 694 | if (resp->count & 3) { | 691 | if (resp->count & 3) { |
| 695 | /* need to pad the tail */ | 692 | /* need to pad the tail */ |
| 696 | rqstp->rq_restailpage = 0; | ||
| 697 | rqstp->rq_res.tail[0].iov_base = p; | 693 | rqstp->rq_res.tail[0].iov_base = p; |
| 698 | *p = 0; | 694 | *p = 0; |
| 699 | rqstp->rq_res.tail[0].iov_len = 4 - (resp->count & 3); | 695 | rqstp->rq_res.tail[0].iov_len = 4 - (resp->count & 3); |
| @@ -768,7 +764,6 @@ nfs3svc_encode_readdirres(struct svc_rqst *rqstp, u32 *p, | |||
| 768 | rqstp->rq_res.page_len = (resp->count) << 2; | 764 | rqstp->rq_res.page_len = (resp->count) << 2; |
| 769 | 765 | ||
| 770 | /* add the 'tail' to the end of the 'head' page - page 0. */ | 766 | /* add the 'tail' to the end of the 'head' page - page 0. */ |
| 771 | rqstp->rq_restailpage = 0; | ||
| 772 | rqstp->rq_res.tail[0].iov_base = p; | 767 | rqstp->rq_res.tail[0].iov_base = p; |
| 773 | *p++ = 0; /* no more entries */ | 768 | *p++ = 0; /* no more entries */ |
| 774 | *p++ = htonl(resp->common.err == nfserr_eof); | 769 | *p++ = htonl(resp->common.err == nfserr_eof); |
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 5be00436b5b8..9f30c53ac0ed 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c | |||
| @@ -2039,7 +2039,8 @@ nfsd4_encode_open_downgrade(struct nfsd4_compoundres *resp, int nfserr, struct n | |||
| 2039 | } | 2039 | } |
| 2040 | 2040 | ||
| 2041 | static int | 2041 | static int |
| 2042 | nfsd4_encode_read(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_read *read) | 2042 | nfsd4_encode_read(struct nfsd4_compoundres *resp, int nfserr, |
| 2043 | struct nfsd4_read *read) | ||
| 2043 | { | 2044 | { |
| 2044 | u32 eof; | 2045 | u32 eof; |
| 2045 | int v, pn; | 2046 | int v, pn; |
| @@ -2061,10 +2062,11 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_read | |||
| 2061 | len = maxcount; | 2062 | len = maxcount; |
| 2062 | v = 0; | 2063 | v = 0; |
| 2063 | while (len > 0) { | 2064 | while (len > 0) { |
| 2064 | pn = resp->rqstp->rq_resused; | 2065 | pn = resp->rqstp->rq_resused++; |
| 2065 | svc_take_page(resp->rqstp); | 2066 | read->rd_iov[v].iov_base = |
| 2066 | read->rd_iov[v].iov_base = page_address(resp->rqstp->rq_respages[pn]); | 2067 | page_address(resp->rqstp->rq_respages[pn]); |
| 2067 | read->rd_iov[v].iov_len = len < PAGE_SIZE ? len : PAGE_SIZE; | 2068 | read->rd_iov[v].iov_len = |
| 2069 | len < PAGE_SIZE ? len : PAGE_SIZE; | ||
| 2068 | v++; | 2070 | v++; |
| 2069 | len -= PAGE_SIZE; | 2071 | len -= PAGE_SIZE; |
| 2070 | } | 2072 | } |
| @@ -2078,7 +2080,8 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_read | |||
| 2078 | nfserr = nfserr_inval; | 2080 | nfserr = nfserr_inval; |
| 2079 | if (nfserr) | 2081 | if (nfserr) |
| 2080 | return nfserr; | 2082 | return nfserr; |
| 2081 | eof = (read->rd_offset + maxcount >= read->rd_fhp->fh_dentry->d_inode->i_size); | 2083 | eof = (read->rd_offset + maxcount >= |
| 2084 | read->rd_fhp->fh_dentry->d_inode->i_size); | ||
| 2082 | 2085 | ||
| 2083 | WRITE32(eof); | 2086 | WRITE32(eof); |
| 2084 | WRITE32(maxcount); | 2087 | WRITE32(maxcount); |
| @@ -2088,7 +2091,6 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_read | |||
| 2088 | resp->xbuf->page_len = maxcount; | 2091 | resp->xbuf->page_len = maxcount; |
| 2089 | 2092 | ||
| 2090 | /* Use rest of head for padding and remaining ops: */ | 2093 | /* Use rest of head for padding and remaining ops: */ |
| 2091 | resp->rqstp->rq_restailpage = 0; | ||
| 2092 | resp->xbuf->tail[0].iov_base = p; | 2094 | resp->xbuf->tail[0].iov_base = p; |
| 2093 | resp->xbuf->tail[0].iov_len = 0; | 2095 | resp->xbuf->tail[0].iov_len = 0; |
| 2094 | if (maxcount&3) { | 2096 | if (maxcount&3) { |
| @@ -2113,8 +2115,7 @@ nfsd4_encode_readlink(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_r | |||
| 2113 | if (resp->xbuf->page_len) | 2115 | if (resp->xbuf->page_len) |
| 2114 | return nfserr_resource; | 2116 | return nfserr_resource; |
| 2115 | 2117 | ||
| 2116 | svc_take_page(resp->rqstp); | 2118 | page = page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused++]); |
| 2117 | page = page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused-1]); | ||
| 2118 | 2119 | ||
| 2119 | maxcount = PAGE_SIZE; | 2120 | maxcount = PAGE_SIZE; |
| 2120 | RESERVE_SPACE(4); | 2121 | RESERVE_SPACE(4); |
| @@ -2138,7 +2139,6 @@ nfsd4_encode_readlink(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_r | |||
| 2138 | resp->xbuf->page_len = maxcount; | 2139 | resp->xbuf->page_len = maxcount; |
| 2139 | 2140 | ||
| 2140 | /* Use rest of head for padding and remaining ops: */ | 2141 | /* Use rest of head for padding and remaining ops: */ |
| 2141 | resp->rqstp->rq_restailpage = 0; | ||
| 2142 | resp->xbuf->tail[0].iov_base = p; | 2142 | resp->xbuf->tail[0].iov_base = p; |
| 2143 | resp->xbuf->tail[0].iov_len = 0; | 2143 | resp->xbuf->tail[0].iov_len = 0; |
| 2144 | if (maxcount&3) { | 2144 | if (maxcount&3) { |
| @@ -2189,8 +2189,7 @@ nfsd4_encode_readdir(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_re | |||
| 2189 | goto err_no_verf; | 2189 | goto err_no_verf; |
| 2190 | } | 2190 | } |
| 2191 | 2191 | ||
| 2192 | svc_take_page(resp->rqstp); | 2192 | page = page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused++]); |
| 2193 | page = page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused-1]); | ||
| 2194 | readdir->common.err = 0; | 2193 | readdir->common.err = 0; |
| 2195 | readdir->buflen = maxcount; | 2194 | readdir->buflen = maxcount; |
| 2196 | readdir->buffer = page; | 2195 | readdir->buffer = page; |
| @@ -2215,10 +2214,10 @@ nfsd4_encode_readdir(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_re | |||
| 2215 | p = readdir->buffer; | 2214 | p = readdir->buffer; |
| 2216 | *p++ = 0; /* no more entries */ | 2215 | *p++ = 0; /* no more entries */ |
| 2217 | *p++ = htonl(readdir->common.err == nfserr_eof); | 2216 | *p++ = htonl(readdir->common.err == nfserr_eof); |
| 2218 | resp->xbuf->page_len = ((char*)p) - (char*)page_address(resp->rqstp->rq_respages[resp->rqstp->rq_resused-1]); | 2217 | resp->xbuf->page_len = ((char*)p) - (char*)page_address( |
| 2218 | resp->rqstp->rq_respages[resp->rqstp->rq_resused-1]); | ||
| 2219 | 2219 | ||
| 2220 | /* Use rest of head for padding and remaining ops: */ | 2220 | /* Use rest of head for padding and remaining ops: */ |
| 2221 | resp->rqstp->rq_restailpage = 0; | ||
| 2222 | resp->xbuf->tail[0].iov_base = tailbase; | 2221 | resp->xbuf->tail[0].iov_base = tailbase; |
| 2223 | resp->xbuf->tail[0].iov_len = 0; | 2222 | resp->xbuf->tail[0].iov_len = 0; |
| 2224 | resp->p = resp->xbuf->tail[0].iov_base; | 2223 | resp->p = resp->xbuf->tail[0].iov_base; |
diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c index 3f14a17eaa6e..ad2fba3c54f8 100644 --- a/fs/nfsd/nfsxdr.c +++ b/fs/nfsd/nfsxdr.c | |||
| @@ -262,8 +262,7 @@ nfssvc_decode_readargs(struct svc_rqst *rqstp, u32 *p, | |||
| 262 | */ | 262 | */ |
| 263 | v=0; | 263 | v=0; |
| 264 | while (len > 0) { | 264 | while (len > 0) { |
| 265 | pn=rqstp->rq_resused; | 265 | pn = rqstp->rq_resused++; |
| 266 | svc_take_page(rqstp); | ||
| 267 | args->vec[v].iov_base = page_address(rqstp->rq_respages[pn]); | 266 | args->vec[v].iov_base = page_address(rqstp->rq_respages[pn]); |
| 268 | args->vec[v].iov_len = len < PAGE_SIZE?len:PAGE_SIZE; | 267 | args->vec[v].iov_len = len < PAGE_SIZE?len:PAGE_SIZE; |
| 269 | len -= args->vec[v].iov_len; | 268 | len -= args->vec[v].iov_len; |
| @@ -295,7 +294,7 @@ nfssvc_decode_writeargs(struct svc_rqst *rqstp, u32 *p, | |||
| 295 | while (len > args->vec[v].iov_len) { | 294 | while (len > args->vec[v].iov_len) { |
| 296 | len -= args->vec[v].iov_len; | 295 | len -= args->vec[v].iov_len; |
| 297 | v++; | 296 | v++; |
| 298 | args->vec[v].iov_base = page_address(rqstp->rq_argpages[v]); | 297 | args->vec[v].iov_base = page_address(rqstp->rq_pages[v]); |
| 299 | args->vec[v].iov_len = PAGE_SIZE; | 298 | args->vec[v].iov_len = PAGE_SIZE; |
| 300 | } | 299 | } |
| 301 | args->vec[v].iov_len = len; | 300 | args->vec[v].iov_len = len; |
| @@ -333,8 +332,7 @@ nfssvc_decode_readlinkargs(struct svc_rqst *rqstp, u32 *p, struct nfsd_readlinka | |||
| 333 | { | 332 | { |
| 334 | if (!(p = decode_fh(p, &args->fh))) | 333 | if (!(p = decode_fh(p, &args->fh))) |
| 335 | return 0; | 334 | return 0; |
| 336 | svc_take_page(rqstp); | 335 | args->buffer = page_address(rqstp->rq_respages[rqstp->rq_resused++]); |
| 337 | args->buffer = page_address(rqstp->rq_respages[rqstp->rq_resused-1]); | ||
| 338 | 336 | ||
| 339 | return xdr_argsize_check(rqstp, p); | 337 | return xdr_argsize_check(rqstp, p); |
| 340 | } | 338 | } |
| @@ -375,8 +373,7 @@ nfssvc_decode_readdirargs(struct svc_rqst *rqstp, u32 *p, | |||
| 375 | if (args->count > PAGE_SIZE) | 373 | if (args->count > PAGE_SIZE) |
| 376 | args->count = PAGE_SIZE; | 374 | args->count = PAGE_SIZE; |
| 377 | 375 | ||
| 378 | svc_take_page(rqstp); | 376 | args->buffer = page_address(rqstp->rq_respages[rqstp->rq_resused++]); |
| 379 | args->buffer = page_address(rqstp->rq_respages[rqstp->rq_resused-1]); | ||
| 380 | 377 | ||
| 381 | return xdr_argsize_check(rqstp, p); | 378 | return xdr_argsize_check(rqstp, p); |
| 382 | } | 379 | } |
| @@ -416,7 +413,6 @@ nfssvc_encode_readlinkres(struct svc_rqst *rqstp, u32 *p, | |||
| 416 | rqstp->rq_res.page_len = resp->len; | 413 | rqstp->rq_res.page_len = resp->len; |
| 417 | if (resp->len & 3) { | 414 | if (resp->len & 3) { |
| 418 | /* need to pad the tail */ | 415 | /* need to pad the tail */ |
| 419 | rqstp->rq_restailpage = 0; | ||
| 420 | rqstp->rq_res.tail[0].iov_base = p; | 416 | rqstp->rq_res.tail[0].iov_base = p; |
| 421 | *p = 0; | 417 | *p = 0; |
| 422 | rqstp->rq_res.tail[0].iov_len = 4 - (resp->len&3); | 418 | rqstp->rq_res.tail[0].iov_len = 4 - (resp->len&3); |
| @@ -436,7 +432,6 @@ nfssvc_encode_readres(struct svc_rqst *rqstp, u32 *p, | |||
| 436 | rqstp->rq_res.page_len = resp->count; | 432 | rqstp->rq_res.page_len = resp->count; |
| 437 | if (resp->count & 3) { | 433 | if (resp->count & 3) { |
| 438 | /* need to pad the tail */ | 434 | /* need to pad the tail */ |
| 439 | rqstp->rq_restailpage = 0; | ||
| 440 | rqstp->rq_res.tail[0].iov_base = p; | 435 | rqstp->rq_res.tail[0].iov_base = p; |
| 441 | *p = 0; | 436 | *p = 0; |
| 442 | rqstp->rq_res.tail[0].iov_len = 4 - (resp->count&3); | 437 | rqstp->rq_res.tail[0].iov_len = 4 - (resp->count&3); |
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 443ebc52e382..bfd36e587ec5 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
| @@ -791,22 +791,26 @@ nfsd_read_actor(read_descriptor_t *desc, struct page *page, unsigned long offset | |||
| 791 | { | 791 | { |
| 792 | unsigned long count = desc->count; | 792 | unsigned long count = desc->count; |
| 793 | struct svc_rqst *rqstp = desc->arg.data; | 793 | struct svc_rqst *rqstp = desc->arg.data; |
| 794 | struct page **pp = rqstp->rq_respages + rqstp->rq_resused; | ||
| 794 | 795 | ||
| 795 | if (size > count) | 796 | if (size > count) |
| 796 | size = count; | 797 | size = count; |
| 797 | 798 | ||
| 798 | if (rqstp->rq_res.page_len == 0) { | 799 | if (rqstp->rq_res.page_len == 0) { |
| 799 | get_page(page); | 800 | get_page(page); |
| 800 | rqstp->rq_respages[rqstp->rq_resused++] = page; | 801 | put_page(*pp); |
| 802 | *pp = page; | ||
| 803 | rqstp->rq_resused++; | ||
| 801 | rqstp->rq_res.page_base = offset; | 804 | rqstp->rq_res.page_base = offset; |
| 802 | rqstp->rq_res.page_len = size; | 805 | rqstp->rq_res.page_len = size; |
| 803 | } else if (page != rqstp->rq_respages[rqstp->rq_resused-1]) { | 806 | } else if (page != pp[-1]) { |
| 804 | get_page(page); | 807 | get_page(page); |
| 805 | rqstp->rq_respages[rqstp->rq_resused++] = page; | 808 | put_page(*pp); |
| 809 | *pp = page; | ||
| 810 | rqstp->rq_resused++; | ||
| 806 | rqstp->rq_res.page_len += size; | 811 | rqstp->rq_res.page_len += size; |
| 807 | } else { | 812 | } else |
| 808 | rqstp->rq_res.page_len += size; | 813 | rqstp->rq_res.page_len += size; |
| 809 | } | ||
| 810 | 814 | ||
| 811 | desc->count = count - size; | 815 | desc->count = count - size; |
| 812 | desc->written += size; | 816 | desc->written += size; |
| @@ -837,7 +841,7 @@ nfsd_vfs_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, | |||
| 837 | file->f_ra = ra->p_ra; | 841 | file->f_ra = ra->p_ra; |
| 838 | 842 | ||
| 839 | if (file->f_op->sendfile && rqstp->rq_sendfile_ok) { | 843 | if (file->f_op->sendfile && rqstp->rq_sendfile_ok) { |
| 840 | svc_pushback_unused_pages(rqstp); | 844 | rqstp->rq_resused = 1; |
| 841 | err = file->f_op->sendfile(file, &offset, *count, | 845 | err = file->f_op->sendfile(file, &offset, *count, |
| 842 | nfsd_read_actor, rqstp); | 846 | nfsd_read_actor, rqstp); |
| 843 | } else { | 847 | } else { |
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h index 4ebcdf91f3b3..3669e91c43b8 100644 --- a/include/linux/sunrpc/svc.h +++ b/include/linux/sunrpc/svc.h | |||
| @@ -170,7 +170,6 @@ static inline void svc_putu32(struct kvec *iov, __be32 val) | |||
| 170 | /* | 170 | /* |
| 171 | * The context of a single thread, including the request currently being | 171 | * The context of a single thread, including the request currently being |
| 172 | * processed. | 172 | * processed. |
| 173 | * NOTE: First two items must be prev/next. | ||
| 174 | */ | 173 | */ |
| 175 | struct svc_rqst { | 174 | struct svc_rqst { |
| 176 | struct list_head rq_list; /* idle list */ | 175 | struct list_head rq_list; /* idle list */ |
| @@ -189,12 +188,9 @@ struct svc_rqst { | |||
| 189 | 188 | ||
| 190 | struct xdr_buf rq_arg; | 189 | struct xdr_buf rq_arg; |
| 191 | struct xdr_buf rq_res; | 190 | struct xdr_buf rq_res; |
| 192 | struct page * rq_argpages[RPCSVC_MAXPAGES]; | 191 | struct page * rq_pages[RPCSVC_MAXPAGES]; |
| 193 | struct page * rq_respages[RPCSVC_MAXPAGES]; | 192 | struct page * *rq_respages; /* points into rq_pages */ |
| 194 | int rq_restailpage; | 193 | int rq_resused; /* number of pages used for result */ |
| 195 | short rq_argused; /* pages used for argument */ | ||
| 196 | short rq_arghi; /* pages available in argument page list */ | ||
| 197 | short rq_resused; /* pages used for result */ | ||
| 198 | 194 | ||
| 199 | __be32 rq_xid; /* transmission id */ | 195 | __be32 rq_xid; /* transmission id */ |
| 200 | u32 rq_prog; /* program number */ | 196 | u32 rq_prog; /* program number */ |
| @@ -255,63 +251,18 @@ xdr_ressize_check(struct svc_rqst *rqstp, __be32 *p) | |||
| 255 | return vec->iov_len <= PAGE_SIZE; | 251 | return vec->iov_len <= PAGE_SIZE; |
| 256 | } | 252 | } |
| 257 | 253 | ||
| 258 | static inline struct page * | 254 | static inline void svc_free_res_pages(struct svc_rqst *rqstp) |
| 259 | svc_take_res_page(struct svc_rqst *rqstp) | ||
| 260 | { | 255 | { |
| 261 | if (rqstp->rq_arghi <= rqstp->rq_argused) | 256 | while (rqstp->rq_resused) { |
| 262 | return NULL; | 257 | struct page **pp = (rqstp->rq_respages + |
| 263 | rqstp->rq_arghi--; | 258 | --rqstp->rq_resused); |
| 264 | rqstp->rq_respages[rqstp->rq_resused] = | 259 | if (*pp) { |
| 265 | rqstp->rq_argpages[rqstp->rq_arghi]; | 260 | put_page(*pp); |
| 266 | return rqstp->rq_respages[rqstp->rq_resused++]; | 261 | *pp = NULL; |
| 267 | } | ||
| 268 | |||
| 269 | static inline void svc_take_page(struct svc_rqst *rqstp) | ||
| 270 | { | ||
| 271 | if (rqstp->rq_arghi <= rqstp->rq_argused) { | ||
| 272 | WARN_ON(1); | ||
| 273 | return; | ||
| 274 | } | ||
| 275 | rqstp->rq_arghi--; | ||
| 276 | rqstp->rq_respages[rqstp->rq_resused] = | ||
| 277 | rqstp->rq_argpages[rqstp->rq_arghi]; | ||
| 278 | rqstp->rq_resused++; | ||
| 279 | } | ||
| 280 | |||
| 281 | static inline void svc_pushback_allpages(struct svc_rqst *rqstp) | ||
| 282 | { | ||
| 283 | while (rqstp->rq_resused) { | ||
| 284 | if (rqstp->rq_respages[--rqstp->rq_resused] == NULL) | ||
| 285 | continue; | ||
| 286 | rqstp->rq_argpages[rqstp->rq_arghi++] = | ||
| 287 | rqstp->rq_respages[rqstp->rq_resused]; | ||
| 288 | rqstp->rq_respages[rqstp->rq_resused] = NULL; | ||
| 289 | } | ||
| 290 | } | ||
| 291 | |||
| 292 | static inline void svc_pushback_unused_pages(struct svc_rqst *rqstp) | ||
| 293 | { | ||
| 294 | while (rqstp->rq_resused && | ||
| 295 | rqstp->rq_res.pages != &rqstp->rq_respages[rqstp->rq_resused]) { | ||
| 296 | |||
| 297 | if (rqstp->rq_respages[--rqstp->rq_resused] != NULL) { | ||
| 298 | rqstp->rq_argpages[rqstp->rq_arghi++] = | ||
| 299 | rqstp->rq_respages[rqstp->rq_resused]; | ||
| 300 | rqstp->rq_respages[rqstp->rq_resused] = NULL; | ||
| 301 | } | 262 | } |
| 302 | } | 263 | } |
| 303 | } | 264 | } |
| 304 | 265 | ||
| 305 | static inline void svc_free_allpages(struct svc_rqst *rqstp) | ||
| 306 | { | ||
| 307 | while (rqstp->rq_resused) { | ||
| 308 | if (rqstp->rq_respages[--rqstp->rq_resused] == NULL) | ||
| 309 | continue; | ||
| 310 | put_page(rqstp->rq_respages[rqstp->rq_resused]); | ||
| 311 | rqstp->rq_respages[rqstp->rq_resused] = NULL; | ||
| 312 | } | ||
| 313 | } | ||
| 314 | |||
| 315 | struct svc_deferred_req { | 266 | struct svc_deferred_req { |
| 316 | u32 prot; /* protocol (UDP or TCP) */ | 267 | u32 prot; /* protocol (UDP or TCP) */ |
| 317 | struct sockaddr_in addr; | 268 | struct sockaddr_in addr; |
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c index 638c0b576203..558692d7e465 100644 --- a/net/sunrpc/auth_gss/svcauth_gss.c +++ b/net/sunrpc/auth_gss/svcauth_gss.c | |||
| @@ -1191,7 +1191,6 @@ svcauth_gss_wrap_resp_integ(struct svc_rqst *rqstp) | |||
| 1191 | resbuf->tail[0].iov_base = resbuf->head[0].iov_base | 1191 | resbuf->tail[0].iov_base = resbuf->head[0].iov_base |
| 1192 | + resbuf->head[0].iov_len; | 1192 | + resbuf->head[0].iov_len; |
| 1193 | resbuf->tail[0].iov_len = 0; | 1193 | resbuf->tail[0].iov_len = 0; |
| 1194 | rqstp->rq_restailpage = 0; | ||
| 1195 | resv = &resbuf->tail[0]; | 1194 | resv = &resbuf->tail[0]; |
| 1196 | } else { | 1195 | } else { |
| 1197 | resv = &resbuf->tail[0]; | 1196 | resv = &resbuf->tail[0]; |
| @@ -1240,7 +1239,7 @@ svcauth_gss_wrap_resp_priv(struct svc_rqst *rqstp) | |||
| 1240 | inpages = resbuf->pages; | 1239 | inpages = resbuf->pages; |
| 1241 | /* XXX: Would be better to write some xdr helper functions for | 1240 | /* XXX: Would be better to write some xdr helper functions for |
| 1242 | * nfs{2,3,4}xdr.c that place the data right, instead of copying: */ | 1241 | * nfs{2,3,4}xdr.c that place the data right, instead of copying: */ |
| 1243 | if (resbuf->tail[0].iov_base && rqstp->rq_restailpage == 0) { | 1242 | if (resbuf->tail[0].iov_base) { |
| 1244 | BUG_ON(resbuf->tail[0].iov_base >= resbuf->head[0].iov_base | 1243 | BUG_ON(resbuf->tail[0].iov_base >= resbuf->head[0].iov_base |
| 1245 | + PAGE_SIZE); | 1244 | + PAGE_SIZE); |
| 1246 | BUG_ON(resbuf->tail[0].iov_base < resbuf->head[0].iov_base); | 1245 | BUG_ON(resbuf->tail[0].iov_base < resbuf->head[0].iov_base); |
| @@ -1258,7 +1257,6 @@ svcauth_gss_wrap_resp_priv(struct svc_rqst *rqstp) | |||
| 1258 | resbuf->tail[0].iov_base = resbuf->head[0].iov_base | 1257 | resbuf->tail[0].iov_base = resbuf->head[0].iov_base |
| 1259 | + resbuf->head[0].iov_len + RPC_MAX_AUTH_SIZE; | 1258 | + resbuf->head[0].iov_len + RPC_MAX_AUTH_SIZE; |
| 1260 | resbuf->tail[0].iov_len = 0; | 1259 | resbuf->tail[0].iov_len = 0; |
| 1261 | rqstp->rq_restailpage = 0; | ||
| 1262 | } | 1260 | } |
| 1263 | if (gss_wrap(gsd->rsci->mechctx, offset, resbuf, inpages)) | 1261 | if (gss_wrap(gsd->rsci->mechctx, offset, resbuf, inpages)) |
| 1264 | return -ENOMEM; | 1262 | return -ENOMEM; |
diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c index a99e67b164c1..f4a509a925b5 100644 --- a/net/sunrpc/svc.c +++ b/net/sunrpc/svc.c | |||
| @@ -417,18 +417,15 @@ svc_init_buffer(struct svc_rqst *rqstp, unsigned int size) | |||
| 417 | if (size > RPCSVC_MAXPAYLOAD) | 417 | if (size > RPCSVC_MAXPAYLOAD) |
| 418 | size = RPCSVC_MAXPAYLOAD; | 418 | size = RPCSVC_MAXPAYLOAD; |
| 419 | pages = 2 + (size+ PAGE_SIZE -1) / PAGE_SIZE; | 419 | pages = 2 + (size+ PAGE_SIZE -1) / PAGE_SIZE; |
| 420 | rqstp->rq_argused = 0; | ||
| 421 | rqstp->rq_resused = 0; | ||
| 422 | arghi = 0; | 420 | arghi = 0; |
| 423 | BUG_ON(pages > RPCSVC_MAXPAGES); | 421 | BUG_ON(pages > RPCSVC_MAXPAGES); |
| 424 | while (pages) { | 422 | while (pages) { |
| 425 | struct page *p = alloc_page(GFP_KERNEL); | 423 | struct page *p = alloc_page(GFP_KERNEL); |
| 426 | if (!p) | 424 | if (!p) |
| 427 | break; | 425 | break; |
| 428 | rqstp->rq_argpages[arghi++] = p; | 426 | rqstp->rq_pages[arghi++] = p; |
| 429 | pages--; | 427 | pages--; |
| 430 | } | 428 | } |
| 431 | rqstp->rq_arghi = arghi; | ||
| 432 | return ! pages; | 429 | return ! pages; |
| 433 | } | 430 | } |
| 434 | 431 | ||
| @@ -438,14 +435,10 @@ svc_init_buffer(struct svc_rqst *rqstp, unsigned int size) | |||
| 438 | static void | 435 | static void |
| 439 | svc_release_buffer(struct svc_rqst *rqstp) | 436 | svc_release_buffer(struct svc_rqst *rqstp) |
| 440 | { | 437 | { |
| 441 | while (rqstp->rq_arghi) | 438 | int i; |
| 442 | put_page(rqstp->rq_argpages[--rqstp->rq_arghi]); | 439 | for (i=0; i<ARRAY_SIZE(rqstp->rq_pages); i++) |
| 443 | while (rqstp->rq_resused) { | 440 | if (rqstp->rq_pages[i]) |
| 444 | if (rqstp->rq_respages[--rqstp->rq_resused] == NULL) | 441 | put_page(rqstp->rq_pages[i]); |
| 445 | continue; | ||
| 446 | put_page(rqstp->rq_respages[rqstp->rq_resused]); | ||
| 447 | } | ||
| 448 | rqstp->rq_argused = 0; | ||
| 449 | } | 442 | } |
| 450 | 443 | ||
| 451 | /* | 444 | /* |
| @@ -707,10 +700,10 @@ svc_process(struct svc_rqst *rqstp) | |||
| 707 | /* setup response xdr_buf. | 700 | /* setup response xdr_buf. |
| 708 | * Initially it has just one page | 701 | * Initially it has just one page |
| 709 | */ | 702 | */ |
| 710 | svc_take_page(rqstp); /* must succeed */ | 703 | rqstp->rq_resused = 1; |
| 711 | resv->iov_base = page_address(rqstp->rq_respages[0]); | 704 | resv->iov_base = page_address(rqstp->rq_respages[0]); |
| 712 | resv->iov_len = 0; | 705 | resv->iov_len = 0; |
| 713 | rqstp->rq_res.pages = rqstp->rq_respages+1; | 706 | rqstp->rq_res.pages = rqstp->rq_respages + 1; |
| 714 | rqstp->rq_res.len = 0; | 707 | rqstp->rq_res.len = 0; |
| 715 | rqstp->rq_res.page_base = 0; | 708 | rqstp->rq_res.page_base = 0; |
| 716 | rqstp->rq_res.page_len = 0; | 709 | rqstp->rq_res.page_len = 0; |
diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index 4de8626e4f54..25096d53667a 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c | |||
| @@ -313,7 +313,7 @@ svc_sock_release(struct svc_rqst *rqstp) | |||
| 313 | 313 | ||
| 314 | svc_release_skb(rqstp); | 314 | svc_release_skb(rqstp); |
| 315 | 315 | ||
| 316 | svc_free_allpages(rqstp); | 316 | svc_free_res_pages(rqstp); |
| 317 | rqstp->rq_res.page_len = 0; | 317 | rqstp->rq_res.page_len = 0; |
| 318 | rqstp->rq_res.page_base = 0; | 318 | rqstp->rq_res.page_base = 0; |
| 319 | 319 | ||
| @@ -412,7 +412,8 @@ svc_sendto(struct svc_rqst *rqstp, struct xdr_buf *xdr) | |||
| 412 | /* send head */ | 412 | /* send head */ |
| 413 | if (slen == xdr->head[0].iov_len) | 413 | if (slen == xdr->head[0].iov_len) |
| 414 | flags = 0; | 414 | flags = 0; |
| 415 | len = kernel_sendpage(sock, rqstp->rq_respages[0], 0, xdr->head[0].iov_len, flags); | 415 | len = kernel_sendpage(sock, rqstp->rq_respages[0], 0, |
| 416 | xdr->head[0].iov_len, flags); | ||
| 416 | if (len != xdr->head[0].iov_len) | 417 | if (len != xdr->head[0].iov_len) |
| 417 | goto out; | 418 | goto out; |
| 418 | slen -= xdr->head[0].iov_len; | 419 | slen -= xdr->head[0].iov_len; |
| @@ -437,8 +438,9 @@ svc_sendto(struct svc_rqst *rqstp, struct xdr_buf *xdr) | |||
| 437 | } | 438 | } |
| 438 | /* send tail */ | 439 | /* send tail */ |
| 439 | if (xdr->tail[0].iov_len) { | 440 | if (xdr->tail[0].iov_len) { |
| 440 | result = kernel_sendpage(sock, rqstp->rq_respages[rqstp->rq_restailpage], | 441 | result = kernel_sendpage(sock, rqstp->rq_respages[0], |
| 441 | ((unsigned long)xdr->tail[0].iov_base)& (PAGE_SIZE-1), | 442 | ((unsigned long)xdr->tail[0].iov_base) |
| 443 | & (PAGE_SIZE-1), | ||
| 442 | xdr->tail[0].iov_len, 0); | 444 | xdr->tail[0].iov_len, 0); |
| 443 | 445 | ||
| 444 | if (result > 0) | 446 | if (result > 0) |
| @@ -708,9 +710,11 @@ svc_udp_recvfrom(struct svc_rqst *rqstp) | |||
| 708 | if (len <= rqstp->rq_arg.head[0].iov_len) { | 710 | if (len <= rqstp->rq_arg.head[0].iov_len) { |
| 709 | rqstp->rq_arg.head[0].iov_len = len; | 711 | rqstp->rq_arg.head[0].iov_len = len; |
| 710 | rqstp->rq_arg.page_len = 0; | 712 | rqstp->rq_arg.page_len = 0; |
| 713 | rqstp->rq_respages = rqstp->rq_pages+1; | ||
| 711 | } else { | 714 | } else { |
| 712 | rqstp->rq_arg.page_len = len - rqstp->rq_arg.head[0].iov_len; | 715 | rqstp->rq_arg.page_len = len - rqstp->rq_arg.head[0].iov_len; |
| 713 | rqstp->rq_argused += (rqstp->rq_arg.page_len + PAGE_SIZE - 1)/ PAGE_SIZE; | 716 | rqstp->rq_respages = rqstp->rq_pages + 1 + |
| 717 | (rqstp->rq_arg.page_len + PAGE_SIZE - 1)/ PAGE_SIZE; | ||
| 714 | } | 718 | } |
| 715 | 719 | ||
| 716 | if (serv->sv_stats) | 720 | if (serv->sv_stats) |
| @@ -1053,11 +1057,12 @@ svc_tcp_recvfrom(struct svc_rqst *rqstp) | |||
| 1053 | vlen = PAGE_SIZE; | 1057 | vlen = PAGE_SIZE; |
| 1054 | pnum = 1; | 1058 | pnum = 1; |
| 1055 | while (vlen < len) { | 1059 | while (vlen < len) { |
| 1056 | vec[pnum].iov_base = page_address(rqstp->rq_argpages[rqstp->rq_argused++]); | 1060 | vec[pnum].iov_base = page_address(rqstp->rq_pages[pnum]); |
| 1057 | vec[pnum].iov_len = PAGE_SIZE; | 1061 | vec[pnum].iov_len = PAGE_SIZE; |
| 1058 | pnum++; | 1062 | pnum++; |
| 1059 | vlen += PAGE_SIZE; | 1063 | vlen += PAGE_SIZE; |
| 1060 | } | 1064 | } |
| 1065 | rqstp->rq_respages = &rqstp->rq_pages[pnum]; | ||
| 1061 | 1066 | ||
| 1062 | /* Now receive data */ | 1067 | /* Now receive data */ |
| 1063 | len = svc_recvfrom(rqstp, vec, pnum, len); | 1068 | len = svc_recvfrom(rqstp, vec, pnum, len); |
| @@ -1209,7 +1214,7 @@ svc_recv(struct svc_rqst *rqstp, long timeout) | |||
| 1209 | struct svc_sock *svsk =NULL; | 1214 | struct svc_sock *svsk =NULL; |
| 1210 | struct svc_serv *serv = rqstp->rq_server; | 1215 | struct svc_serv *serv = rqstp->rq_server; |
| 1211 | struct svc_pool *pool = rqstp->rq_pool; | 1216 | struct svc_pool *pool = rqstp->rq_pool; |
| 1212 | int len; | 1217 | int len, i; |
| 1213 | int pages; | 1218 | int pages; |
| 1214 | struct xdr_buf *arg; | 1219 | struct xdr_buf *arg; |
| 1215 | DECLARE_WAITQUEUE(wait, current); | 1220 | DECLARE_WAITQUEUE(wait, current); |
| @@ -1226,27 +1231,22 @@ svc_recv(struct svc_rqst *rqstp, long timeout) | |||
| 1226 | "svc_recv: service %p, wait queue active!\n", | 1231 | "svc_recv: service %p, wait queue active!\n", |
| 1227 | rqstp); | 1232 | rqstp); |
| 1228 | 1233 | ||
| 1229 | /* Initialize the buffers */ | ||
| 1230 | /* first reclaim pages that were moved to response list */ | ||
| 1231 | svc_pushback_allpages(rqstp); | ||
| 1232 | 1234 | ||
| 1233 | /* now allocate needed pages. If we get a failure, sleep briefly */ | 1235 | /* now allocate needed pages. If we get a failure, sleep briefly */ |
| 1234 | pages = 2 + (serv->sv_bufsz + PAGE_SIZE -1) / PAGE_SIZE; | 1236 | pages = 2 + (serv->sv_bufsz + PAGE_SIZE -1) / PAGE_SIZE; |
| 1235 | while (rqstp->rq_arghi < pages) { | 1237 | for (i=0; i < pages ; i++) |
| 1236 | struct page *p = alloc_page(GFP_KERNEL); | 1238 | while (rqstp->rq_pages[i] == NULL) { |
| 1237 | if (!p) { | 1239 | struct page *p = alloc_page(GFP_KERNEL); |
| 1238 | schedule_timeout_uninterruptible(msecs_to_jiffies(500)); | 1240 | if (!p) |
| 1239 | continue; | 1241 | schedule_timeout_uninterruptible(msecs_to_jiffies(500)); |
| 1242 | rqstp->rq_pages[i] = p; | ||
| 1240 | } | 1243 | } |
| 1241 | rqstp->rq_argpages[rqstp->rq_arghi++] = p; | ||
| 1242 | } | ||
| 1243 | 1244 | ||
| 1244 | /* Make arg->head point to first page and arg->pages point to rest */ | 1245 | /* Make arg->head point to first page and arg->pages point to rest */ |
| 1245 | arg = &rqstp->rq_arg; | 1246 | arg = &rqstp->rq_arg; |
| 1246 | arg->head[0].iov_base = page_address(rqstp->rq_argpages[0]); | 1247 | arg->head[0].iov_base = page_address(rqstp->rq_pages[0]); |
| 1247 | arg->head[0].iov_len = PAGE_SIZE; | 1248 | arg->head[0].iov_len = PAGE_SIZE; |
| 1248 | rqstp->rq_argused = 1; | 1249 | arg->pages = rqstp->rq_pages + 1; |
| 1249 | arg->pages = rqstp->rq_argpages + 1; | ||
| 1250 | arg->page_base = 0; | 1250 | arg->page_base = 0; |
| 1251 | /* save at least one page for response */ | 1251 | /* save at least one page for response */ |
| 1252 | arg->page_len = (pages-2)*PAGE_SIZE; | 1252 | arg->page_len = (pages-2)*PAGE_SIZE; |
| @@ -1704,6 +1704,7 @@ static int svc_deferred_recv(struct svc_rqst *rqstp) | |||
| 1704 | rqstp->rq_prot = dr->prot; | 1704 | rqstp->rq_prot = dr->prot; |
| 1705 | rqstp->rq_addr = dr->addr; | 1705 | rqstp->rq_addr = dr->addr; |
| 1706 | rqstp->rq_daddr = dr->daddr; | 1706 | rqstp->rq_daddr = dr->daddr; |
| 1707 | rqstp->rq_respages = rqstp->rq_pages; | ||
| 1707 | return dr->argslen<<2; | 1708 | return dr->argslen<<2; |
| 1708 | } | 1709 | } |
| 1709 | 1710 | ||
