diff options
Diffstat (limited to 'mm/page-writeback.c')
-rw-r--r-- | mm/page-writeback.c | 34 |
1 files changed, 22 insertions, 12 deletions
diff --git a/mm/page-writeback.c b/mm/page-writeback.c index 5edca676e2c3..c3fb38b1ea43 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c | |||
@@ -899,11 +899,14 @@ int write_cache_pages(struct address_space *mapping, | |||
899 | } | 899 | } |
900 | retry: | 900 | retry: |
901 | done_index = index; | 901 | done_index = index; |
902 | while (!done && (index <= end) && | 902 | while (!done && (index <= end)) { |
903 | (nr_pages = pagevec_lookup_tag(&pvec, mapping, &index, | 903 | int i; |
904 | PAGECACHE_TAG_DIRTY, | 904 | |
905 | min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1))) { | 905 | nr_pages = pagevec_lookup_tag(&pvec, mapping, &index, |
906 | unsigned i; | 906 | PAGECACHE_TAG_DIRTY, |
907 | min(end - index, (pgoff_t)PAGEVEC_SIZE-1) + 1); | ||
908 | if (nr_pages == 0) | ||
909 | break; | ||
907 | 910 | ||
908 | for (i = 0; i < nr_pages; i++) { | 911 | for (i = 0; i < nr_pages; i++) { |
909 | struct page *page = pvec.pages[i]; | 912 | struct page *page = pvec.pages[i]; |
@@ -919,7 +922,16 @@ retry: | |||
919 | */ | 922 | */ |
920 | lock_page(page); | 923 | lock_page(page); |
921 | 924 | ||
925 | /* | ||
926 | * Page truncated or invalidated. We can freely skip it | ||
927 | * then, even for data integrity operations: the page | ||
928 | * has disappeared concurrently, so there could be no | ||
929 | * real expectation of this data interity operation | ||
930 | * even if there is now a new, dirty page at the same | ||
931 | * pagecache address. | ||
932 | */ | ||
922 | if (unlikely(page->mapping != mapping)) { | 933 | if (unlikely(page->mapping != mapping)) { |
934 | continue_unlock: | ||
923 | unlock_page(page); | 935 | unlock_page(page); |
924 | continue; | 936 | continue; |
925 | } | 937 | } |
@@ -930,18 +942,15 @@ retry: | |||
930 | * end == -1 in that case. | 942 | * end == -1 in that case. |
931 | */ | 943 | */ |
932 | done = 1; | 944 | done = 1; |
933 | unlock_page(page); | 945 | goto continue_unlock; |
934 | continue; | ||
935 | } | 946 | } |
936 | 947 | ||
937 | if (wbc->sync_mode != WB_SYNC_NONE) | 948 | if (wbc->sync_mode != WB_SYNC_NONE) |
938 | wait_on_page_writeback(page); | 949 | wait_on_page_writeback(page); |
939 | 950 | ||
940 | if (PageWriteback(page) || | 951 | if (PageWriteback(page) || |
941 | !clear_page_dirty_for_io(page)) { | 952 | !clear_page_dirty_for_io(page)) |
942 | unlock_page(page); | 953 | goto continue_unlock; |
943 | continue; | ||
944 | } | ||
945 | 954 | ||
946 | ret = (*writepage)(page, wbc, data); | 955 | ret = (*writepage)(page, wbc, data); |
947 | if (unlikely(ret)) { | 956 | if (unlikely(ret)) { |
@@ -964,7 +973,8 @@ retry: | |||
964 | } | 973 | } |
965 | 974 | ||
966 | if (wbc->sync_mode == WB_SYNC_NONE) { | 975 | if (wbc->sync_mode == WB_SYNC_NONE) { |
967 | if (--wbc->nr_to_write <= 0) | 976 | wbc->nr_to_write--; |
977 | if (wbc->nr_to_write <= 0) | ||
968 | done = 1; | 978 | done = 1; |
969 | } | 979 | } |
970 | if (wbc->nonblocking && bdi_write_congested(bdi)) { | 980 | if (wbc->nonblocking && bdi_write_congested(bdi)) { |