diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/nfs/direct.c | 17 | ||||
-rw-r--r-- | fs/nfs/internal.h | 1 | ||||
-rw-r--r-- | fs/nfs/objlayout/objio_osd.c | 3 | ||||
-rw-r--r-- | fs/nfs/pagelist.c | 270 | ||||
-rw-r--r-- | fs/nfs/pnfs.c | 26 | ||||
-rw-r--r-- | fs/nfs/read.c | 30 | ||||
-rw-r--r-- | fs/nfs/write.c | 10 |
7 files changed, 293 insertions, 64 deletions
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index 1ee41d74c31c..0178d4fe8ab7 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c | |||
@@ -360,8 +360,14 @@ static void nfs_direct_read_completion(struct nfs_pgio_header *hdr) | |||
360 | spin_lock(&dreq->lock); | 360 | spin_lock(&dreq->lock); |
361 | if (test_bit(NFS_IOHDR_ERROR, &hdr->flags) && (hdr->good_bytes == 0)) | 361 | if (test_bit(NFS_IOHDR_ERROR, &hdr->flags) && (hdr->good_bytes == 0)) |
362 | dreq->error = hdr->error; | 362 | dreq->error = hdr->error; |
363 | else | 363 | else { |
364 | dreq->count += hdr->good_bytes; | 364 | /* |
365 | * FIXME: right now this only accounts for bytes written | ||
366 | * to the first mirror | ||
367 | */ | ||
368 | if (hdr->pgio_mirror_idx == 0) | ||
369 | dreq->count += hdr->good_bytes; | ||
370 | } | ||
365 | spin_unlock(&dreq->lock); | 371 | spin_unlock(&dreq->lock); |
366 | 372 | ||
367 | while (!list_empty(&hdr->pages)) { | 373 | while (!list_empty(&hdr->pages)) { |
@@ -724,7 +730,12 @@ static void nfs_direct_write_completion(struct nfs_pgio_header *hdr) | |||
724 | dreq->error = hdr->error; | 730 | dreq->error = hdr->error; |
725 | } | 731 | } |
726 | if (dreq->error == 0) { | 732 | if (dreq->error == 0) { |
727 | dreq->count += hdr->good_bytes; | 733 | /* |
734 | * FIXME: right now this only accounts for bytes written | ||
735 | * to the first mirror | ||
736 | */ | ||
737 | if (hdr->pgio_mirror_idx == 0) | ||
738 | dreq->count += hdr->good_bytes; | ||
728 | if (nfs_write_need_commit(hdr)) { | 739 | if (nfs_write_need_commit(hdr)) { |
729 | if (dreq->flags == NFS_ODIRECT_RESCHED_WRITES) | 740 | if (dreq->flags == NFS_ODIRECT_RESCHED_WRITES) |
730 | request_commit = true; | 741 | request_commit = true; |
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 05f9a87cdab4..ef1c703e487b 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h | |||
@@ -469,6 +469,7 @@ void nfs_init_cinfo(struct nfs_commit_info *cinfo, | |||
469 | struct nfs_direct_req *dreq); | 469 | struct nfs_direct_req *dreq); |
470 | int nfs_key_timeout_notify(struct file *filp, struct inode *inode); | 470 | int nfs_key_timeout_notify(struct file *filp, struct inode *inode); |
471 | bool nfs_ctx_key_to_expire(struct nfs_open_context *ctx); | 471 | bool nfs_ctx_key_to_expire(struct nfs_open_context *ctx); |
472 | void nfs_pageio_stop_mirroring(struct nfs_pageio_descriptor *pgio); | ||
472 | 473 | ||
473 | #ifdef CONFIG_MIGRATION | 474 | #ifdef CONFIG_MIGRATION |
474 | extern int nfs_migrate_page(struct address_space *, | 475 | extern int nfs_migrate_page(struct address_space *, |
diff --git a/fs/nfs/objlayout/objio_osd.c b/fs/nfs/objlayout/objio_osd.c index d00778077df1..9a5f2ee6001f 100644 --- a/fs/nfs/objlayout/objio_osd.c +++ b/fs/nfs/objlayout/objio_osd.c | |||
@@ -537,11 +537,12 @@ int objio_write_pagelist(struct nfs_pgio_header *hdr, int how) | |||
537 | static size_t objio_pg_test(struct nfs_pageio_descriptor *pgio, | 537 | static size_t objio_pg_test(struct nfs_pageio_descriptor *pgio, |
538 | struct nfs_page *prev, struct nfs_page *req) | 538 | struct nfs_page *prev, struct nfs_page *req) |
539 | { | 539 | { |
540 | struct nfs_pgio_mirror *mirror = &pgio->pg_mirrors[pgio->pg_mirror_idx]; | ||
540 | unsigned int size; | 541 | unsigned int size; |
541 | 542 | ||
542 | size = pnfs_generic_pg_test(pgio, prev, req); | 543 | size = pnfs_generic_pg_test(pgio, prev, req); |
543 | 544 | ||
544 | if (!size || pgio->pg_count + req->wb_bytes > | 545 | if (!size || mirror->pg_count + req->wb_bytes > |
545 | (unsigned long)pgio->pg_layout_private) | 546 | (unsigned long)pgio->pg_layout_private) |
546 | return 0; | 547 | return 0; |
547 | 548 | ||
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c index 1c031878c752..eec12b75c232 100644 --- a/fs/nfs/pagelist.c +++ b/fs/nfs/pagelist.c | |||
@@ -46,17 +46,22 @@ void nfs_pgheader_init(struct nfs_pageio_descriptor *desc, | |||
46 | struct nfs_pgio_header *hdr, | 46 | struct nfs_pgio_header *hdr, |
47 | void (*release)(struct nfs_pgio_header *hdr)) | 47 | void (*release)(struct nfs_pgio_header *hdr)) |
48 | { | 48 | { |
49 | hdr->req = nfs_list_entry(desc->pg_list.next); | 49 | struct nfs_pgio_mirror *mirror = &desc->pg_mirrors[desc->pg_mirror_idx]; |
50 | |||
51 | |||
52 | hdr->req = nfs_list_entry(mirror->pg_list.next); | ||
50 | hdr->inode = desc->pg_inode; | 53 | hdr->inode = desc->pg_inode; |
51 | hdr->cred = hdr->req->wb_context->cred; | 54 | hdr->cred = hdr->req->wb_context->cred; |
52 | hdr->io_start = req_offset(hdr->req); | 55 | hdr->io_start = req_offset(hdr->req); |
53 | hdr->good_bytes = desc->pg_count; | 56 | hdr->good_bytes = mirror->pg_count; |
54 | hdr->dreq = desc->pg_dreq; | 57 | hdr->dreq = desc->pg_dreq; |
55 | hdr->layout_private = desc->pg_layout_private; | 58 | hdr->layout_private = desc->pg_layout_private; |
56 | hdr->release = release; | 59 | hdr->release = release; |
57 | hdr->completion_ops = desc->pg_completion_ops; | 60 | hdr->completion_ops = desc->pg_completion_ops; |
58 | if (hdr->completion_ops->init_hdr) | 61 | if (hdr->completion_ops->init_hdr) |
59 | hdr->completion_ops->init_hdr(hdr); | 62 | hdr->completion_ops->init_hdr(hdr); |
63 | |||
64 | hdr->pgio_mirror_idx = desc->pg_mirror_idx; | ||
60 | } | 65 | } |
61 | EXPORT_SYMBOL_GPL(nfs_pgheader_init); | 66 | EXPORT_SYMBOL_GPL(nfs_pgheader_init); |
62 | 67 | ||
@@ -480,7 +485,10 @@ nfs_wait_on_request(struct nfs_page *req) | |||
480 | size_t nfs_generic_pg_test(struct nfs_pageio_descriptor *desc, | 485 | size_t nfs_generic_pg_test(struct nfs_pageio_descriptor *desc, |
481 | struct nfs_page *prev, struct nfs_page *req) | 486 | struct nfs_page *prev, struct nfs_page *req) |
482 | { | 487 | { |
483 | if (desc->pg_count > desc->pg_bsize) { | 488 | struct nfs_pgio_mirror *mirror = &desc->pg_mirrors[desc->pg_mirror_idx]; |
489 | |||
490 | |||
491 | if (mirror->pg_count > mirror->pg_bsize) { | ||
484 | /* should never happen */ | 492 | /* should never happen */ |
485 | WARN_ON_ONCE(1); | 493 | WARN_ON_ONCE(1); |
486 | return 0; | 494 | return 0; |
@@ -490,11 +498,11 @@ size_t nfs_generic_pg_test(struct nfs_pageio_descriptor *desc, | |||
490 | * Limit the request size so that we can still allocate a page array | 498 | * Limit the request size so that we can still allocate a page array |
491 | * for it without upsetting the slab allocator. | 499 | * for it without upsetting the slab allocator. |
492 | */ | 500 | */ |
493 | if (((desc->pg_count + req->wb_bytes) >> PAGE_SHIFT) * | 501 | if (((mirror->pg_count + req->wb_bytes) >> PAGE_SHIFT) * |
494 | sizeof(struct page) > PAGE_SIZE) | 502 | sizeof(struct page) > PAGE_SIZE) |
495 | return 0; | 503 | return 0; |
496 | 504 | ||
497 | return min(desc->pg_bsize - desc->pg_count, (size_t)req->wb_bytes); | 505 | return min(mirror->pg_bsize - mirror->pg_count, (size_t)req->wb_bytes); |
498 | } | 506 | } |
499 | EXPORT_SYMBOL_GPL(nfs_generic_pg_test); | 507 | EXPORT_SYMBOL_GPL(nfs_generic_pg_test); |
500 | 508 | ||
@@ -651,10 +659,18 @@ EXPORT_SYMBOL_GPL(nfs_initiate_pgio); | |||
651 | static int nfs_pgio_error(struct nfs_pageio_descriptor *desc, | 659 | static int nfs_pgio_error(struct nfs_pageio_descriptor *desc, |
652 | struct nfs_pgio_header *hdr) | 660 | struct nfs_pgio_header *hdr) |
653 | { | 661 | { |
662 | struct nfs_pgio_mirror *mirror; | ||
663 | u32 midx; | ||
664 | |||
654 | set_bit(NFS_IOHDR_REDO, &hdr->flags); | 665 | set_bit(NFS_IOHDR_REDO, &hdr->flags); |
655 | nfs_pgio_data_destroy(hdr); | 666 | nfs_pgio_data_destroy(hdr); |
656 | hdr->completion_ops->completion(hdr); | 667 | hdr->completion_ops->completion(hdr); |
657 | desc->pg_completion_ops->error_cleanup(&desc->pg_list); | 668 | /* TODO: Make sure it's right to clean up all mirrors here |
669 | * and not just hdr->pgio_mirror_idx */ | ||
670 | for (midx = 0; midx < desc->pg_mirror_count; midx++) { | ||
671 | mirror = &desc->pg_mirrors[midx]; | ||
672 | desc->pg_completion_ops->error_cleanup(&mirror->pg_list); | ||
673 | } | ||
658 | return -ENOMEM; | 674 | return -ENOMEM; |
659 | } | 675 | } |
660 | 676 | ||
@@ -671,6 +687,17 @@ static void nfs_pgio_release(void *calldata) | |||
671 | hdr->completion_ops->completion(hdr); | 687 | hdr->completion_ops->completion(hdr); |
672 | } | 688 | } |
673 | 689 | ||
690 | static void nfs_pageio_mirror_init(struct nfs_pgio_mirror *mirror, | ||
691 | unsigned int bsize) | ||
692 | { | ||
693 | INIT_LIST_HEAD(&mirror->pg_list); | ||
694 | mirror->pg_bytes_written = 0; | ||
695 | mirror->pg_count = 0; | ||
696 | mirror->pg_bsize = bsize; | ||
697 | mirror->pg_base = 0; | ||
698 | mirror->pg_recoalesce = 0; | ||
699 | } | ||
700 | |||
674 | /** | 701 | /** |
675 | * nfs_pageio_init - initialise a page io descriptor | 702 | * nfs_pageio_init - initialise a page io descriptor |
676 | * @desc: pointer to descriptor | 703 | * @desc: pointer to descriptor |
@@ -687,13 +714,10 @@ void nfs_pageio_init(struct nfs_pageio_descriptor *desc, | |||
687 | size_t bsize, | 714 | size_t bsize, |
688 | int io_flags) | 715 | int io_flags) |
689 | { | 716 | { |
690 | INIT_LIST_HEAD(&desc->pg_list); | 717 | struct nfs_pgio_mirror *new; |
691 | desc->pg_bytes_written = 0; | 718 | int i; |
692 | desc->pg_count = 0; | 719 | |
693 | desc->pg_bsize = bsize; | ||
694 | desc->pg_base = 0; | ||
695 | desc->pg_moreio = 0; | 720 | desc->pg_moreio = 0; |
696 | desc->pg_recoalesce = 0; | ||
697 | desc->pg_inode = inode; | 721 | desc->pg_inode = inode; |
698 | desc->pg_ops = pg_ops; | 722 | desc->pg_ops = pg_ops; |
699 | desc->pg_completion_ops = compl_ops; | 723 | desc->pg_completion_ops = compl_ops; |
@@ -703,6 +727,26 @@ void nfs_pageio_init(struct nfs_pageio_descriptor *desc, | |||
703 | desc->pg_lseg = NULL; | 727 | desc->pg_lseg = NULL; |
704 | desc->pg_dreq = NULL; | 728 | desc->pg_dreq = NULL; |
705 | desc->pg_layout_private = NULL; | 729 | desc->pg_layout_private = NULL; |
730 | desc->pg_bsize = bsize; | ||
731 | |||
732 | desc->pg_mirror_count = 1; | ||
733 | desc->pg_mirror_idx = 0; | ||
734 | |||
735 | if (pg_ops->pg_get_mirror_count) { | ||
736 | /* until we have a request, we don't have an lseg and no | ||
737 | * idea how many mirrors there will be */ | ||
738 | new = kcalloc(NFS_PAGEIO_DESCRIPTOR_MIRROR_MAX, | ||
739 | sizeof(struct nfs_pgio_mirror), GFP_KERNEL); | ||
740 | desc->pg_mirrors_dynamic = new; | ||
741 | desc->pg_mirrors = new; | ||
742 | |||
743 | for (i = 0; i < NFS_PAGEIO_DESCRIPTOR_MIRROR_MAX; i++) | ||
744 | nfs_pageio_mirror_init(&desc->pg_mirrors[i], bsize); | ||
745 | } else { | ||
746 | desc->pg_mirrors_dynamic = NULL; | ||
747 | desc->pg_mirrors = desc->pg_mirrors_static; | ||
748 | nfs_pageio_mirror_init(&desc->pg_mirrors[0], bsize); | ||
749 | } | ||
706 | } | 750 | } |
707 | EXPORT_SYMBOL_GPL(nfs_pageio_init); | 751 | EXPORT_SYMBOL_GPL(nfs_pageio_init); |
708 | 752 | ||
@@ -738,14 +782,16 @@ static void nfs_pgio_result(struct rpc_task *task, void *calldata) | |||
738 | int nfs_generic_pgio(struct nfs_pageio_descriptor *desc, | 782 | int nfs_generic_pgio(struct nfs_pageio_descriptor *desc, |
739 | struct nfs_pgio_header *hdr) | 783 | struct nfs_pgio_header *hdr) |
740 | { | 784 | { |
785 | struct nfs_pgio_mirror *mirror = &desc->pg_mirrors[desc->pg_mirror_idx]; | ||
786 | |||
741 | struct nfs_page *req; | 787 | struct nfs_page *req; |
742 | struct page **pages, | 788 | struct page **pages, |
743 | *last_page; | 789 | *last_page; |
744 | struct list_head *head = &desc->pg_list; | 790 | struct list_head *head = &mirror->pg_list; |
745 | struct nfs_commit_info cinfo; | 791 | struct nfs_commit_info cinfo; |
746 | unsigned int pagecount, pageused; | 792 | unsigned int pagecount, pageused; |
747 | 793 | ||
748 | pagecount = nfs_page_array_len(desc->pg_base, desc->pg_count); | 794 | pagecount = nfs_page_array_len(mirror->pg_base, mirror->pg_count); |
749 | if (!nfs_pgarray_set(&hdr->page_array, pagecount)) | 795 | if (!nfs_pgarray_set(&hdr->page_array, pagecount)) |
750 | return nfs_pgio_error(desc, hdr); | 796 | return nfs_pgio_error(desc, hdr); |
751 | 797 | ||
@@ -773,7 +819,7 @@ int nfs_generic_pgio(struct nfs_pageio_descriptor *desc, | |||
773 | desc->pg_ioflags &= ~FLUSH_COND_STABLE; | 819 | desc->pg_ioflags &= ~FLUSH_COND_STABLE; |
774 | 820 | ||
775 | /* Set up the argument struct */ | 821 | /* Set up the argument struct */ |
776 | nfs_pgio_rpcsetup(hdr, desc->pg_count, 0, desc->pg_ioflags, &cinfo); | 822 | nfs_pgio_rpcsetup(hdr, mirror->pg_count, 0, desc->pg_ioflags, &cinfo); |
777 | desc->pg_rpc_callops = &nfs_pgio_common_ops; | 823 | desc->pg_rpc_callops = &nfs_pgio_common_ops; |
778 | return 0; | 824 | return 0; |
779 | } | 825 | } |
@@ -781,12 +827,17 @@ EXPORT_SYMBOL_GPL(nfs_generic_pgio); | |||
781 | 827 | ||
782 | static int nfs_generic_pg_pgios(struct nfs_pageio_descriptor *desc) | 828 | static int nfs_generic_pg_pgios(struct nfs_pageio_descriptor *desc) |
783 | { | 829 | { |
830 | struct nfs_pgio_mirror *mirror; | ||
784 | struct nfs_pgio_header *hdr; | 831 | struct nfs_pgio_header *hdr; |
785 | int ret; | 832 | int ret; |
786 | 833 | ||
834 | mirror = &desc->pg_mirrors[desc->pg_mirror_idx]; | ||
835 | |||
787 | hdr = nfs_pgio_header_alloc(desc->pg_rw_ops); | 836 | hdr = nfs_pgio_header_alloc(desc->pg_rw_ops); |
788 | if (!hdr) { | 837 | if (!hdr) { |
789 | desc->pg_completion_ops->error_cleanup(&desc->pg_list); | 838 | /* TODO: make sure this is right with mirroring - or |
839 | * should it back out all mirrors? */ | ||
840 | desc->pg_completion_ops->error_cleanup(&mirror->pg_list); | ||
790 | return -ENOMEM; | 841 | return -ENOMEM; |
791 | } | 842 | } |
792 | nfs_pgheader_init(desc, hdr, nfs_pgio_header_free); | 843 | nfs_pgheader_init(desc, hdr, nfs_pgio_header_free); |
@@ -801,6 +852,49 @@ static int nfs_generic_pg_pgios(struct nfs_pageio_descriptor *desc) | |||
801 | return ret; | 852 | return ret; |
802 | } | 853 | } |
803 | 854 | ||
855 | /* | ||
856 | * nfs_pageio_setup_mirroring - determine if mirroring is to be used | ||
857 | * by calling the pg_get_mirror_count op | ||
858 | */ | ||
859 | static int nfs_pageio_setup_mirroring(struct nfs_pageio_descriptor *pgio, | ||
860 | struct nfs_page *req) | ||
861 | { | ||
862 | int mirror_count = 1; | ||
863 | |||
864 | if (!pgio->pg_ops->pg_get_mirror_count) | ||
865 | return 0; | ||
866 | |||
867 | mirror_count = pgio->pg_ops->pg_get_mirror_count(pgio, req); | ||
868 | |||
869 | if (!mirror_count || mirror_count > NFS_PAGEIO_DESCRIPTOR_MIRROR_MAX) | ||
870 | return -EINVAL; | ||
871 | |||
872 | if (WARN_ON_ONCE(!pgio->pg_mirrors_dynamic)) | ||
873 | return -EINVAL; | ||
874 | |||
875 | pgio->pg_mirror_count = mirror_count; | ||
876 | |||
877 | return 0; | ||
878 | } | ||
879 | |||
880 | /* | ||
881 | * nfs_pageio_stop_mirroring - stop using mirroring (set mirror count to 1) | ||
882 | */ | ||
883 | void nfs_pageio_stop_mirroring(struct nfs_pageio_descriptor *pgio) | ||
884 | { | ||
885 | pgio->pg_mirror_count = 1; | ||
886 | pgio->pg_mirror_idx = 0; | ||
887 | } | ||
888 | |||
889 | static void nfs_pageio_cleanup_mirroring(struct nfs_pageio_descriptor *pgio) | ||
890 | { | ||
891 | pgio->pg_mirror_count = 1; | ||
892 | pgio->pg_mirror_idx = 0; | ||
893 | pgio->pg_mirrors = pgio->pg_mirrors_static; | ||
894 | kfree(pgio->pg_mirrors_dynamic); | ||
895 | pgio->pg_mirrors_dynamic = NULL; | ||
896 | } | ||
897 | |||
804 | static bool nfs_match_open_context(const struct nfs_open_context *ctx1, | 898 | static bool nfs_match_open_context(const struct nfs_open_context *ctx1, |
805 | const struct nfs_open_context *ctx2) | 899 | const struct nfs_open_context *ctx2) |
806 | { | 900 | { |
@@ -867,19 +961,22 @@ static bool nfs_can_coalesce_requests(struct nfs_page *prev, | |||
867 | static int nfs_pageio_do_add_request(struct nfs_pageio_descriptor *desc, | 961 | static int nfs_pageio_do_add_request(struct nfs_pageio_descriptor *desc, |
868 | struct nfs_page *req) | 962 | struct nfs_page *req) |
869 | { | 963 | { |
964 | struct nfs_pgio_mirror *mirror = &desc->pg_mirrors[desc->pg_mirror_idx]; | ||
965 | |||
870 | struct nfs_page *prev = NULL; | 966 | struct nfs_page *prev = NULL; |
871 | if (desc->pg_count != 0) { | 967 | |
872 | prev = nfs_list_entry(desc->pg_list.prev); | 968 | if (mirror->pg_count != 0) { |
969 | prev = nfs_list_entry(mirror->pg_list.prev); | ||
873 | } else { | 970 | } else { |
874 | if (desc->pg_ops->pg_init) | 971 | if (desc->pg_ops->pg_init) |
875 | desc->pg_ops->pg_init(desc, req); | 972 | desc->pg_ops->pg_init(desc, req); |
876 | desc->pg_base = req->wb_pgbase; | 973 | mirror->pg_base = req->wb_pgbase; |
877 | } | 974 | } |
878 | if (!nfs_can_coalesce_requests(prev, req, desc)) | 975 | if (!nfs_can_coalesce_requests(prev, req, desc)) |
879 | return 0; | 976 | return 0; |
880 | nfs_list_remove_request(req); | 977 | nfs_list_remove_request(req); |
881 | nfs_list_add_request(req, &desc->pg_list); | 978 | nfs_list_add_request(req, &mirror->pg_list); |
882 | desc->pg_count += req->wb_bytes; | 979 | mirror->pg_count += req->wb_bytes; |
883 | return 1; | 980 | return 1; |
884 | } | 981 | } |
885 | 982 | ||
@@ -888,16 +985,19 @@ static int nfs_pageio_do_add_request(struct nfs_pageio_descriptor *desc, | |||
888 | */ | 985 | */ |
889 | static void nfs_pageio_doio(struct nfs_pageio_descriptor *desc) | 986 | static void nfs_pageio_doio(struct nfs_pageio_descriptor *desc) |
890 | { | 987 | { |
891 | if (!list_empty(&desc->pg_list)) { | 988 | struct nfs_pgio_mirror *mirror = &desc->pg_mirrors[desc->pg_mirror_idx]; |
989 | |||
990 | |||
991 | if (!list_empty(&mirror->pg_list)) { | ||
892 | int error = desc->pg_ops->pg_doio(desc); | 992 | int error = desc->pg_ops->pg_doio(desc); |
893 | if (error < 0) | 993 | if (error < 0) |
894 | desc->pg_error = error; | 994 | desc->pg_error = error; |
895 | else | 995 | else |
896 | desc->pg_bytes_written += desc->pg_count; | 996 | mirror->pg_bytes_written += mirror->pg_count; |
897 | } | 997 | } |
898 | if (list_empty(&desc->pg_list)) { | 998 | if (list_empty(&mirror->pg_list)) { |
899 | desc->pg_count = 0; | 999 | mirror->pg_count = 0; |
900 | desc->pg_base = 0; | 1000 | mirror->pg_base = 0; |
901 | } | 1001 | } |
902 | } | 1002 | } |
903 | 1003 | ||
@@ -915,10 +1015,14 @@ static void nfs_pageio_doio(struct nfs_pageio_descriptor *desc) | |||
915 | static int __nfs_pageio_add_request(struct nfs_pageio_descriptor *desc, | 1015 | static int __nfs_pageio_add_request(struct nfs_pageio_descriptor *desc, |
916 | struct nfs_page *req) | 1016 | struct nfs_page *req) |
917 | { | 1017 | { |
1018 | struct nfs_pgio_mirror *mirror = &desc->pg_mirrors[desc->pg_mirror_idx]; | ||
1019 | |||
918 | struct nfs_page *subreq; | 1020 | struct nfs_page *subreq; |
919 | unsigned int bytes_left = 0; | 1021 | unsigned int bytes_left = 0; |
920 | unsigned int offset, pgbase; | 1022 | unsigned int offset, pgbase; |
921 | 1023 | ||
1024 | WARN_ON_ONCE(desc->pg_mirror_idx >= desc->pg_mirror_count); | ||
1025 | |||
922 | nfs_page_group_lock(req, false); | 1026 | nfs_page_group_lock(req, false); |
923 | 1027 | ||
924 | subreq = req; | 1028 | subreq = req; |
@@ -938,7 +1042,7 @@ static int __nfs_pageio_add_request(struct nfs_pageio_descriptor *desc, | |||
938 | nfs_pageio_doio(desc); | 1042 | nfs_pageio_doio(desc); |
939 | if (desc->pg_error < 0) | 1043 | if (desc->pg_error < 0) |
940 | return 0; | 1044 | return 0; |
941 | if (desc->pg_recoalesce) | 1045 | if (mirror->pg_recoalesce) |
942 | return 0; | 1046 | return 0; |
943 | /* retry add_request for this subreq */ | 1047 | /* retry add_request for this subreq */ |
944 | nfs_page_group_lock(req, false); | 1048 | nfs_page_group_lock(req, false); |
@@ -976,14 +1080,16 @@ err_ptr: | |||
976 | 1080 | ||
977 | static int nfs_do_recoalesce(struct nfs_pageio_descriptor *desc) | 1081 | static int nfs_do_recoalesce(struct nfs_pageio_descriptor *desc) |
978 | { | 1082 | { |
1083 | struct nfs_pgio_mirror *mirror = &desc->pg_mirrors[desc->pg_mirror_idx]; | ||
979 | LIST_HEAD(head); | 1084 | LIST_HEAD(head); |
980 | 1085 | ||
981 | do { | 1086 | do { |
982 | list_splice_init(&desc->pg_list, &head); | 1087 | list_splice_init(&mirror->pg_list, &head); |
983 | desc->pg_bytes_written -= desc->pg_count; | 1088 | mirror->pg_bytes_written -= mirror->pg_count; |
984 | desc->pg_count = 0; | 1089 | mirror->pg_count = 0; |
985 | desc->pg_base = 0; | 1090 | mirror->pg_base = 0; |
986 | desc->pg_recoalesce = 0; | 1091 | mirror->pg_recoalesce = 0; |
1092 | |||
987 | desc->pg_moreio = 0; | 1093 | desc->pg_moreio = 0; |
988 | 1094 | ||
989 | while (!list_empty(&head)) { | 1095 | while (!list_empty(&head)) { |
@@ -997,11 +1103,11 @@ static int nfs_do_recoalesce(struct nfs_pageio_descriptor *desc) | |||
997 | return 0; | 1103 | return 0; |
998 | break; | 1104 | break; |
999 | } | 1105 | } |
1000 | } while (desc->pg_recoalesce); | 1106 | } while (mirror->pg_recoalesce); |
1001 | return 1; | 1107 | return 1; |
1002 | } | 1108 | } |
1003 | 1109 | ||
1004 | int nfs_pageio_add_request(struct nfs_pageio_descriptor *desc, | 1110 | static int nfs_pageio_add_request_mirror(struct nfs_pageio_descriptor *desc, |
1005 | struct nfs_page *req) | 1111 | struct nfs_page *req) |
1006 | { | 1112 | { |
1007 | int ret; | 1113 | int ret; |
@@ -1014,9 +1120,78 @@ int nfs_pageio_add_request(struct nfs_pageio_descriptor *desc, | |||
1014 | break; | 1120 | break; |
1015 | ret = nfs_do_recoalesce(desc); | 1121 | ret = nfs_do_recoalesce(desc); |
1016 | } while (ret); | 1122 | } while (ret); |
1123 | |||
1017 | return ret; | 1124 | return ret; |
1018 | } | 1125 | } |
1019 | 1126 | ||
1127 | int nfs_pageio_add_request(struct nfs_pageio_descriptor *desc, | ||
1128 | struct nfs_page *req) | ||
1129 | { | ||
1130 | u32 midx; | ||
1131 | unsigned int pgbase, offset, bytes; | ||
1132 | struct nfs_page *dupreq, *lastreq; | ||
1133 | |||
1134 | pgbase = req->wb_pgbase; | ||
1135 | offset = req->wb_offset; | ||
1136 | bytes = req->wb_bytes; | ||
1137 | |||
1138 | nfs_pageio_setup_mirroring(desc, req); | ||
1139 | |||
1140 | for (midx = 0; midx < desc->pg_mirror_count; midx++) { | ||
1141 | if (midx) { | ||
1142 | nfs_page_group_lock(req, false); | ||
1143 | |||
1144 | /* find the last request */ | ||
1145 | for (lastreq = req->wb_head; | ||
1146 | lastreq->wb_this_page != req->wb_head; | ||
1147 | lastreq = lastreq->wb_this_page) | ||
1148 | ; | ||
1149 | |||
1150 | dupreq = nfs_create_request(req->wb_context, | ||
1151 | req->wb_page, lastreq, pgbase, bytes); | ||
1152 | |||
1153 | if (IS_ERR(dupreq)) { | ||
1154 | nfs_page_group_unlock(req); | ||
1155 | return 0; | ||
1156 | } | ||
1157 | |||
1158 | nfs_lock_request(dupreq); | ||
1159 | nfs_page_group_unlock(req); | ||
1160 | dupreq->wb_offset = offset; | ||
1161 | dupreq->wb_index = req->wb_index; | ||
1162 | } else | ||
1163 | dupreq = req; | ||
1164 | |||
1165 | desc->pg_mirror_idx = midx; | ||
1166 | if (!nfs_pageio_add_request_mirror(desc, dupreq)) | ||
1167 | return 0; | ||
1168 | } | ||
1169 | |||
1170 | return 1; | ||
1171 | } | ||
1172 | |||
1173 | /* | ||
1174 | * nfs_pageio_complete_mirror - Complete I/O on the current mirror of an | ||
1175 | * nfs_pageio_descriptor | ||
1176 | * @desc: pointer to io descriptor | ||
1177 | */ | ||
1178 | static void nfs_pageio_complete_mirror(struct nfs_pageio_descriptor *desc, | ||
1179 | u32 mirror_idx) | ||
1180 | { | ||
1181 | struct nfs_pgio_mirror *mirror = &desc->pg_mirrors[mirror_idx]; | ||
1182 | u32 restore_idx = desc->pg_mirror_idx; | ||
1183 | |||
1184 | desc->pg_mirror_idx = mirror_idx; | ||
1185 | for (;;) { | ||
1186 | nfs_pageio_doio(desc); | ||
1187 | if (!mirror->pg_recoalesce) | ||
1188 | break; | ||
1189 | if (!nfs_do_recoalesce(desc)) | ||
1190 | break; | ||
1191 | } | ||
1192 | desc->pg_mirror_idx = restore_idx; | ||
1193 | } | ||
1194 | |||
1020 | /* | 1195 | /* |
1021 | * nfs_pageio_resend - Transfer requests to new descriptor and resend | 1196 | * nfs_pageio_resend - Transfer requests to new descriptor and resend |
1022 | * @hdr - the pgio header to move request from | 1197 | * @hdr - the pgio header to move request from |
@@ -1055,16 +1230,14 @@ EXPORT_SYMBOL_GPL(nfs_pageio_resend); | |||
1055 | */ | 1230 | */ |
1056 | void nfs_pageio_complete(struct nfs_pageio_descriptor *desc) | 1231 | void nfs_pageio_complete(struct nfs_pageio_descriptor *desc) |
1057 | { | 1232 | { |
1058 | for (;;) { | 1233 | u32 midx; |
1059 | nfs_pageio_doio(desc); | 1234 | |
1060 | if (!desc->pg_recoalesce) | 1235 | for (midx = 0; midx < desc->pg_mirror_count; midx++) |
1061 | break; | 1236 | nfs_pageio_complete_mirror(desc, midx); |
1062 | if (!nfs_do_recoalesce(desc)) | ||
1063 | break; | ||
1064 | } | ||
1065 | 1237 | ||
1066 | if (desc->pg_ops->pg_cleanup) | 1238 | if (desc->pg_ops->pg_cleanup) |
1067 | desc->pg_ops->pg_cleanup(desc); | 1239 | desc->pg_ops->pg_cleanup(desc); |
1240 | nfs_pageio_cleanup_mirroring(desc); | ||
1068 | } | 1241 | } |
1069 | 1242 | ||
1070 | /** | 1243 | /** |
@@ -1080,10 +1253,17 @@ void nfs_pageio_complete(struct nfs_pageio_descriptor *desc) | |||
1080 | */ | 1253 | */ |
1081 | void nfs_pageio_cond_complete(struct nfs_pageio_descriptor *desc, pgoff_t index) | 1254 | void nfs_pageio_cond_complete(struct nfs_pageio_descriptor *desc, pgoff_t index) |
1082 | { | 1255 | { |
1083 | if (!list_empty(&desc->pg_list)) { | 1256 | struct nfs_pgio_mirror *mirror; |
1084 | struct nfs_page *prev = nfs_list_entry(desc->pg_list.prev); | 1257 | struct nfs_page *prev; |
1085 | if (index != prev->wb_index + 1) | 1258 | u32 midx; |
1086 | nfs_pageio_complete(desc); | 1259 | |
1260 | for (midx = 0; midx < desc->pg_mirror_count; midx++) { | ||
1261 | mirror = &desc->pg_mirrors[midx]; | ||
1262 | if (!list_empty(&mirror->pg_list)) { | ||
1263 | prev = nfs_list_entry(mirror->pg_list.prev); | ||
1264 | if (index != prev->wb_index + 1) | ||
1265 | nfs_pageio_complete_mirror(desc, midx); | ||
1266 | } | ||
1087 | } | 1267 | } |
1088 | } | 1268 | } |
1089 | 1269 | ||
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c index 2da2e771fefe..5f7c422ebb5d 100644 --- a/fs/nfs/pnfs.c +++ b/fs/nfs/pnfs.c | |||
@@ -1646,8 +1646,8 @@ EXPORT_SYMBOL_GPL(pnfs_generic_pg_cleanup); | |||
1646 | * of bytes (maximum @req->wb_bytes) that can be coalesced. | 1646 | * of bytes (maximum @req->wb_bytes) that can be coalesced. |
1647 | */ | 1647 | */ |
1648 | size_t | 1648 | size_t |
1649 | pnfs_generic_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev, | 1649 | pnfs_generic_pg_test(struct nfs_pageio_descriptor *pgio, |
1650 | struct nfs_page *req) | 1650 | struct nfs_page *prev, struct nfs_page *req) |
1651 | { | 1651 | { |
1652 | unsigned int size; | 1652 | unsigned int size; |
1653 | u64 seg_end, req_start, seg_left; | 1653 | u64 seg_end, req_start, seg_left; |
@@ -1729,10 +1729,12 @@ static void | |||
1729 | pnfs_write_through_mds(struct nfs_pageio_descriptor *desc, | 1729 | pnfs_write_through_mds(struct nfs_pageio_descriptor *desc, |
1730 | struct nfs_pgio_header *hdr) | 1730 | struct nfs_pgio_header *hdr) |
1731 | { | 1731 | { |
1732 | struct nfs_pgio_mirror *mirror = &desc->pg_mirrors[desc->pg_mirror_idx]; | ||
1733 | |||
1732 | if (!test_and_set_bit(NFS_IOHDR_REDO, &hdr->flags)) { | 1734 | if (!test_and_set_bit(NFS_IOHDR_REDO, &hdr->flags)) { |
1733 | list_splice_tail_init(&hdr->pages, &desc->pg_list); | 1735 | list_splice_tail_init(&hdr->pages, &mirror->pg_list); |
1734 | nfs_pageio_reset_write_mds(desc); | 1736 | nfs_pageio_reset_write_mds(desc); |
1735 | desc->pg_recoalesce = 1; | 1737 | mirror->pg_recoalesce = 1; |
1736 | } | 1738 | } |
1737 | nfs_pgio_data_destroy(hdr); | 1739 | nfs_pgio_data_destroy(hdr); |
1738 | } | 1740 | } |
@@ -1781,12 +1783,14 @@ EXPORT_SYMBOL_GPL(pnfs_writehdr_free); | |||
1781 | int | 1783 | int |
1782 | pnfs_generic_pg_writepages(struct nfs_pageio_descriptor *desc) | 1784 | pnfs_generic_pg_writepages(struct nfs_pageio_descriptor *desc) |
1783 | { | 1785 | { |
1786 | struct nfs_pgio_mirror *mirror = &desc->pg_mirrors[desc->pg_mirror_idx]; | ||
1787 | |||
1784 | struct nfs_pgio_header *hdr; | 1788 | struct nfs_pgio_header *hdr; |
1785 | int ret; | 1789 | int ret; |
1786 | 1790 | ||
1787 | hdr = nfs_pgio_header_alloc(desc->pg_rw_ops); | 1791 | hdr = nfs_pgio_header_alloc(desc->pg_rw_ops); |
1788 | if (!hdr) { | 1792 | if (!hdr) { |
1789 | desc->pg_completion_ops->error_cleanup(&desc->pg_list); | 1793 | desc->pg_completion_ops->error_cleanup(&mirror->pg_list); |
1790 | return -ENOMEM; | 1794 | return -ENOMEM; |
1791 | } | 1795 | } |
1792 | nfs_pgheader_init(desc, hdr, pnfs_writehdr_free); | 1796 | nfs_pgheader_init(desc, hdr, pnfs_writehdr_free); |
@@ -1795,6 +1799,7 @@ pnfs_generic_pg_writepages(struct nfs_pageio_descriptor *desc) | |||
1795 | ret = nfs_generic_pgio(desc, hdr); | 1799 | ret = nfs_generic_pgio(desc, hdr); |
1796 | if (!ret) | 1800 | if (!ret) |
1797 | pnfs_do_write(desc, hdr, desc->pg_ioflags); | 1801 | pnfs_do_write(desc, hdr, desc->pg_ioflags); |
1802 | |||
1798 | return ret; | 1803 | return ret; |
1799 | } | 1804 | } |
1800 | EXPORT_SYMBOL_GPL(pnfs_generic_pg_writepages); | 1805 | EXPORT_SYMBOL_GPL(pnfs_generic_pg_writepages); |
@@ -1839,10 +1844,13 @@ static void | |||
1839 | pnfs_read_through_mds(struct nfs_pageio_descriptor *desc, | 1844 | pnfs_read_through_mds(struct nfs_pageio_descriptor *desc, |
1840 | struct nfs_pgio_header *hdr) | 1845 | struct nfs_pgio_header *hdr) |
1841 | { | 1846 | { |
1847 | struct nfs_pgio_mirror *mirror = &desc->pg_mirrors[desc->pg_mirror_idx]; | ||
1848 | |||
1849 | |||
1842 | if (!test_and_set_bit(NFS_IOHDR_REDO, &hdr->flags)) { | 1850 | if (!test_and_set_bit(NFS_IOHDR_REDO, &hdr->flags)) { |
1843 | list_splice_tail_init(&hdr->pages, &desc->pg_list); | 1851 | list_splice_tail_init(&hdr->pages, &mirror->pg_list); |
1844 | nfs_pageio_reset_read_mds(desc); | 1852 | nfs_pageio_reset_read_mds(desc); |
1845 | desc->pg_recoalesce = 1; | 1853 | mirror->pg_recoalesce = 1; |
1846 | } | 1854 | } |
1847 | nfs_pgio_data_destroy(hdr); | 1855 | nfs_pgio_data_destroy(hdr); |
1848 | } | 1856 | } |
@@ -1893,12 +1901,14 @@ EXPORT_SYMBOL_GPL(pnfs_readhdr_free); | |||
1893 | int | 1901 | int |
1894 | pnfs_generic_pg_readpages(struct nfs_pageio_descriptor *desc) | 1902 | pnfs_generic_pg_readpages(struct nfs_pageio_descriptor *desc) |
1895 | { | 1903 | { |
1904 | struct nfs_pgio_mirror *mirror = &desc->pg_mirrors[desc->pg_mirror_idx]; | ||
1905 | |||
1896 | struct nfs_pgio_header *hdr; | 1906 | struct nfs_pgio_header *hdr; |
1897 | int ret; | 1907 | int ret; |
1898 | 1908 | ||
1899 | hdr = nfs_pgio_header_alloc(desc->pg_rw_ops); | 1909 | hdr = nfs_pgio_header_alloc(desc->pg_rw_ops); |
1900 | if (!hdr) { | 1910 | if (!hdr) { |
1901 | desc->pg_completion_ops->error_cleanup(&desc->pg_list); | 1911 | desc->pg_completion_ops->error_cleanup(&mirror->pg_list); |
1902 | return -ENOMEM; | 1912 | return -ENOMEM; |
1903 | } | 1913 | } |
1904 | nfs_pgheader_init(desc, hdr, pnfs_readhdr_free); | 1914 | nfs_pgheader_init(desc, hdr, pnfs_readhdr_free); |
diff --git a/fs/nfs/read.c b/fs/nfs/read.c index 092ab499f2b6..568ecf0a880f 100644 --- a/fs/nfs/read.c +++ b/fs/nfs/read.c | |||
@@ -70,8 +70,15 @@ EXPORT_SYMBOL_GPL(nfs_pageio_init_read); | |||
70 | 70 | ||
71 | void nfs_pageio_reset_read_mds(struct nfs_pageio_descriptor *pgio) | 71 | void nfs_pageio_reset_read_mds(struct nfs_pageio_descriptor *pgio) |
72 | { | 72 | { |
73 | struct nfs_pgio_mirror *mirror; | ||
74 | |||
73 | pgio->pg_ops = &nfs_pgio_rw_ops; | 75 | pgio->pg_ops = &nfs_pgio_rw_ops; |
74 | pgio->pg_bsize = NFS_SERVER(pgio->pg_inode)->rsize; | 76 | |
77 | /* read path should never have more than one mirror */ | ||
78 | WARN_ON_ONCE(pgio->pg_mirror_count != 1); | ||
79 | |||
80 | mirror = &pgio->pg_mirrors[0]; | ||
81 | mirror->pg_bsize = NFS_SERVER(pgio->pg_inode)->rsize; | ||
75 | } | 82 | } |
76 | EXPORT_SYMBOL_GPL(nfs_pageio_reset_read_mds); | 83 | EXPORT_SYMBOL_GPL(nfs_pageio_reset_read_mds); |
77 | 84 | ||
@@ -81,6 +88,7 @@ int nfs_readpage_async(struct nfs_open_context *ctx, struct inode *inode, | |||
81 | struct nfs_page *new; | 88 | struct nfs_page *new; |
82 | unsigned int len; | 89 | unsigned int len; |
83 | struct nfs_pageio_descriptor pgio; | 90 | struct nfs_pageio_descriptor pgio; |
91 | struct nfs_pgio_mirror *pgm; | ||
84 | 92 | ||
85 | len = nfs_page_length(page); | 93 | len = nfs_page_length(page); |
86 | if (len == 0) | 94 | if (len == 0) |
@@ -97,7 +105,13 @@ int nfs_readpage_async(struct nfs_open_context *ctx, struct inode *inode, | |||
97 | &nfs_async_read_completion_ops); | 105 | &nfs_async_read_completion_ops); |
98 | nfs_pageio_add_request(&pgio, new); | 106 | nfs_pageio_add_request(&pgio, new); |
99 | nfs_pageio_complete(&pgio); | 107 | nfs_pageio_complete(&pgio); |
100 | NFS_I(inode)->read_io += pgio.pg_bytes_written; | 108 | |
109 | /* It doesn't make sense to do mirrored reads! */ | ||
110 | WARN_ON_ONCE(pgio.pg_mirror_count != 1); | ||
111 | |||
112 | pgm = &pgio.pg_mirrors[0]; | ||
113 | NFS_I(inode)->read_io += pgm->pg_bytes_written; | ||
114 | |||
101 | return 0; | 115 | return 0; |
102 | } | 116 | } |
103 | 117 | ||
@@ -352,6 +366,7 @@ int nfs_readpages(struct file *filp, struct address_space *mapping, | |||
352 | struct list_head *pages, unsigned nr_pages) | 366 | struct list_head *pages, unsigned nr_pages) |
353 | { | 367 | { |
354 | struct nfs_pageio_descriptor pgio; | 368 | struct nfs_pageio_descriptor pgio; |
369 | struct nfs_pgio_mirror *pgm; | ||
355 | struct nfs_readdesc desc = { | 370 | struct nfs_readdesc desc = { |
356 | .pgio = &pgio, | 371 | .pgio = &pgio, |
357 | }; | 372 | }; |
@@ -387,10 +402,15 @@ int nfs_readpages(struct file *filp, struct address_space *mapping, | |||
387 | &nfs_async_read_completion_ops); | 402 | &nfs_async_read_completion_ops); |
388 | 403 | ||
389 | ret = read_cache_pages(mapping, pages, readpage_async_filler, &desc); | 404 | ret = read_cache_pages(mapping, pages, readpage_async_filler, &desc); |
390 | |||
391 | nfs_pageio_complete(&pgio); | 405 | nfs_pageio_complete(&pgio); |
392 | NFS_I(inode)->read_io += pgio.pg_bytes_written; | 406 | |
393 | npages = (pgio.pg_bytes_written + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; | 407 | /* It doesn't make sense to do mirrored reads! */ |
408 | WARN_ON_ONCE(pgio.pg_mirror_count != 1); | ||
409 | |||
410 | pgm = &pgio.pg_mirrors[0]; | ||
411 | NFS_I(inode)->read_io += pgm->pg_bytes_written; | ||
412 | npages = (pgm->pg_bytes_written + PAGE_CACHE_SIZE - 1) >> | ||
413 | PAGE_CACHE_SHIFT; | ||
394 | nfs_add_stats(inode, NFSIOS_READPAGES, npages); | 414 | nfs_add_stats(inode, NFSIOS_READPAGES, npages); |
395 | read_complete: | 415 | read_complete: |
396 | put_nfs_open_context(desc.ctx); | 416 | put_nfs_open_context(desc.ctx); |
diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 2bee165fddcf..ceacfeeb28c2 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c | |||
@@ -906,7 +906,7 @@ static void nfs_write_completion(struct nfs_pgio_header *hdr) | |||
906 | if (nfs_write_need_commit(hdr)) { | 906 | if (nfs_write_need_commit(hdr)) { |
907 | memcpy(&req->wb_verf, &hdr->verf.verifier, sizeof(req->wb_verf)); | 907 | memcpy(&req->wb_verf, &hdr->verf.verifier, sizeof(req->wb_verf)); |
908 | nfs_mark_request_commit(req, hdr->lseg, &cinfo, | 908 | nfs_mark_request_commit(req, hdr->lseg, &cinfo, |
909 | 0); | 909 | hdr->pgio_mirror_idx); |
910 | goto next; | 910 | goto next; |
911 | } | 911 | } |
912 | remove_req: | 912 | remove_req: |
@@ -1304,8 +1304,14 @@ EXPORT_SYMBOL_GPL(nfs_pageio_init_write); | |||
1304 | 1304 | ||
1305 | void nfs_pageio_reset_write_mds(struct nfs_pageio_descriptor *pgio) | 1305 | void nfs_pageio_reset_write_mds(struct nfs_pageio_descriptor *pgio) |
1306 | { | 1306 | { |
1307 | struct nfs_pgio_mirror *mirror; | ||
1308 | |||
1307 | pgio->pg_ops = &nfs_pgio_rw_ops; | 1309 | pgio->pg_ops = &nfs_pgio_rw_ops; |
1308 | pgio->pg_bsize = NFS_SERVER(pgio->pg_inode)->wsize; | 1310 | |
1311 | nfs_pageio_stop_mirroring(pgio); | ||
1312 | |||
1313 | mirror = &pgio->pg_mirrors[0]; | ||
1314 | mirror->pg_bsize = NFS_SERVER(pgio->pg_inode)->wsize; | ||
1309 | } | 1315 | } |
1310 | EXPORT_SYMBOL_GPL(nfs_pageio_reset_write_mds); | 1316 | EXPORT_SYMBOL_GPL(nfs_pageio_reset_write_mds); |
1311 | 1317 | ||