diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-11-13 01:45:43 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-11-13 01:45:43 -0500 |
commit | 5cbb3d216e2041700231bcfc383ee5f8b7fc8b74 (patch) | |
tree | a738fa82dbcefa9bd283c08bc67f38827be63937 /fs/fs-writeback.c | |
parent | 9bc9ccd7db1c9f043f75380b5a5b94912046a60e (diff) | |
parent | 4e9b45a19241354daec281d7a785739829b52359 (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.c | 33 |
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 @@ | |||
40 | struct wb_writeback_work { | 40 | struct 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 | */ |
1354 | void sync_inodes_sb(struct super_block *sb) | 1363 | void 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, |