aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/pagelist.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/pagelist.c')
-rw-r--r--fs/nfs/pagelist.c294
1 files changed, 245 insertions, 49 deletions
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
index 2b5e769beb16..960c99f75d3f 100644
--- a/fs/nfs/pagelist.c
+++ b/fs/nfs/pagelist.c
@@ -42,21 +42,35 @@ static bool nfs_pgarray_set(struct nfs_page_array *p, unsigned int pagecount)
42 return p->pagevec != NULL; 42 return p->pagevec != NULL;
43} 43}
44 44
45struct nfs_pgio_mirror *
46nfs_pgio_current_mirror(struct nfs_pageio_descriptor *desc)
47{
48 return nfs_pgio_has_mirroring(desc) ?
49 &desc->pg_mirrors[desc->pg_mirror_idx] :
50 &desc->pg_mirrors[0];
51}
52EXPORT_SYMBOL_GPL(nfs_pgio_current_mirror);
53
45void nfs_pgheader_init(struct nfs_pageio_descriptor *desc, 54void nfs_pgheader_init(struct nfs_pageio_descriptor *desc,
46 struct nfs_pgio_header *hdr, 55 struct nfs_pgio_header *hdr,
47 void (*release)(struct nfs_pgio_header *hdr)) 56 void (*release)(struct nfs_pgio_header *hdr))
48{ 57{
49 hdr->req = nfs_list_entry(desc->pg_list.next); 58 struct nfs_pgio_mirror *mirror = nfs_pgio_current_mirror(desc);
59
60
61 hdr->req = nfs_list_entry(mirror->pg_list.next);
50 hdr->inode = desc->pg_inode; 62 hdr->inode = desc->pg_inode;
51 hdr->cred = hdr->req->wb_context->cred; 63 hdr->cred = hdr->req->wb_context->cred;
52 hdr->io_start = req_offset(hdr->req); 64 hdr->io_start = req_offset(hdr->req);
53 hdr->good_bytes = desc->pg_count; 65 hdr->good_bytes = mirror->pg_count;
54 hdr->dreq = desc->pg_dreq; 66 hdr->dreq = desc->pg_dreq;
55 hdr->layout_private = desc->pg_layout_private; 67 hdr->layout_private = desc->pg_layout_private;
56 hdr->release = release; 68 hdr->release = release;
57 hdr->completion_ops = desc->pg_completion_ops; 69 hdr->completion_ops = desc->pg_completion_ops;
58 if (hdr->completion_ops->init_hdr) 70 if (hdr->completion_ops->init_hdr)
59 hdr->completion_ops->init_hdr(hdr); 71 hdr->completion_ops->init_hdr(hdr);
72
73 hdr->pgio_mirror_idx = desc->pg_mirror_idx;
60} 74}
61EXPORT_SYMBOL_GPL(nfs_pgheader_init); 75EXPORT_SYMBOL_GPL(nfs_pgheader_init);
62 76
@@ -480,7 +494,10 @@ nfs_wait_on_request(struct nfs_page *req)
480size_t nfs_generic_pg_test(struct nfs_pageio_descriptor *desc, 494size_t nfs_generic_pg_test(struct nfs_pageio_descriptor *desc,
481 struct nfs_page *prev, struct nfs_page *req) 495 struct nfs_page *prev, struct nfs_page *req)
482{ 496{
483 if (desc->pg_count > desc->pg_bsize) { 497 struct nfs_pgio_mirror *mirror = nfs_pgio_current_mirror(desc);
498
499
500 if (mirror->pg_count > mirror->pg_bsize) {
484 /* should never happen */ 501 /* should never happen */
485 WARN_ON_ONCE(1); 502 WARN_ON_ONCE(1);
486 return 0; 503 return 0;
@@ -490,11 +507,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 507 * Limit the request size so that we can still allocate a page array
491 * for it without upsetting the slab allocator. 508 * for it without upsetting the slab allocator.
492 */ 509 */
493 if (((desc->pg_count + req->wb_bytes) >> PAGE_SHIFT) * 510 if (((mirror->pg_count + req->wb_bytes) >> PAGE_SHIFT) *
494 sizeof(struct page) > PAGE_SIZE) 511 sizeof(struct page) > PAGE_SIZE)
495 return 0; 512 return 0;
496 513
497 return min(desc->pg_bsize - desc->pg_count, (size_t)req->wb_bytes); 514 return min(mirror->pg_bsize - mirror->pg_count, (size_t)req->wb_bytes);
498} 515}
499EXPORT_SYMBOL_GPL(nfs_generic_pg_test); 516EXPORT_SYMBOL_GPL(nfs_generic_pg_test);
500 517
@@ -597,13 +614,14 @@ static void nfs_pgio_prepare(struct rpc_task *task, void *calldata)
597} 614}
598 615
599int nfs_initiate_pgio(struct rpc_clnt *clnt, struct nfs_pgio_header *hdr, 616int nfs_initiate_pgio(struct rpc_clnt *clnt, struct nfs_pgio_header *hdr,
617 struct rpc_cred *cred, const struct nfs_rpc_ops *rpc_ops,
600 const struct rpc_call_ops *call_ops, int how, int flags) 618 const struct rpc_call_ops *call_ops, int how, int flags)
601{ 619{
602 struct rpc_task *task; 620 struct rpc_task *task;
603 struct rpc_message msg = { 621 struct rpc_message msg = {
604 .rpc_argp = &hdr->args, 622 .rpc_argp = &hdr->args,
605 .rpc_resp = &hdr->res, 623 .rpc_resp = &hdr->res,
606 .rpc_cred = hdr->cred, 624 .rpc_cred = cred,
607 }; 625 };
608 struct rpc_task_setup task_setup_data = { 626 struct rpc_task_setup task_setup_data = {
609 .rpc_client = clnt, 627 .rpc_client = clnt,
@@ -616,7 +634,7 @@ int nfs_initiate_pgio(struct rpc_clnt *clnt, struct nfs_pgio_header *hdr,
616 }; 634 };
617 int ret = 0; 635 int ret = 0;
618 636
619 hdr->rw_ops->rw_initiate(hdr, &msg, &task_setup_data, how); 637 hdr->rw_ops->rw_initiate(hdr, &msg, rpc_ops, &task_setup_data, how);
620 638
621 dprintk("NFS: %5u initiated pgio call " 639 dprintk("NFS: %5u initiated pgio call "
622 "(req %s/%llu, %u bytes @ offset %llu)\n", 640 "(req %s/%llu, %u bytes @ offset %llu)\n",
@@ -650,10 +668,18 @@ EXPORT_SYMBOL_GPL(nfs_initiate_pgio);
650static int nfs_pgio_error(struct nfs_pageio_descriptor *desc, 668static int nfs_pgio_error(struct nfs_pageio_descriptor *desc,
651 struct nfs_pgio_header *hdr) 669 struct nfs_pgio_header *hdr)
652{ 670{
671 struct nfs_pgio_mirror *mirror;
672 u32 midx;
673
653 set_bit(NFS_IOHDR_REDO, &hdr->flags); 674 set_bit(NFS_IOHDR_REDO, &hdr->flags);
654 nfs_pgio_data_destroy(hdr); 675 nfs_pgio_data_destroy(hdr);
655 hdr->completion_ops->completion(hdr); 676 hdr->completion_ops->completion(hdr);
656 desc->pg_completion_ops->error_cleanup(&desc->pg_list); 677 /* TODO: Make sure it's right to clean up all mirrors here
678 * and not just hdr->pgio_mirror_idx */
679 for (midx = 0; midx < desc->pg_mirror_count; midx++) {
680 mirror = &desc->pg_mirrors[midx];
681 desc->pg_completion_ops->error_cleanup(&mirror->pg_list);
682 }
657 return -ENOMEM; 683 return -ENOMEM;
658} 684}
659 685
@@ -670,6 +696,17 @@ static void nfs_pgio_release(void *calldata)
670 hdr->completion_ops->completion(hdr); 696 hdr->completion_ops->completion(hdr);
671} 697}
672 698
699static void nfs_pageio_mirror_init(struct nfs_pgio_mirror *mirror,
700 unsigned int bsize)
701{
702 INIT_LIST_HEAD(&mirror->pg_list);
703 mirror->pg_bytes_written = 0;
704 mirror->pg_count = 0;
705 mirror->pg_bsize = bsize;
706 mirror->pg_base = 0;
707 mirror->pg_recoalesce = 0;
708}
709
673/** 710/**
674 * nfs_pageio_init - initialise a page io descriptor 711 * nfs_pageio_init - initialise a page io descriptor
675 * @desc: pointer to descriptor 712 * @desc: pointer to descriptor
@@ -686,13 +723,10 @@ void nfs_pageio_init(struct nfs_pageio_descriptor *desc,
686 size_t bsize, 723 size_t bsize,
687 int io_flags) 724 int io_flags)
688{ 725{
689 INIT_LIST_HEAD(&desc->pg_list); 726 struct nfs_pgio_mirror *new;
690 desc->pg_bytes_written = 0; 727 int i;
691 desc->pg_count = 0; 728
692 desc->pg_bsize = bsize;
693 desc->pg_base = 0;
694 desc->pg_moreio = 0; 729 desc->pg_moreio = 0;
695 desc->pg_recoalesce = 0;
696 desc->pg_inode = inode; 730 desc->pg_inode = inode;
697 desc->pg_ops = pg_ops; 731 desc->pg_ops = pg_ops;
698 desc->pg_completion_ops = compl_ops; 732 desc->pg_completion_ops = compl_ops;
@@ -702,6 +736,26 @@ void nfs_pageio_init(struct nfs_pageio_descriptor *desc,
702 desc->pg_lseg = NULL; 736 desc->pg_lseg = NULL;
703 desc->pg_dreq = NULL; 737 desc->pg_dreq = NULL;
704 desc->pg_layout_private = NULL; 738 desc->pg_layout_private = NULL;
739 desc->pg_bsize = bsize;
740
741 desc->pg_mirror_count = 1;
742 desc->pg_mirror_idx = 0;
743
744 if (pg_ops->pg_get_mirror_count) {
745 /* until we have a request, we don't have an lseg and no
746 * idea how many mirrors there will be */
747 new = kcalloc(NFS_PAGEIO_DESCRIPTOR_MIRROR_MAX,
748 sizeof(struct nfs_pgio_mirror), GFP_KERNEL);
749 desc->pg_mirrors_dynamic = new;
750 desc->pg_mirrors = new;
751
752 for (i = 0; i < NFS_PAGEIO_DESCRIPTOR_MIRROR_MAX; i++)
753 nfs_pageio_mirror_init(&desc->pg_mirrors[i], bsize);
754 } else {
755 desc->pg_mirrors_dynamic = NULL;
756 desc->pg_mirrors = desc->pg_mirrors_static;
757 nfs_pageio_mirror_init(&desc->pg_mirrors[0], bsize);
758 }
705} 759}
706EXPORT_SYMBOL_GPL(nfs_pageio_init); 760EXPORT_SYMBOL_GPL(nfs_pageio_init);
707 761
@@ -737,14 +791,16 @@ static void nfs_pgio_result(struct rpc_task *task, void *calldata)
737int nfs_generic_pgio(struct nfs_pageio_descriptor *desc, 791int nfs_generic_pgio(struct nfs_pageio_descriptor *desc,
738 struct nfs_pgio_header *hdr) 792 struct nfs_pgio_header *hdr)
739{ 793{
794 struct nfs_pgio_mirror *mirror = nfs_pgio_current_mirror(desc);
795
740 struct nfs_page *req; 796 struct nfs_page *req;
741 struct page **pages, 797 struct page **pages,
742 *last_page; 798 *last_page;
743 struct list_head *head = &desc->pg_list; 799 struct list_head *head = &mirror->pg_list;
744 struct nfs_commit_info cinfo; 800 struct nfs_commit_info cinfo;
745 unsigned int pagecount, pageused; 801 unsigned int pagecount, pageused;
746 802
747 pagecount = nfs_page_array_len(desc->pg_base, desc->pg_count); 803 pagecount = nfs_page_array_len(mirror->pg_base, mirror->pg_count);
748 if (!nfs_pgarray_set(&hdr->page_array, pagecount)) 804 if (!nfs_pgarray_set(&hdr->page_array, pagecount))
749 return nfs_pgio_error(desc, hdr); 805 return nfs_pgio_error(desc, hdr);
750 806
@@ -772,7 +828,7 @@ int nfs_generic_pgio(struct nfs_pageio_descriptor *desc,
772 desc->pg_ioflags &= ~FLUSH_COND_STABLE; 828 desc->pg_ioflags &= ~FLUSH_COND_STABLE;
773 829
774 /* Set up the argument struct */ 830 /* Set up the argument struct */
775 nfs_pgio_rpcsetup(hdr, desc->pg_count, 0, desc->pg_ioflags, &cinfo); 831 nfs_pgio_rpcsetup(hdr, mirror->pg_count, 0, desc->pg_ioflags, &cinfo);
776 desc->pg_rpc_callops = &nfs_pgio_common_ops; 832 desc->pg_rpc_callops = &nfs_pgio_common_ops;
777 return 0; 833 return 0;
778} 834}
@@ -780,23 +836,74 @@ EXPORT_SYMBOL_GPL(nfs_generic_pgio);
780 836
781static int nfs_generic_pg_pgios(struct nfs_pageio_descriptor *desc) 837static int nfs_generic_pg_pgios(struct nfs_pageio_descriptor *desc)
782{ 838{
839 struct nfs_pgio_mirror *mirror;
783 struct nfs_pgio_header *hdr; 840 struct nfs_pgio_header *hdr;
784 int ret; 841 int ret;
785 842
843 mirror = nfs_pgio_current_mirror(desc);
844
786 hdr = nfs_pgio_header_alloc(desc->pg_rw_ops); 845 hdr = nfs_pgio_header_alloc(desc->pg_rw_ops);
787 if (!hdr) { 846 if (!hdr) {
788 desc->pg_completion_ops->error_cleanup(&desc->pg_list); 847 /* TODO: make sure this is right with mirroring - or
848 * should it back out all mirrors? */
849 desc->pg_completion_ops->error_cleanup(&mirror->pg_list);
789 return -ENOMEM; 850 return -ENOMEM;
790 } 851 }
791 nfs_pgheader_init(desc, hdr, nfs_pgio_header_free); 852 nfs_pgheader_init(desc, hdr, nfs_pgio_header_free);
792 ret = nfs_generic_pgio(desc, hdr); 853 ret = nfs_generic_pgio(desc, hdr);
793 if (ret == 0) 854 if (ret == 0)
794 ret = nfs_initiate_pgio(NFS_CLIENT(hdr->inode), 855 ret = nfs_initiate_pgio(NFS_CLIENT(hdr->inode),
795 hdr, desc->pg_rpc_callops, 856 hdr,
857 hdr->cred,
858 NFS_PROTO(hdr->inode),
859 desc->pg_rpc_callops,
796 desc->pg_ioflags, 0); 860 desc->pg_ioflags, 0);
797 return ret; 861 return ret;
798} 862}
799 863
864/*
865 * nfs_pageio_setup_mirroring - determine if mirroring is to be used
866 * by calling the pg_get_mirror_count op
867 */
868static int nfs_pageio_setup_mirroring(struct nfs_pageio_descriptor *pgio,
869 struct nfs_page *req)
870{
871 int mirror_count = 1;
872
873 if (!pgio->pg_ops->pg_get_mirror_count)
874 return 0;
875
876 mirror_count = pgio->pg_ops->pg_get_mirror_count(pgio, req);
877
878 if (!mirror_count || mirror_count > NFS_PAGEIO_DESCRIPTOR_MIRROR_MAX)
879 return -EINVAL;
880
881 if (WARN_ON_ONCE(!pgio->pg_mirrors_dynamic))
882 return -EINVAL;
883
884 pgio->pg_mirror_count = mirror_count;
885
886 return 0;
887}
888
889/*
890 * nfs_pageio_stop_mirroring - stop using mirroring (set mirror count to 1)
891 */
892void nfs_pageio_stop_mirroring(struct nfs_pageio_descriptor *pgio)
893{
894 pgio->pg_mirror_count = 1;
895 pgio->pg_mirror_idx = 0;
896}
897
898static void nfs_pageio_cleanup_mirroring(struct nfs_pageio_descriptor *pgio)
899{
900 pgio->pg_mirror_count = 1;
901 pgio->pg_mirror_idx = 0;
902 pgio->pg_mirrors = pgio->pg_mirrors_static;
903 kfree(pgio->pg_mirrors_dynamic);
904 pgio->pg_mirrors_dynamic = NULL;
905}
906
800static bool nfs_match_open_context(const struct nfs_open_context *ctx1, 907static bool nfs_match_open_context(const struct nfs_open_context *ctx1,
801 const struct nfs_open_context *ctx2) 908 const struct nfs_open_context *ctx2)
802{ 909{
@@ -863,19 +970,22 @@ static bool nfs_can_coalesce_requests(struct nfs_page *prev,
863static int nfs_pageio_do_add_request(struct nfs_pageio_descriptor *desc, 970static int nfs_pageio_do_add_request(struct nfs_pageio_descriptor *desc,
864 struct nfs_page *req) 971 struct nfs_page *req)
865{ 972{
973 struct nfs_pgio_mirror *mirror = nfs_pgio_current_mirror(desc);
974
866 struct nfs_page *prev = NULL; 975 struct nfs_page *prev = NULL;
867 if (desc->pg_count != 0) { 976
868 prev = nfs_list_entry(desc->pg_list.prev); 977 if (mirror->pg_count != 0) {
978 prev = nfs_list_entry(mirror->pg_list.prev);
869 } else { 979 } else {
870 if (desc->pg_ops->pg_init) 980 if (desc->pg_ops->pg_init)
871 desc->pg_ops->pg_init(desc, req); 981 desc->pg_ops->pg_init(desc, req);
872 desc->pg_base = req->wb_pgbase; 982 mirror->pg_base = req->wb_pgbase;
873 } 983 }
874 if (!nfs_can_coalesce_requests(prev, req, desc)) 984 if (!nfs_can_coalesce_requests(prev, req, desc))
875 return 0; 985 return 0;
876 nfs_list_remove_request(req); 986 nfs_list_remove_request(req);
877 nfs_list_add_request(req, &desc->pg_list); 987 nfs_list_add_request(req, &mirror->pg_list);
878 desc->pg_count += req->wb_bytes; 988 mirror->pg_count += req->wb_bytes;
879 return 1; 989 return 1;
880} 990}
881 991
@@ -884,16 +994,19 @@ static int nfs_pageio_do_add_request(struct nfs_pageio_descriptor *desc,
884 */ 994 */
885static void nfs_pageio_doio(struct nfs_pageio_descriptor *desc) 995static void nfs_pageio_doio(struct nfs_pageio_descriptor *desc)
886{ 996{
887 if (!list_empty(&desc->pg_list)) { 997 struct nfs_pgio_mirror *mirror = nfs_pgio_current_mirror(desc);
998
999
1000 if (!list_empty(&mirror->pg_list)) {
888 int error = desc->pg_ops->pg_doio(desc); 1001 int error = desc->pg_ops->pg_doio(desc);
889 if (error < 0) 1002 if (error < 0)
890 desc->pg_error = error; 1003 desc->pg_error = error;
891 else 1004 else
892 desc->pg_bytes_written += desc->pg_count; 1005 mirror->pg_bytes_written += mirror->pg_count;
893 } 1006 }
894 if (list_empty(&desc->pg_list)) { 1007 if (list_empty(&mirror->pg_list)) {
895 desc->pg_count = 0; 1008 mirror->pg_count = 0;
896 desc->pg_base = 0; 1009 mirror->pg_base = 0;
897 } 1010 }
898} 1011}
899 1012
@@ -911,6 +1024,8 @@ static void nfs_pageio_doio(struct nfs_pageio_descriptor *desc)
911static int __nfs_pageio_add_request(struct nfs_pageio_descriptor *desc, 1024static int __nfs_pageio_add_request(struct nfs_pageio_descriptor *desc,
912 struct nfs_page *req) 1025 struct nfs_page *req)
913{ 1026{
1027 struct nfs_pgio_mirror *mirror = nfs_pgio_current_mirror(desc);
1028
914 struct nfs_page *subreq; 1029 struct nfs_page *subreq;
915 unsigned int bytes_left = 0; 1030 unsigned int bytes_left = 0;
916 unsigned int offset, pgbase; 1031 unsigned int offset, pgbase;
@@ -934,7 +1049,7 @@ static int __nfs_pageio_add_request(struct nfs_pageio_descriptor *desc,
934 nfs_pageio_doio(desc); 1049 nfs_pageio_doio(desc);
935 if (desc->pg_error < 0) 1050 if (desc->pg_error < 0)
936 return 0; 1051 return 0;
937 if (desc->pg_recoalesce) 1052 if (mirror->pg_recoalesce)
938 return 0; 1053 return 0;
939 /* retry add_request for this subreq */ 1054 /* retry add_request for this subreq */
940 nfs_page_group_lock(req, false); 1055 nfs_page_group_lock(req, false);
@@ -972,14 +1087,16 @@ err_ptr:
972 1087
973static int nfs_do_recoalesce(struct nfs_pageio_descriptor *desc) 1088static int nfs_do_recoalesce(struct nfs_pageio_descriptor *desc)
974{ 1089{
1090 struct nfs_pgio_mirror *mirror = nfs_pgio_current_mirror(desc);
975 LIST_HEAD(head); 1091 LIST_HEAD(head);
976 1092
977 do { 1093 do {
978 list_splice_init(&desc->pg_list, &head); 1094 list_splice_init(&mirror->pg_list, &head);
979 desc->pg_bytes_written -= desc->pg_count; 1095 mirror->pg_bytes_written -= mirror->pg_count;
980 desc->pg_count = 0; 1096 mirror->pg_count = 0;
981 desc->pg_base = 0; 1097 mirror->pg_base = 0;
982 desc->pg_recoalesce = 0; 1098 mirror->pg_recoalesce = 0;
1099
983 desc->pg_moreio = 0; 1100 desc->pg_moreio = 0;
984 1101
985 while (!list_empty(&head)) { 1102 while (!list_empty(&head)) {
@@ -993,11 +1110,11 @@ static int nfs_do_recoalesce(struct nfs_pageio_descriptor *desc)
993 return 0; 1110 return 0;
994 break; 1111 break;
995 } 1112 }
996 } while (desc->pg_recoalesce); 1113 } while (mirror->pg_recoalesce);
997 return 1; 1114 return 1;
998} 1115}
999 1116
1000int nfs_pageio_add_request(struct nfs_pageio_descriptor *desc, 1117static int nfs_pageio_add_request_mirror(struct nfs_pageio_descriptor *desc,
1001 struct nfs_page *req) 1118 struct nfs_page *req)
1002{ 1119{
1003 int ret; 1120 int ret;
@@ -1010,9 +1127,80 @@ int nfs_pageio_add_request(struct nfs_pageio_descriptor *desc,
1010 break; 1127 break;
1011 ret = nfs_do_recoalesce(desc); 1128 ret = nfs_do_recoalesce(desc);
1012 } while (ret); 1129 } while (ret);
1130
1013 return ret; 1131 return ret;
1014} 1132}
1015 1133
1134int nfs_pageio_add_request(struct nfs_pageio_descriptor *desc,
1135 struct nfs_page *req)
1136{
1137 u32 midx;
1138 unsigned int pgbase, offset, bytes;
1139 struct nfs_page *dupreq, *lastreq;
1140
1141 pgbase = req->wb_pgbase;
1142 offset = req->wb_offset;
1143 bytes = req->wb_bytes;
1144
1145 nfs_pageio_setup_mirroring(desc, req);
1146
1147 for (midx = 0; midx < desc->pg_mirror_count; midx++) {
1148 if (midx) {
1149 nfs_page_group_lock(req, false);
1150
1151 /* find the last request */
1152 for (lastreq = req->wb_head;
1153 lastreq->wb_this_page != req->wb_head;
1154 lastreq = lastreq->wb_this_page)
1155 ;
1156
1157 dupreq = nfs_create_request(req->wb_context,
1158 req->wb_page, lastreq, pgbase, bytes);
1159
1160 if (IS_ERR(dupreq)) {
1161 nfs_page_group_unlock(req);
1162 return 0;
1163 }
1164
1165 nfs_lock_request(dupreq);
1166 nfs_page_group_unlock(req);
1167 dupreq->wb_offset = offset;
1168 dupreq->wb_index = req->wb_index;
1169 } else
1170 dupreq = req;
1171
1172 if (nfs_pgio_has_mirroring(desc))
1173 desc->pg_mirror_idx = midx;
1174 if (!nfs_pageio_add_request_mirror(desc, dupreq))
1175 return 0;
1176 }
1177
1178 return 1;
1179}
1180
1181/*
1182 * nfs_pageio_complete_mirror - Complete I/O on the current mirror of an
1183 * nfs_pageio_descriptor
1184 * @desc: pointer to io descriptor
1185 */
1186static void nfs_pageio_complete_mirror(struct nfs_pageio_descriptor *desc,
1187 u32 mirror_idx)
1188{
1189 struct nfs_pgio_mirror *mirror = &desc->pg_mirrors[mirror_idx];
1190 u32 restore_idx = desc->pg_mirror_idx;
1191
1192 if (nfs_pgio_has_mirroring(desc))
1193 desc->pg_mirror_idx = mirror_idx;
1194 for (;;) {
1195 nfs_pageio_doio(desc);
1196 if (!mirror->pg_recoalesce)
1197 break;
1198 if (!nfs_do_recoalesce(desc))
1199 break;
1200 }
1201 desc->pg_mirror_idx = restore_idx;
1202}
1203
1016/* 1204/*
1017 * nfs_pageio_resend - Transfer requests to new descriptor and resend 1205 * nfs_pageio_resend - Transfer requests to new descriptor and resend
1018 * @hdr - the pgio header to move request from 1206 * @hdr - the pgio header to move request from
@@ -1046,18 +1234,19 @@ int nfs_pageio_resend(struct nfs_pageio_descriptor *desc,
1046EXPORT_SYMBOL_GPL(nfs_pageio_resend); 1234EXPORT_SYMBOL_GPL(nfs_pageio_resend);
1047 1235
1048/** 1236/**
1049 * nfs_pageio_complete - Complete I/O on an nfs_pageio_descriptor 1237 * nfs_pageio_complete - Complete I/O then cleanup an nfs_pageio_descriptor
1050 * @desc: pointer to io descriptor 1238 * @desc: pointer to io descriptor
1051 */ 1239 */
1052void nfs_pageio_complete(struct nfs_pageio_descriptor *desc) 1240void nfs_pageio_complete(struct nfs_pageio_descriptor *desc)
1053{ 1241{
1054 for (;;) { 1242 u32 midx;
1055 nfs_pageio_doio(desc); 1243
1056 if (!desc->pg_recoalesce) 1244 for (midx = 0; midx < desc->pg_mirror_count; midx++)
1057 break; 1245 nfs_pageio_complete_mirror(desc, midx);
1058 if (!nfs_do_recoalesce(desc)) 1246
1059 break; 1247 if (desc->pg_ops->pg_cleanup)
1060 } 1248 desc->pg_ops->pg_cleanup(desc);
1249 nfs_pageio_cleanup_mirroring(desc);
1061} 1250}
1062 1251
1063/** 1252/**
@@ -1073,10 +1262,17 @@ void nfs_pageio_complete(struct nfs_pageio_descriptor *desc)
1073 */ 1262 */
1074void nfs_pageio_cond_complete(struct nfs_pageio_descriptor *desc, pgoff_t index) 1263void nfs_pageio_cond_complete(struct nfs_pageio_descriptor *desc, pgoff_t index)
1075{ 1264{
1076 if (!list_empty(&desc->pg_list)) { 1265 struct nfs_pgio_mirror *mirror;
1077 struct nfs_page *prev = nfs_list_entry(desc->pg_list.prev); 1266 struct nfs_page *prev;
1078 if (index != prev->wb_index + 1) 1267 u32 midx;
1079 nfs_pageio_complete(desc); 1268
1269 for (midx = 0; midx < desc->pg_mirror_count; midx++) {
1270 mirror = &desc->pg_mirrors[midx];
1271 if (!list_empty(&mirror->pg_list)) {
1272 prev = nfs_list_entry(mirror->pg_list.prev);
1273 if (index != prev->wb_index + 1)
1274 nfs_pageio_complete_mirror(desc, midx);
1275 }
1080 } 1276 }
1081} 1277}
1082 1278