Skip to content

Commit

Permalink
fs: remove WB_SYNC_HOLD
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Nick Piggin authored and torvalds committed Jan 6, 2009
1 parent e8ea175 commit 4f5a99d
Show file tree
Hide file tree
Showing 2 changed files with 2 additions and 11 deletions.
12 changes: 2 additions & 10 deletions fs/fs-writeback.c
Original file line number Diff line number Diff line change
Expand Up @@ -421,9 +421,6 @@ __writeback_single_inode(struct inode *inode, struct writeback_control *wbc)
* If we're a pdlfush thread, then implement pdflush collision avoidance
* against the entire list.
*
* WB_SYNC_HOLD is a hack for sys_sync(): reattach the inode to sb->s_dirty so
* that it can be located for waiting on in __writeback_single_inode().
*
* If `bdi' is non-zero then we're being asked to writeback a specific queue.
* This function assumes that the blockdev superblock's inodes are backed by
* a variety of queues, so all inodes are searched. For other superblocks,
Expand Down Expand Up @@ -499,10 +496,6 @@ void generic_sync_sb_inodes(struct super_block *sb,
__iget(inode);
pages_skipped = wbc->pages_skipped;
__writeback_single_inode(inode, wbc);
if (wbc->sync_mode == WB_SYNC_HOLD) {
inode->dirtied_when = jiffies;
list_move(&inode->i_list, &sb->s_dirty);
}
if (current_is_pdflush())
writeback_release(bdi);
if (wbc->pages_skipped != pages_skipped) {
Expand Down Expand Up @@ -588,8 +581,7 @@ writeback_inodes(struct writeback_control *wbc)

/*
* writeback and wait upon the filesystem's dirty inodes. The caller will
* do this in two passes - one to write, and one to wait. WB_SYNC_HOLD is
* used to park the written inodes on sb->s_dirty for the wait pass.
* do this in two passes - one to write, and one to wait.
*
* A finite limit is set on the number of pages which will be written.
* To prevent infinite livelock of sys_sync().
Expand All @@ -600,7 +592,7 @@ writeback_inodes(struct writeback_control *wbc)
void sync_inodes_sb(struct super_block *sb, int wait)
{
struct writeback_control wbc = {
.sync_mode = wait ? WB_SYNC_ALL : WB_SYNC_HOLD,
.sync_mode = wait ? WB_SYNC_ALL : WB_SYNC_NONE,
.range_start = 0,
.range_end = LLONG_MAX,
};
Expand Down
1 change: 0 additions & 1 deletion include/linux/writeback.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ static inline int task_is_pdflush(struct task_struct *task)
enum writeback_sync_modes {
WB_SYNC_NONE, /* Don't wait on anything */
WB_SYNC_ALL, /* Wait on every mapping */
WB_SYNC_HOLD, /* Hold the inode on sb_dirty for sys_sync() */
};

/*
Expand Down

0 comments on commit 4f5a99d

Please sign in to comment.