aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2011-01-10 14:48:02 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2011-01-10 14:48:02 -0500
commit68c404b18f6fba404b2753622d0459c68ee128ae (patch)
treec1ec0bb12f19d91071b461cc2831d9d3dd4c74f3 /fs/nfs
parentd035c36c58dd9183ad6aa7875dea89893faedb55 (diff)
parent6650239a4b01077e80d5a4468562756d77afaa59 (diff)
Merge branch 'bugfixes' into nfs-for-2.6.38
Conflicts: fs/nfs/nfs2xdr.c fs/nfs/nfs3xdr.c fs/nfs/nfs4xdr.c
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/dir.c44
-rw-r--r--fs/nfs/nfs2xdr.c5
-rw-r--r--fs/nfs/nfs3xdr.c5
-rw-r--r--fs/nfs/nfs4xdr.c6
4 files changed, 21 insertions, 39 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 65d5cb4f70b1..16ec096f6b24 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -33,7 +33,6 @@
33#include <linux/namei.h> 33#include <linux/namei.h>
34#include <linux/mount.h> 34#include <linux/mount.h>
35#include <linux/sched.h> 35#include <linux/sched.h>
36#include <linux/vmalloc.h>
37#include <linux/kmemleak.h> 36#include <linux/kmemleak.h>
38#include <linux/xattr.h> 37#include <linux/xattr.h>
39 38
@@ -461,25 +460,26 @@ out:
461/* Perform conversion from xdr to cache array */ 460/* Perform conversion from xdr to cache array */
462static 461static
463int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *entry, 462int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *entry,
464 void *xdr_page, struct page *page, unsigned int buflen) 463 struct page **xdr_pages, struct page *page, unsigned int buflen)
465{ 464{
466 struct xdr_stream stream; 465 struct xdr_stream stream;
467 struct xdr_buf buf; 466 struct xdr_buf buf = {
468 __be32 *ptr = xdr_page; 467 .pages = xdr_pages,
468 .page_len = buflen,
469 .buflen = buflen,
470 .len = buflen,
471 };
472 struct page *scratch;
469 struct nfs_cache_array *array; 473 struct nfs_cache_array *array;
470 unsigned int count = 0; 474 unsigned int count = 0;
471 int status; 475 int status;
472 476
473 buf.head->iov_base = xdr_page; 477 scratch = alloc_page(GFP_KERNEL);
474 buf.head->iov_len = buflen; 478 if (scratch == NULL)
475 buf.tail->iov_len = 0; 479 return -ENOMEM;
476 buf.page_base = 0;
477 buf.page_len = 0;
478 buf.buflen = buf.head->iov_len;
479 buf.len = buf.head->iov_len;
480
481 xdr_init_decode(&stream, &buf, ptr);
482 480
481 xdr_init_decode(&stream, &buf, NULL);
482 xdr_set_scratch_buffer(&stream, page_address(scratch), PAGE_SIZE);
483 483
484 do { 484 do {
485 status = xdr_decode(desc, entry, &stream); 485 status = xdr_decode(desc, entry, &stream);
@@ -508,6 +508,8 @@ int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *en
508 } else 508 } else
509 status = PTR_ERR(array); 509 status = PTR_ERR(array);
510 } 510 }
511
512 put_page(scratch);
511 return status; 513 return status;
512} 514}
513 515
@@ -523,7 +525,6 @@ static
523void nfs_readdir_free_large_page(void *ptr, struct page **pages, 525void nfs_readdir_free_large_page(void *ptr, struct page **pages,
524 unsigned int npages) 526 unsigned int npages)
525{ 527{
526 vm_unmap_ram(ptr, npages);
527 nfs_readdir_free_pagearray(pages, npages); 528 nfs_readdir_free_pagearray(pages, npages);
528} 529}
529 530
@@ -532,9 +533,8 @@ void nfs_readdir_free_large_page(void *ptr, struct page **pages,
532 * to nfs_readdir_free_large_page 533 * to nfs_readdir_free_large_page
533 */ 534 */
534static 535static
535void *nfs_readdir_large_page(struct page **pages, unsigned int npages) 536int nfs_readdir_large_page(struct page **pages, unsigned int npages)
536{ 537{
537 void *ptr;
538 unsigned int i; 538 unsigned int i;
539 539
540 for (i = 0; i < npages; i++) { 540 for (i = 0; i < npages; i++) {
@@ -543,13 +543,11 @@ void *nfs_readdir_large_page(struct page **pages, unsigned int npages)
543 goto out_freepages; 543 goto out_freepages;
544 pages[i] = page; 544 pages[i] = page;
545 } 545 }
546 return 0;
546 547
547 ptr = vm_map_ram(pages, npages, 0, PAGE_KERNEL);
548 if (!IS_ERR_OR_NULL(ptr))
549 return ptr;
550out_freepages: 548out_freepages:
551 nfs_readdir_free_pagearray(pages, i); 549 nfs_readdir_free_pagearray(pages, i);
552 return NULL; 550 return -ENOMEM;
553} 551}
554 552
555static 553static
@@ -580,8 +578,8 @@ int nfs_readdir_xdr_to_array(nfs_readdir_descriptor_t *desc, struct page *page,
580 memset(array, 0, sizeof(struct nfs_cache_array)); 578 memset(array, 0, sizeof(struct nfs_cache_array));
581 array->eof_index = -1; 579 array->eof_index = -1;
582 580
583 pages_ptr = nfs_readdir_large_page(pages, array_size); 581 status = nfs_readdir_large_page(pages, array_size);
584 if (!pages_ptr) 582 if (status < 0)
585 goto out_release_array; 583 goto out_release_array;
586 do { 584 do {
587 unsigned int pglen; 585 unsigned int pglen;
@@ -590,7 +588,7 @@ int nfs_readdir_xdr_to_array(nfs_readdir_descriptor_t *desc, struct page *page,
590 if (status < 0) 588 if (status < 0)
591 break; 589 break;
592 pglen = status; 590 pglen = status;
593 status = nfs_readdir_page_filler(desc, &entry, pages_ptr, page, pglen); 591 status = nfs_readdir_page_filler(desc, &entry, pages, page, pglen);
594 if (status < 0) { 592 if (status < 0) {
595 if (status == -ENOSPC) 593 if (status == -ENOSPC)
596 status = 0; 594 status = 0;
diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
index 51f1cfa04d27..792cb13a4304 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -943,11 +943,6 @@ int nfs2_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry,
943 943
944 entry->d_type = DT_UNKNOWN; 944 entry->d_type = DT_UNKNOWN;
945 945
946 /* Peek at the next entry to see if we're at EOD */
947 p = xdr_inline_peek(xdr, 4 + 4);
948 entry->eof = 0;
949 if (p != NULL)
950 entry->eof = (p[0] == xdr_zero) && (p[1] != xdr_zero);
951 return 0; 946 return 0;
952 947
953out_overflow: 948out_overflow:
diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c
index df30a26cc4fa..01c5e8b1941d 100644
--- a/fs/nfs/nfs3xdr.c
+++ b/fs/nfs/nfs3xdr.c
@@ -1989,11 +1989,6 @@ int nfs3_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry,
1989 zero_nfs_fh3(entry->fh); 1989 zero_nfs_fh3(entry->fh);
1990 } 1990 }
1991 1991
1992 /* Peek at the next entry to see if we're at EOD */
1993 p = xdr_inline_peek(xdr, 4 + 4);
1994 entry->eof = 0;
1995 if (p != NULL)
1996 entry->eof = (p[0] == xdr_zero) && (p[1] != xdr_zero);
1997 return 0; 1992 return 0;
1998 1993
1999out_overflow: 1994out_overflow:
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 8e496887ec61..2ab8e5cb8f59 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -6135,12 +6135,6 @@ int nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry,
6135 if (verify_attr_len(xdr, p, len) < 0) 6135 if (verify_attr_len(xdr, p, len) < 0)
6136 goto out_overflow; 6136 goto out_overflow;
6137 6137
6138 p = xdr_inline_peek(xdr, 8);
6139 if (p != NULL)
6140 entry->eof = !p[0] && p[1];
6141 else
6142 entry->eof = 0;
6143
6144 return 0; 6138 return 0;
6145 6139
6146out_overflow: 6140out_overflow: