aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNick Piggin <npiggin@suse.de>2009-01-06 17:40:25 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-01-06 18:59:09 -0500
commit4f5a99d64c17470a784a6c68064207d82e3e74a5 (patch)
tree2a3e0f0c3990bb8dbda2cdaa506a64180e5cbff2
parente8ea1759138d4279869f52bfb7dca8f02f8ccfe5 (diff)
fs: remove WB_SYNC_HOLD
Remove WB_SYNC_HOLD. The primary motiviation is the design of my anti-starvation code for fsync. It requires taking an inode lock over the sync operation, so we could run into lock ordering problems with multiple inodes. It is possible to take a single global lock to solve the ordering problem, but then that would prevent a future nice implementation of "sync multiple inodes" based on lock order via inode address. Seems like a backward step to remove this, but actually it is busted anyway: we can't use the inode lists for data integrity wait: an inode can be taken off the dirty lists but still be under writeback. In order to satisfy data integrity semantics, we should wait for it to finish writeback, but if we only search the dirty lists, we'll miss it. It would be possible to have a "writeback" list, for sys_sync, I suppose. But why complicate things by prematurely optimise? For unmounting, we could avoid the "livelock avoidance" code, which would be easier, but again premature IMO. Fixing the existing data integrity problem will come next. Signed-off-by: Nick Piggin <npiggin@suse.de> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--fs/fs-writeback.c12
-rw-r--r--include/linux/writeback.h1
2 files changed, 2 insertions, 11 deletions
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index d0ff0b8cf309..d99601af9e48 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -421,9 +421,6 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
421 * If we're a pdlfush thread, then implement pdflush collision avoidance 421 * If we're a pdlfush thread, then implement pdflush collision avoidance
422 * against the entire list. 422 * against the entire list.
423 * 423 *
424 * WB_SYNC_HOLD is a hack for sys_sync(): reattach the inode to sb->s_dirty so
425 * that it can be located for waiting on in __writeback_single_inode().
426 *
427 * If `bdi' is non-zero then we're being asked to writeback a specific queue. 424 * If `bdi' is non-zero then we're being asked to writeback a specific queue.
428 * This function assumes that the blockdev superblock's inodes are backed by 425 * This function assumes that the blockdev superblock's inodes are backed by
429 * a variety of queues, so all inodes are searched. For other superblocks, 426 * a variety of queues, so all inodes are searched. For other superblocks,
@@ -499,10 +496,6 @@ void generic_sync_sb_inodes(struct super_block *sb,
499 __iget(inode); 496 __iget(inode);
500 pages_skipped = wbc->pages_skipped; 497 pages_skipped = wbc->pages_skipped;
501 __writeback_single_inode(inode, wbc); 498 __writeback_single_inode(inode, wbc);
502 if (wbc->sync_mode == WB_SYNC_HOLD) {
503 inode->dirtied_when = jiffies;
504 list_move(&inode->i_list, &sb->s_dirty);
505 }
506 if (current_is_pdflush()) 499 if (current_is_pdflush())
507 writeback_release(bdi); 500 writeback_release(bdi);
508 if (wbc->pages_skipped != pages_skipped) { 501 if (wbc->pages_skipped != pages_skipped) {
@@ -588,8 +581,7 @@ restart:
588 581
589/* 582/*
590 * writeback and wait upon the filesystem's dirty inodes. The caller will 583 * writeback and wait upon the filesystem's dirty inodes. The caller will
591 * do this in two passes - one to write, and one to wait. WB_SYNC_HOLD is 584 * do this in two passes - one to write, and one to wait.
592 * used to park the written inodes on sb->s_dirty for the wait pass.
593 * 585 *
594 * A finite limit is set on the number of pages which will be written. 586 * A finite limit is set on the number of pages which will be written.
595 * To prevent infinite livelock of sys_sync(). 587 * To prevent infinite livelock of sys_sync().
@@ -600,7 +592,7 @@ restart:
600void sync_inodes_sb(struct super_block *sb, int wait) 592void sync_inodes_sb(struct super_block *sb, int wait)
601{ 593{
602 struct writeback_control wbc = { 594 struct writeback_control wbc = {
603 .sync_mode = wait ? WB_SYNC_ALL : WB_SYNC_HOLD, 595 .sync_mode = wait ? WB_SYNC_ALL : WB_SYNC_NONE,
604 .range_start = 0, 596 .range_start = 0,
605 .range_end = LLONG_MAX, 597 .range_end = LLONG_MAX,
606 }; 598 };
diff --git a/include/linux/writeback.h b/include/linux/writeback.h
index bb28c975c1d7..7300ecdc480c 100644
--- a/include/linux/writeback.h
+++ b/include/linux/writeback.h
@@ -30,7 +30,6 @@ static inline int task_is_pdflush(struct task_struct *task)
30enum writeback_sync_modes { 30enum writeback_sync_modes {
31 WB_SYNC_NONE, /* Don't wait on anything */ 31 WB_SYNC_NONE, /* Don't wait on anything */
32 WB_SYNC_ALL, /* Wait on every mapping */ 32 WB_SYNC_ALL, /* Wait on every mapping */
33 WB_SYNC_HOLD, /* Hold the inode on sb_dirty for sys_sync() */
34}; 33};
35 34
36/* 35/*