aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/nfs/direct.c17
-rw-r--r--fs/nfs/internal.h1
-rw-r--r--fs/nfs/objlayout/objio_osd.c3
-rw-r--r--fs/nfs/pagelist.c270
-rw-r--r--fs/nfs/pnfs.c26
-rw-r--r--fs/nfs/read.c30
-rw-r--r--fs/nfs/write.c10
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);
470int nfs_key_timeout_notify(struct file *filp, struct inode *inode); 470int nfs_key_timeout_notify(struct file *filp, struct inode *inode);
471bool nfs_ctx_key_to_expire(struct nfs_open_context *ctx); 471bool nfs_ctx_key_to_expire(struct nfs_open_context *ctx);
472void nfs_pageio_stop_mirroring(struct nfs_pageio_descriptor *pgio);
472 473
473#ifdef CONFIG_MIGRATION 474#ifdef CONFIG_MIGRATION
474extern int nfs_migrate_page(struct address_space *, 475extern 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)
537static size_t objio_pg_test(struct nfs_pageio_descriptor *pgio, 537static 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}
61EXPORT_SYMBOL_GPL(nfs_pgheader_init); 66EXPORT_SYMBOL_GPL(nfs_pgheader_init);
62 67
@@ -480,7 +485,10 @@ nfs_wait_on_request(struct nfs_page *req)
480size_t nfs_generic_pg_test(struct nfs_pageio_descriptor *desc, 485size_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}
499EXPORT_SYMBOL_GPL(nfs_generic_pg_test); 507EXPORT_SYMBOL_GPL(nfs_generic_pg_test);
500 508
@@ -651,10 +659,18 @@ EXPORT_SYMBOL_GPL(nfs_initiate_pgio);
651static int nfs_pgio_error(struct nfs_pageio_descriptor *desc, 659static 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
690static 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}
707EXPORT_SYMBOL_GPL(nfs_pageio_init); 751EXPORT_SYMBOL_GPL(nfs_pageio_init);
708 752
@@ -738,14 +782,16 @@ static void nfs_pgio_result(struct rpc_task *task, void *calldata)
738int nfs_generic_pgio(struct nfs_pageio_descriptor *desc, 782int 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
782static int nfs_generic_pg_pgios(struct nfs_pageio_descriptor *desc) 828static 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 */
859static 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 */
883void nfs_pageio_stop_mirroring(struct nfs_pageio_descriptor *pgio)
884{
885 pgio->pg_mirror_count = 1;
886 pgio->pg_mirror_idx = 0;
887}
888
889static 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
804static bool nfs_match_open_context(const struct nfs_open_context *ctx1, 898static 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,
867static int nfs_pageio_do_add_request(struct nfs_pageio_descriptor *desc, 961static 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 */
889static void nfs_pageio_doio(struct nfs_pageio_descriptor *desc) 986static 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)
915static int __nfs_pageio_add_request(struct nfs_pageio_descriptor *desc, 1015static 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
977static int nfs_do_recoalesce(struct nfs_pageio_descriptor *desc) 1081static 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
1004int nfs_pageio_add_request(struct nfs_pageio_descriptor *desc, 1110static 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
1127int 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 */
1178static 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 */
1056void nfs_pageio_complete(struct nfs_pageio_descriptor *desc) 1231void 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 */
1081void nfs_pageio_cond_complete(struct nfs_pageio_descriptor *desc, pgoff_t index) 1254void 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 */
1648size_t 1648size_t
1649pnfs_generic_pg_test(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev, 1649pnfs_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
1729pnfs_write_through_mds(struct nfs_pageio_descriptor *desc, 1729pnfs_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);
1781int 1783int
1782pnfs_generic_pg_writepages(struct nfs_pageio_descriptor *desc) 1784pnfs_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}
1800EXPORT_SYMBOL_GPL(pnfs_generic_pg_writepages); 1805EXPORT_SYMBOL_GPL(pnfs_generic_pg_writepages);
@@ -1839,10 +1844,13 @@ static void
1839pnfs_read_through_mds(struct nfs_pageio_descriptor *desc, 1844pnfs_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);
1893int 1901int
1894pnfs_generic_pg_readpages(struct nfs_pageio_descriptor *desc) 1902pnfs_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
71void nfs_pageio_reset_read_mds(struct nfs_pageio_descriptor *pgio) 71void 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}
76EXPORT_SYMBOL_GPL(nfs_pageio_reset_read_mds); 83EXPORT_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);
395read_complete: 415read_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 }
912remove_req: 912remove_req:
@@ -1304,8 +1304,14 @@ EXPORT_SYMBOL_GPL(nfs_pageio_init_write);
1304 1304
1305void nfs_pageio_reset_write_mds(struct nfs_pageio_descriptor *pgio) 1305void 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}
1310EXPORT_SYMBOL_GPL(nfs_pageio_reset_write_mds); 1316EXPORT_SYMBOL_GPL(nfs_pageio_reset_write_mds);
1311 1317