diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/nfs/dir.c | 44 | ||||
-rw-r--r-- | fs/nfs/nfs2xdr.c | 6 | ||||
-rw-r--r-- | fs/nfs/nfs3xdr.c | 6 | ||||
-rw-r--r-- | fs/nfs/nfs4xdr.c | 6 |
4 files changed, 21 insertions, 41 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 996dd8989a91..0108cf4f3403 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 | 37 | ||
39 | #include "delegation.h" | 38 | #include "delegation.h" |
@@ -459,25 +458,26 @@ out: | |||
459 | /* Perform conversion from xdr to cache array */ | 458 | /* Perform conversion from xdr to cache array */ |
460 | static | 459 | static |
461 | int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *entry, | 460 | int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *entry, |
462 | void *xdr_page, struct page *page, unsigned int buflen) | 461 | struct page **xdr_pages, struct page *page, unsigned int buflen) |
463 | { | 462 | { |
464 | struct xdr_stream stream; | 463 | struct xdr_stream stream; |
465 | struct xdr_buf buf; | 464 | struct xdr_buf buf = { |
466 | __be32 *ptr = xdr_page; | 465 | .pages = xdr_pages, |
466 | .page_len = buflen, | ||
467 | .buflen = buflen, | ||
468 | .len = buflen, | ||
469 | }; | ||
470 | struct page *scratch; | ||
467 | struct nfs_cache_array *array; | 471 | struct nfs_cache_array *array; |
468 | unsigned int count = 0; | 472 | unsigned int count = 0; |
469 | int status; | 473 | int status; |
470 | 474 | ||
471 | buf.head->iov_base = xdr_page; | 475 | scratch = alloc_page(GFP_KERNEL); |
472 | buf.head->iov_len = buflen; | 476 | if (scratch == NULL) |
473 | buf.tail->iov_len = 0; | 477 | return -ENOMEM; |
474 | buf.page_base = 0; | ||
475 | buf.page_len = 0; | ||
476 | buf.buflen = buf.head->iov_len; | ||
477 | buf.len = buf.head->iov_len; | ||
478 | |||
479 | xdr_init_decode(&stream, &buf, ptr); | ||
480 | 478 | ||
479 | xdr_init_decode(&stream, &buf, NULL); | ||
480 | xdr_set_scratch_buffer(&stream, page_address(scratch), PAGE_SIZE); | ||
481 | 481 | ||
482 | do { | 482 | do { |
483 | status = xdr_decode(desc, entry, &stream); | 483 | status = xdr_decode(desc, entry, &stream); |
@@ -506,6 +506,8 @@ int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *en | |||
506 | } else | 506 | } else |
507 | status = PTR_ERR(array); | 507 | status = PTR_ERR(array); |
508 | } | 508 | } |
509 | |||
510 | put_page(scratch); | ||
509 | return status; | 511 | return status; |
510 | } | 512 | } |
511 | 513 | ||
@@ -521,7 +523,6 @@ static | |||
521 | void nfs_readdir_free_large_page(void *ptr, struct page **pages, | 523 | void nfs_readdir_free_large_page(void *ptr, struct page **pages, |
522 | unsigned int npages) | 524 | unsigned int npages) |
523 | { | 525 | { |
524 | vm_unmap_ram(ptr, npages); | ||
525 | nfs_readdir_free_pagearray(pages, npages); | 526 | nfs_readdir_free_pagearray(pages, npages); |
526 | } | 527 | } |
527 | 528 | ||
@@ -530,9 +531,8 @@ void nfs_readdir_free_large_page(void *ptr, struct page **pages, | |||
530 | * to nfs_readdir_free_large_page | 531 | * to nfs_readdir_free_large_page |
531 | */ | 532 | */ |
532 | static | 533 | static |
533 | void *nfs_readdir_large_page(struct page **pages, unsigned int npages) | 534 | int nfs_readdir_large_page(struct page **pages, unsigned int npages) |
534 | { | 535 | { |
535 | void *ptr; | ||
536 | unsigned int i; | 536 | unsigned int i; |
537 | 537 | ||
538 | for (i = 0; i < npages; i++) { | 538 | for (i = 0; i < npages; i++) { |
@@ -541,13 +541,11 @@ void *nfs_readdir_large_page(struct page **pages, unsigned int npages) | |||
541 | goto out_freepages; | 541 | goto out_freepages; |
542 | pages[i] = page; | 542 | pages[i] = page; |
543 | } | 543 | } |
544 | return 0; | ||
544 | 545 | ||
545 | ptr = vm_map_ram(pages, npages, 0, PAGE_KERNEL); | ||
546 | if (!IS_ERR_OR_NULL(ptr)) | ||
547 | return ptr; | ||
548 | out_freepages: | 546 | out_freepages: |
549 | nfs_readdir_free_pagearray(pages, i); | 547 | nfs_readdir_free_pagearray(pages, i); |
550 | return NULL; | 548 | return -ENOMEM; |
551 | } | 549 | } |
552 | 550 | ||
553 | static | 551 | static |
@@ -577,8 +575,8 @@ int nfs_readdir_xdr_to_array(nfs_readdir_descriptor_t *desc, struct page *page, | |||
577 | memset(array, 0, sizeof(struct nfs_cache_array)); | 575 | memset(array, 0, sizeof(struct nfs_cache_array)); |
578 | array->eof_index = -1; | 576 | array->eof_index = -1; |
579 | 577 | ||
580 | pages_ptr = nfs_readdir_large_page(pages, array_size); | 578 | status = nfs_readdir_large_page(pages, array_size); |
581 | if (!pages_ptr) | 579 | if (status < 0) |
582 | goto out_release_array; | 580 | goto out_release_array; |
583 | do { | 581 | do { |
584 | unsigned int pglen; | 582 | unsigned int pglen; |
@@ -587,7 +585,7 @@ int nfs_readdir_xdr_to_array(nfs_readdir_descriptor_t *desc, struct page *page, | |||
587 | if (status < 0) | 585 | if (status < 0) |
588 | break; | 586 | break; |
589 | pglen = status; | 587 | pglen = status; |
590 | status = nfs_readdir_page_filler(desc, &entry, pages_ptr, page, pglen); | 588 | status = nfs_readdir_page_filler(desc, &entry, pages, page, pglen); |
591 | if (status < 0) { | 589 | if (status < 0) { |
592 | if (status == -ENOSPC) | 590 | if (status == -ENOSPC) |
593 | status = 0; | 591 | status = 0; |
diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c index 5914a1911c95..b382a1b5e7e4 100644 --- a/fs/nfs/nfs2xdr.c +++ b/fs/nfs/nfs2xdr.c | |||
@@ -487,12 +487,6 @@ nfs_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, struct nfs_se | |||
487 | 487 | ||
488 | entry->d_type = DT_UNKNOWN; | 488 | entry->d_type = DT_UNKNOWN; |
489 | 489 | ||
490 | p = xdr_inline_peek(xdr, 8); | ||
491 | if (p != NULL) | ||
492 | entry->eof = !p[0] && p[1]; | ||
493 | else | ||
494 | entry->eof = 0; | ||
495 | |||
496 | return p; | 490 | return p; |
497 | 491 | ||
498 | out_overflow: | 492 | out_overflow: |
diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c index f6cc60f06dac..ba91236c6ee7 100644 --- a/fs/nfs/nfs3xdr.c +++ b/fs/nfs/nfs3xdr.c | |||
@@ -647,12 +647,6 @@ nfs3_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, struct nfs_s | |||
647 | memset((u8*)(entry->fh), 0, sizeof(*entry->fh)); | 647 | memset((u8*)(entry->fh), 0, sizeof(*entry->fh)); |
648 | } | 648 | } |
649 | 649 | ||
650 | p = xdr_inline_peek(xdr, 8); | ||
651 | if (p != NULL) | ||
652 | entry->eof = !p[0] && p[1]; | ||
653 | else | ||
654 | entry->eof = 0; | ||
655 | |||
656 | return p; | 650 | return p; |
657 | 651 | ||
658 | out_overflow: | 652 | out_overflow: |
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 9f1826b012e6..0662a9821df5 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c | |||
@@ -6215,12 +6215,6 @@ __be32 *nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, | |||
6215 | if (verify_attr_len(xdr, p, len) < 0) | 6215 | if (verify_attr_len(xdr, p, len) < 0) |
6216 | goto out_overflow; | 6216 | goto out_overflow; |
6217 | 6217 | ||
6218 | p = xdr_inline_peek(xdr, 8); | ||
6219 | if (p != NULL) | ||
6220 | entry->eof = !p[0] && p[1]; | ||
6221 | else | ||
6222 | entry->eof = 0; | ||
6223 | |||
6224 | return p; | 6218 | return p; |
6225 | 6219 | ||
6226 | out_overflow: | 6220 | out_overflow: |