aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ext4/inode.c4
-rw-r--r--fs/fs-writeback.c17
-rw-r--r--include/linux/writeback.h1
-rw-r--r--mm/page-writeback.c4
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
2975retry: 2975retry:
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;
899retry: 899retry:
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)) {