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.c47
1 files changed, 29 insertions, 18 deletions
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
index e54d899c1848..e9f39fa5964b 100644
--- a/fs/nfs/pagelist.c
+++ b/fs/nfs/pagelist.c
@@ -350,7 +350,7 @@ nfs_create_request(struct nfs_open_context *ctx, struct page *page,
350 350
351/** 351/**
352 * nfs_unlock_request - Unlock request and wake up sleepers. 352 * nfs_unlock_request - Unlock request and wake up sleepers.
353 * @req: 353 * @req: pointer to request
354 */ 354 */
355void nfs_unlock_request(struct nfs_page *req) 355void nfs_unlock_request(struct nfs_page *req)
356{ 356{
@@ -368,7 +368,7 @@ void nfs_unlock_request(struct nfs_page *req)
368 368
369/** 369/**
370 * nfs_unlock_and_release_request - Unlock request and release the nfs_page 370 * nfs_unlock_and_release_request - Unlock request and release the nfs_page
371 * @req: 371 * @req: pointer to request
372 */ 372 */
373void nfs_unlock_and_release_request(struct nfs_page *req) 373void nfs_unlock_and_release_request(struct nfs_page *req)
374{ 374{
@@ -531,7 +531,6 @@ EXPORT_SYMBOL_GPL(nfs_pgio_header_free);
531 * nfs_pgio_rpcsetup - Set up arguments for a pageio call 531 * nfs_pgio_rpcsetup - Set up arguments for a pageio call
532 * @hdr: The pageio hdr 532 * @hdr: The pageio hdr
533 * @count: Number of bytes to read 533 * @count: Number of bytes to read
534 * @offset: Initial offset
535 * @how: How to commit data (writes only) 534 * @how: How to commit data (writes only)
536 * @cinfo: Commit information for the call (writes only) 535 * @cinfo: Commit information for the call (writes only)
537 */ 536 */
@@ -634,7 +633,6 @@ EXPORT_SYMBOL_GPL(nfs_initiate_pgio);
634 633
635/** 634/**
636 * nfs_pgio_error - Clean up from a pageio error 635 * nfs_pgio_error - Clean up from a pageio error
637 * @desc: IO descriptor
638 * @hdr: pageio header 636 * @hdr: pageio header
639 */ 637 */
640static void nfs_pgio_error(struct nfs_pgio_header *hdr) 638static void nfs_pgio_error(struct nfs_pgio_header *hdr)
@@ -768,8 +766,7 @@ int nfs_generic_pgio(struct nfs_pageio_descriptor *desc,
768 pageused = 0; 766 pageused = 0;
769 while (!list_empty(head)) { 767 while (!list_empty(head)) {
770 req = nfs_list_entry(head->next); 768 req = nfs_list_entry(head->next);
771 nfs_list_remove_request(req); 769 nfs_list_move_request(req, &hdr->pages);
772 nfs_list_add_request(req, &hdr->pages);
773 770
774 if (!last_page || last_page != req->wb_page) { 771 if (!last_page || last_page != req->wb_page) {
775 pageused++; 772 pageused++;
@@ -893,6 +890,7 @@ static bool nfs_match_lock_context(const struct nfs_lock_context *l1,
893 * nfs_can_coalesce_requests - test two requests for compatibility 890 * nfs_can_coalesce_requests - test two requests for compatibility
894 * @prev: pointer to nfs_page 891 * @prev: pointer to nfs_page
895 * @req: pointer to nfs_page 892 * @req: pointer to nfs_page
893 * @pgio: pointer to nfs_pagio_descriptor
896 * 894 *
897 * The nfs_page structures 'prev' and 'req' are compared to ensure that the 895 * The nfs_page structures 'prev' and 'req' are compared to ensure that the
898 * page data area they describe is contiguous, and that their RPC 896 * page data area they describe is contiguous, and that their RPC
@@ -961,8 +959,7 @@ static int nfs_pageio_do_add_request(struct nfs_pageio_descriptor *desc,
961 } 959 }
962 if (!nfs_can_coalesce_requests(prev, req, desc)) 960 if (!nfs_can_coalesce_requests(prev, req, desc))
963 return 0; 961 return 0;
964 nfs_list_remove_request(req); 962 nfs_list_move_request(req, &mirror->pg_list);
965 nfs_list_add_request(req, &mirror->pg_list);
966 mirror->pg_count += req->wb_bytes; 963 mirror->pg_count += req->wb_bytes;
967 return 1; 964 return 1;
968} 965}
@@ -988,6 +985,16 @@ static void nfs_pageio_doio(struct nfs_pageio_descriptor *desc)
988 } 985 }
989} 986}
990 987
988static void
989nfs_pageio_cleanup_request(struct nfs_pageio_descriptor *desc,
990 struct nfs_page *req)
991{
992 LIST_HEAD(head);
993
994 nfs_list_move_request(req, &head);
995 desc->pg_completion_ops->error_cleanup(&head, desc->pg_error);
996}
997
991/** 998/**
992 * nfs_pageio_add_request - Attempt to coalesce a request into a page list. 999 * nfs_pageio_add_request - Attempt to coalesce a request into a page list.
993 * @desc: destination io descriptor 1000 * @desc: destination io descriptor
@@ -1025,10 +1032,8 @@ static int __nfs_pageio_add_request(struct nfs_pageio_descriptor *desc,
1025 nfs_page_group_unlock(req); 1032 nfs_page_group_unlock(req);
1026 desc->pg_moreio = 1; 1033 desc->pg_moreio = 1;
1027 nfs_pageio_doio(desc); 1034 nfs_pageio_doio(desc);
1028 if (desc->pg_error < 0) 1035 if (desc->pg_error < 0 || mirror->pg_recoalesce)
1029 return 0; 1036 goto out_cleanup_subreq;
1030 if (mirror->pg_recoalesce)
1031 return 0;
1032 /* retry add_request for this subreq */ 1037 /* retry add_request for this subreq */
1033 nfs_page_group_lock(req); 1038 nfs_page_group_lock(req);
1034 continue; 1039 continue;
@@ -1061,6 +1066,10 @@ err_ptr:
1061 desc->pg_error = PTR_ERR(subreq); 1066 desc->pg_error = PTR_ERR(subreq);
1062 nfs_page_group_unlock(req); 1067 nfs_page_group_unlock(req);
1063 return 0; 1068 return 0;
1069out_cleanup_subreq:
1070 if (req != subreq)
1071 nfs_pageio_cleanup_request(desc, subreq);
1072 return 0;
1064} 1073}
1065 1074
1066static int nfs_do_recoalesce(struct nfs_pageio_descriptor *desc) 1075static int nfs_do_recoalesce(struct nfs_pageio_descriptor *desc)
@@ -1079,7 +1088,6 @@ static int nfs_do_recoalesce(struct nfs_pageio_descriptor *desc)
1079 struct nfs_page *req; 1088 struct nfs_page *req;
1080 1089
1081 req = list_first_entry(&head, struct nfs_page, wb_list); 1090 req = list_first_entry(&head, struct nfs_page, wb_list);
1082 nfs_list_remove_request(req);
1083 if (__nfs_pageio_add_request(desc, req)) 1091 if (__nfs_pageio_add_request(desc, req))
1084 continue; 1092 continue;
1085 if (desc->pg_error < 0) { 1093 if (desc->pg_error < 0) {
@@ -1120,7 +1128,8 @@ static void nfs_pageio_error_cleanup(struct nfs_pageio_descriptor *desc)
1120 1128
1121 for (midx = 0; midx < desc->pg_mirror_count; midx++) { 1129 for (midx = 0; midx < desc->pg_mirror_count; midx++) {
1122 mirror = &desc->pg_mirrors[midx]; 1130 mirror = &desc->pg_mirrors[midx];
1123 desc->pg_completion_ops->error_cleanup(&mirror->pg_list); 1131 desc->pg_completion_ops->error_cleanup(&mirror->pg_list,
1132 desc->pg_error);
1124 } 1133 }
1125} 1134}
1126 1135
@@ -1168,11 +1177,14 @@ int nfs_pageio_add_request(struct nfs_pageio_descriptor *desc,
1168 if (nfs_pgio_has_mirroring(desc)) 1177 if (nfs_pgio_has_mirroring(desc))
1169 desc->pg_mirror_idx = midx; 1178 desc->pg_mirror_idx = midx;
1170 if (!nfs_pageio_add_request_mirror(desc, dupreq)) 1179 if (!nfs_pageio_add_request_mirror(desc, dupreq))
1171 goto out_failed; 1180 goto out_cleanup_subreq;
1172 } 1181 }
1173 1182
1174 return 1; 1183 return 1;
1175 1184
1185out_cleanup_subreq:
1186 if (req != dupreq)
1187 nfs_pageio_cleanup_request(desc, dupreq);
1176out_failed: 1188out_failed:
1177 nfs_pageio_error_cleanup(desc); 1189 nfs_pageio_error_cleanup(desc);
1178 return 0; 1190 return 0;
@@ -1194,7 +1206,7 @@ static void nfs_pageio_complete_mirror(struct nfs_pageio_descriptor *desc,
1194 desc->pg_mirror_idx = mirror_idx; 1206 desc->pg_mirror_idx = mirror_idx;
1195 for (;;) { 1207 for (;;) {
1196 nfs_pageio_doio(desc); 1208 nfs_pageio_doio(desc);
1197 if (!mirror->pg_recoalesce) 1209 if (desc->pg_error < 0 || !mirror->pg_recoalesce)
1198 break; 1210 break;
1199 if (!nfs_do_recoalesce(desc)) 1211 if (!nfs_do_recoalesce(desc))
1200 break; 1212 break;
@@ -1222,9 +1234,8 @@ int nfs_pageio_resend(struct nfs_pageio_descriptor *desc,
1222 while (!list_empty(&hdr->pages)) { 1234 while (!list_empty(&hdr->pages)) {
1223 struct nfs_page *req = nfs_list_entry(hdr->pages.next); 1235 struct nfs_page *req = nfs_list_entry(hdr->pages.next);
1224 1236
1225 nfs_list_remove_request(req);
1226 if (!nfs_pageio_add_request(desc, req)) 1237 if (!nfs_pageio_add_request(desc, req))
1227 nfs_list_add_request(req, &failed); 1238 nfs_list_move_request(req, &failed);
1228 } 1239 }
1229 nfs_pageio_complete(desc); 1240 nfs_pageio_complete(desc);
1230 if (!list_empty(&failed)) { 1241 if (!list_empty(&failed)) {