aboutsummaryrefslogtreecommitdiffstats
path: root/mm/page-writeback.c
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2010-06-08 20:37:18 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-06-08 21:12:44 -0400
commit0b5649278e39a068aaf91399941bab1b4a4a3cc2 (patch)
tree3fd2c782385137f5b135c07149de772e207fdaf8 /mm/page-writeback.c
parent8d7458daea2a6809d32418bf489b949d23de99ea (diff)
writeback: pay attention to wbc->nr_to_write in write_cache_pages
If a filesystem writes more than one page in ->writepage, write_cache_pages fails to notice this and continues to attempt writeback when wbc->nr_to_write has gone negative - this trace was captured from XFS: wbc_writeback_start: towrt=1024 wbc_writepage: towrt=1024 wbc_writepage: towrt=0 wbc_writepage: towrt=-1 wbc_writepage: towrt=-5 wbc_writepage: towrt=-21 wbc_writepage: towrt=-85 This has adverse effects on filesystem writeback behaviour. write_cache_pages() needs to terminate after a certain number of pages are written, not after a certain number of calls to ->writepage are made. This is a regression introduced by 17bc6c30cf6bfffd816bdc53682dd46fc34a2cf4 ("vfs: Add no_nrwrite_index_update writeback control flag"), but cannot be reverted directly due to subsequent bug fixes that have gone in on top of it. Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/page-writeback.c')
-rw-r--r--mm/page-writeback.c15
1 files changed, 5 insertions, 10 deletions
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index 5fa63bdf52e4..b3dbb8040ed5 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -835,7 +835,6 @@ int write_cache_pages(struct address_space *mapping,
835 pgoff_t done_index; 835 pgoff_t done_index;
836 int cycled; 836 int cycled;
837 int range_whole = 0; 837 int range_whole = 0;
838 long nr_to_write = wbc->nr_to_write;
839 838
840 pagevec_init(&pvec, 0); 839 pagevec_init(&pvec, 0);
841 if (wbc->range_cyclic) { 840 if (wbc->range_cyclic) {
@@ -935,11 +934,10 @@ continue_unlock:
935 done = 1; 934 done = 1;
936 break; 935 break;
937 } 936 }
938 } 937 }
939 938
940 if (nr_to_write > 0) { 939 if (wbc->nr_to_write > 0) {
941 nr_to_write--; 940 if (--wbc->nr_to_write == 0 &&
942 if (nr_to_write == 0 &&
943 wbc->sync_mode == WB_SYNC_NONE) { 941 wbc->sync_mode == WB_SYNC_NONE) {
944 /* 942 /*
945 * We stop writing back only if we are 943 * We stop writing back only if we are
@@ -970,11 +968,8 @@ continue_unlock:
970 end = writeback_index - 1; 968 end = writeback_index - 1;
971 goto retry; 969 goto retry;
972 } 970 }
973 if (!wbc->no_nrwrite_index_update) { 971 if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0))
974 if (wbc->range_cyclic || (range_whole && nr_to_write > 0)) 972 mapping->writeback_index = done_index;
975 mapping->writeback_index = done_index;
976 wbc->nr_to_write = nr_to_write;
977 }
978 973
979 return ret; 974 return ret;
980} 975}