aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fs-writeback.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-11-13 01:45:43 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-11-13 01:45:43 -0500
commit5cbb3d216e2041700231bcfc383ee5f8b7fc8b74 (patch)
treea738fa82dbcefa9bd283c08bc67f38827be63937 /fs/fs-writeback.c
parent9bc9ccd7db1c9f043f75380b5a5b94912046a60e (diff)
parent4e9b45a19241354daec281d7a785739829b52359 (diff)
Merge branch 'akpm' (patches from Andrew Morton)
Merge first patch-bomb from Andrew Morton: "Quite a lot of other stuff is banked up awaiting further next->mainline merging, but this batch contains: - Lots of random misc patches - OCFS2 - Most of MM - backlight updates - lib/ updates - printk updates - checkpatch updates - epoll tweaking - rtc updates - hfs - hfsplus - documentation - procfs - update gcov to gcc-4.7 format - IPC" * emailed patches from Andrew Morton <akpm@linux-foundation.org>: (269 commits) ipc, msg: fix message length check for negative values ipc/util.c: remove unnecessary work pending test devpts: plug the memory leak in kill_sb ./Makefile: export initial ramdisk compression config option init/Kconfig: add option to disable kernel compression drivers: w1: make w1_slave::flags long to avoid memory corruption drivers/w1/masters/ds1wm.cuse dev_get_platdata() drivers/memstick/core/ms_block.c: fix unreachable state in h_msb_read_page() drivers/memstick/core/mspro_block.c: fix attributes array allocation drivers/pps/clients/pps-gpio.c: remove redundant of_match_ptr kernel/panic.c: reduce 1 byte usage for print tainted buffer gcov: reuse kbasename helper kernel/gcov/fs.c: use pr_warn() kernel/module.c: use pr_foo() gcov: compile specific gcov implementation based on gcc version gcov: add support for gcc 4.7 gcov format gcov: move gcov structs definitions to a gcc version specific file kernel/taskstats.c: return -ENOMEM when alloc memory fails in add_del_listener() kernel/taskstats.c: add nla_nest_cancel() for failure processing between nla_nest_start() and nla_nest_end() kernel/sysctl_binary.c: use scnprintf() instead of snprintf() ...
Diffstat (limited to 'fs/fs-writeback.c')
-rw-r--r--fs/fs-writeback.c33
1 files changed, 22 insertions, 11 deletions
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index 09c11329a17c..1f4a10ece2f1 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -40,13 +40,18 @@
40struct wb_writeback_work { 40struct wb_writeback_work {
41 long nr_pages; 41 long nr_pages;
42 struct super_block *sb; 42 struct super_block *sb;
43 unsigned long *older_than_this; 43 /*
44 * Write only inodes dirtied before this time. Don't forget to set
45 * older_than_this_is_set when you set this.
46 */
47 unsigned long older_than_this;
44 enum writeback_sync_modes sync_mode; 48 enum writeback_sync_modes sync_mode;
45 unsigned int tagged_writepages:1; 49 unsigned int tagged_writepages:1;
46 unsigned int for_kupdate:1; 50 unsigned int for_kupdate:1;
47 unsigned int range_cyclic:1; 51 unsigned int range_cyclic:1;
48 unsigned int for_background:1; 52 unsigned int for_background:1;
49 unsigned int for_sync:1; /* sync(2) WB_SYNC_ALL writeback */ 53 unsigned int for_sync:1; /* sync(2) WB_SYNC_ALL writeback */
54 unsigned int older_than_this_is_set:1;
50 enum wb_reason reason; /* why was writeback initiated? */ 55 enum wb_reason reason; /* why was writeback initiated? */
51 56
52 struct list_head list; /* pending work list */ 57 struct list_head list; /* pending work list */
@@ -247,10 +252,10 @@ static int move_expired_inodes(struct list_head *delaying_queue,
247 int do_sb_sort = 0; 252 int do_sb_sort = 0;
248 int moved = 0; 253 int moved = 0;
249 254
255 WARN_ON_ONCE(!work->older_than_this_is_set);
250 while (!list_empty(delaying_queue)) { 256 while (!list_empty(delaying_queue)) {
251 inode = wb_inode(delaying_queue->prev); 257 inode = wb_inode(delaying_queue->prev);
252 if (work->older_than_this && 258 if (inode_dirtied_after(inode, work->older_than_this))
253 inode_dirtied_after(inode, *work->older_than_this))
254 break; 259 break;
255 list_move(&inode->i_wb_list, &tmp); 260 list_move(&inode->i_wb_list, &tmp);
256 moved++; 261 moved++;
@@ -734,6 +739,8 @@ static long writeback_inodes_wb(struct bdi_writeback *wb, long nr_pages,
734 .sync_mode = WB_SYNC_NONE, 739 .sync_mode = WB_SYNC_NONE,
735 .range_cyclic = 1, 740 .range_cyclic = 1,
736 .reason = reason, 741 .reason = reason,
742 .older_than_this = jiffies,
743 .older_than_this_is_set = 1,
737 }; 744 };
738 745
739 spin_lock(&wb->list_lock); 746 spin_lock(&wb->list_lock);
@@ -792,12 +799,13 @@ static long wb_writeback(struct bdi_writeback *wb,
792{ 799{
793 unsigned long wb_start = jiffies; 800 unsigned long wb_start = jiffies;
794 long nr_pages = work->nr_pages; 801 long nr_pages = work->nr_pages;
795 unsigned long oldest_jif;
796 struct inode *inode; 802 struct inode *inode;
797 long progress; 803 long progress;
798 804
799 oldest_jif = jiffies; 805 if (!work->older_than_this_is_set) {
800 work->older_than_this = &oldest_jif; 806 work->older_than_this = jiffies;
807 work->older_than_this_is_set = 1;
808 }
801 809
802 spin_lock(&wb->list_lock); 810 spin_lock(&wb->list_lock);
803 for (;;) { 811 for (;;) {
@@ -831,10 +839,10 @@ static long wb_writeback(struct bdi_writeback *wb,
831 * safe. 839 * safe.
832 */ 840 */
833 if (work->for_kupdate) { 841 if (work->for_kupdate) {
834 oldest_jif = jiffies - 842 work->older_than_this = jiffies -
835 msecs_to_jiffies(dirty_expire_interval * 10); 843 msecs_to_jiffies(dirty_expire_interval * 10);
836 } else if (work->for_background) 844 } else if (work->for_background)
837 oldest_jif = jiffies; 845 work->older_than_this = jiffies;
838 846
839 trace_writeback_start(wb->bdi, work); 847 trace_writeback_start(wb->bdi, work);
840 if (list_empty(&wb->b_io)) 848 if (list_empty(&wb->b_io))
@@ -1346,18 +1354,21 @@ EXPORT_SYMBOL(try_to_writeback_inodes_sb);
1346 1354
1347/** 1355/**
1348 * sync_inodes_sb - sync sb inode pages 1356 * sync_inodes_sb - sync sb inode pages
1349 * @sb: the superblock 1357 * @sb: the superblock
1358 * @older_than_this: timestamp
1350 * 1359 *
1351 * This function writes and waits on any dirty inode belonging to this 1360 * This function writes and waits on any dirty inode belonging to this
1352 * super_block. 1361 * superblock that has been dirtied before given timestamp.
1353 */ 1362 */
1354void sync_inodes_sb(struct super_block *sb) 1363void sync_inodes_sb(struct super_block *sb, unsigned long older_than_this)
1355{ 1364{
1356 DECLARE_COMPLETION_ONSTACK(done); 1365 DECLARE_COMPLETION_ONSTACK(done);
1357 struct wb_writeback_work work = { 1366 struct wb_writeback_work work = {
1358 .sb = sb, 1367 .sb = sb,
1359 .sync_mode = WB_SYNC_ALL, 1368 .sync_mode = WB_SYNC_ALL,
1360 .nr_pages = LONG_MAX, 1369 .nr_pages = LONG_MAX,
1370 .older_than_this = older_than_this,
1371 .older_than_this_is_set = 1,
1361 .range_cyclic = 0, 1372 .range_cyclic = 0,
1362 .done = &done, 1373 .done = &done,
1363 .reason = WB_REASON_SYNC, 1374 .reason = WB_REASON_SYNC,