aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/nfsd/nfs2acl.c2
-rw-r--r--fs/nfsd/nfs3acl.c2
-rw-r--r--fs/nfsd/nfs3xdr.c23
-rw-r--r--fs/nfsd/nfs4xdr.c27
-rw-r--r--fs/nfsd/nfsxdr.c13
-rw-r--r--fs/nfsd/vfs.c16
6 files changed, 38 insertions, 45 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
2041static int 2041static int
2042nfsd4_encode_read(struct nfsd4_compoundres *resp, int nfserr, struct nfsd4_read *read) 2042nfsd4_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 {