diff options
-rw-r--r-- | fs/ext4/inode.c | 4 | ||||
-rw-r--r-- | fs/fs-writeback.c | 17 | ||||
-rw-r--r-- | include/linux/writeback.h | 1 | ||||
-rw-r--r-- | mm/page-writeback.c | 4 |
4 files changed, 14 insertions, 12 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index a5763e3505ba..8558b6c3450a 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -2741,7 +2741,7 @@ static int write_cache_pages_da(struct address_space *mapping, | |||
2741 | index = wbc->range_start >> PAGE_CACHE_SHIFT; | 2741 | index = wbc->range_start >> PAGE_CACHE_SHIFT; |
2742 | end = wbc->range_end >> PAGE_CACHE_SHIFT; | 2742 | end = wbc->range_end >> PAGE_CACHE_SHIFT; |
2743 | 2743 | ||
2744 | if (wbc->sync_mode == WB_SYNC_ALL) | 2744 | if (wbc->sync_mode == WB_SYNC_ALL || wbc->tagged_writepages) |
2745 | tag = PAGECACHE_TAG_TOWRITE; | 2745 | tag = PAGECACHE_TAG_TOWRITE; |
2746 | else | 2746 | else |
2747 | tag = PAGECACHE_TAG_DIRTY; | 2747 | tag = PAGECACHE_TAG_DIRTY; |
@@ -2973,7 +2973,7 @@ static int ext4_da_writepages(struct address_space *mapping, | |||
2973 | } | 2973 | } |
2974 | 2974 | ||
2975 | retry: | 2975 | retry: |
2976 | if (wbc->sync_mode == WB_SYNC_ALL) | 2976 | if (wbc->sync_mode == WB_SYNC_ALL || wbc->tagged_writepages) |
2977 | tag_pages_for_writeback(mapping, index, end); | 2977 | tag_pages_for_writeback(mapping, index, end); |
2978 | 2978 | ||
2979 | while (!ret && wbc->nr_to_write > 0) { | 2979 | while (!ret && wbc->nr_to_write > 0) { |
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index 0f015a0468de..5ed2ce9a28d0 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c | |||
@@ -36,6 +36,7 @@ struct wb_writeback_work { | |||
36 | long nr_pages; | 36 | long nr_pages; |
37 | struct super_block *sb; | 37 | struct super_block *sb; |
38 | enum writeback_sync_modes sync_mode; | 38 | enum writeback_sync_modes sync_mode; |
39 | unsigned int tagged_writepages:1; | ||
39 | unsigned int for_kupdate:1; | 40 | unsigned int for_kupdate:1; |
40 | unsigned int range_cyclic:1; | 41 | unsigned int range_cyclic:1; |
41 | unsigned int for_background:1; | 42 | unsigned int for_background:1; |
@@ -650,6 +651,7 @@ static long wb_writeback(struct bdi_writeback *wb, | |||
650 | { | 651 | { |
651 | struct writeback_control wbc = { | 652 | struct writeback_control wbc = { |
652 | .sync_mode = work->sync_mode, | 653 | .sync_mode = work->sync_mode, |
654 | .tagged_writepages = work->tagged_writepages, | ||
653 | .older_than_this = NULL, | 655 | .older_than_this = NULL, |
654 | .for_kupdate = work->for_kupdate, | 656 | .for_kupdate = work->for_kupdate, |
655 | .for_background = work->for_background, | 657 | .for_background = work->for_background, |
@@ -657,7 +659,7 @@ static long wb_writeback(struct bdi_writeback *wb, | |||
657 | }; | 659 | }; |
658 | unsigned long oldest_jif; | 660 | unsigned long oldest_jif; |
659 | long wrote = 0; | 661 | long wrote = 0; |
660 | long write_chunk; | 662 | long write_chunk = MAX_WRITEBACK_PAGES; |
661 | struct inode *inode; | 663 | struct inode *inode; |
662 | 664 | ||
663 | if (wbc.for_kupdate) { | 665 | if (wbc.for_kupdate) { |
@@ -683,9 +685,7 @@ static long wb_writeback(struct bdi_writeback *wb, | |||
683 | * (quickly) tag currently dirty pages | 685 | * (quickly) tag currently dirty pages |
684 | * (maybe slowly) sync all tagged pages | 686 | * (maybe slowly) sync all tagged pages |
685 | */ | 687 | */ |
686 | if (wbc.sync_mode == WB_SYNC_NONE) | 688 | if (wbc.sync_mode == WB_SYNC_ALL || wbc.tagged_writepages) |
687 | write_chunk = MAX_WRITEBACK_PAGES; | ||
688 | else | ||
689 | write_chunk = LONG_MAX; | 689 | write_chunk = LONG_MAX; |
690 | 690 | ||
691 | wbc.wb_start = jiffies; /* livelock avoidance */ | 691 | wbc.wb_start = jiffies; /* livelock avoidance */ |
@@ -1188,10 +1188,11 @@ void writeback_inodes_sb_nr(struct super_block *sb, unsigned long nr) | |||
1188 | { | 1188 | { |
1189 | DECLARE_COMPLETION_ONSTACK(done); | 1189 | DECLARE_COMPLETION_ONSTACK(done); |
1190 | struct wb_writeback_work work = { | 1190 | struct wb_writeback_work work = { |
1191 | .sb = sb, | 1191 | .sb = sb, |
1192 | .sync_mode = WB_SYNC_NONE, | 1192 | .sync_mode = WB_SYNC_NONE, |
1193 | .done = &done, | 1193 | .tagged_writepages = 1, |
1194 | .nr_pages = nr, | 1194 | .done = &done, |
1195 | .nr_pages = nr, | ||
1195 | }; | 1196 | }; |
1196 | 1197 | ||
1197 | WARN_ON(!rwsem_is_locked(&sb->s_umount)); | 1198 | WARN_ON(!rwsem_is_locked(&sb->s_umount)); |
diff --git a/include/linux/writeback.h b/include/linux/writeback.h index 17e7ccc322a5..3f6542ca6198 100644 --- a/include/linux/writeback.h +++ b/include/linux/writeback.h | |||
@@ -47,6 +47,7 @@ struct writeback_control { | |||
47 | unsigned encountered_congestion:1; /* An output: a queue is full */ | 47 | unsigned encountered_congestion:1; /* An output: a queue is full */ |
48 | unsigned for_kupdate:1; /* A kupdate writeback */ | 48 | unsigned for_kupdate:1; /* A kupdate writeback */ |
49 | unsigned for_background:1; /* A background writeback */ | 49 | unsigned for_background:1; /* A background writeback */ |
50 | unsigned tagged_writepages:1; /* tag-and-write to avoid livelock */ | ||
50 | unsigned for_reclaim:1; /* Invoked from the page allocator */ | 51 | unsigned for_reclaim:1; /* Invoked from the page allocator */ |
51 | unsigned range_cyclic:1; /* range_start is cyclic */ | 52 | unsigned range_cyclic:1; /* range_start is cyclic */ |
52 | unsigned more_io:1; /* more io to be dispatched */ | 53 | unsigned more_io:1; /* more io to be dispatched */ |
diff --git a/mm/page-writeback.c b/mm/page-writeback.c index 31f698862420..955fe35d01e0 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c | |||
@@ -892,12 +892,12 @@ int write_cache_pages(struct address_space *mapping, | |||
892 | range_whole = 1; | 892 | range_whole = 1; |
893 | cycled = 1; /* ignore range_cyclic tests */ | 893 | cycled = 1; /* ignore range_cyclic tests */ |
894 | } | 894 | } |
895 | if (wbc->sync_mode == WB_SYNC_ALL) | 895 | if (wbc->sync_mode == WB_SYNC_ALL || wbc->tagged_writepages) |
896 | tag = PAGECACHE_TAG_TOWRITE; | 896 | tag = PAGECACHE_TAG_TOWRITE; |
897 | else | 897 | else |
898 | tag = PAGECACHE_TAG_DIRTY; | 898 | tag = PAGECACHE_TAG_DIRTY; |
899 | retry: | 899 | retry: |
900 | if (wbc->sync_mode == WB_SYNC_ALL) | 900 | if (wbc->sync_mode == WB_SYNC_ALL || wbc->tagged_writepages) |
901 | tag_pages_for_writeback(mapping, index, end); | 901 | tag_pages_for_writeback(mapping, index, end); |
902 | done_index = index; | 902 | done_index = index; |
903 | while (!done && (index <= end)) { | 903 | while (!done && (index <= end)) { |