aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2010-10-24 13:40:46 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2010-10-25 21:26:16 -0400
commit9843b76aae80293f5b5a0e275360627508595ce5 (patch)
tree522fc7b8435d13e2a6c329d93a597173ce6956a7
parenta031878670ac8fe466859d4c1506bd91ae48678c (diff)
fs: skip I_FREEING inodes in writeback_sb_inodes
Skip I_FREEING inodes just like I_WILL_FREE and I_NEW when walking the writeback lists. Currenly this can't happen, but once we move from inode_lock to more fine grained locking we can have an inode that's still on the writeback lists but has I_FREEING set, and we absolutely need to skip it here, just like we do for all other inode list walks. Based on a patch from Dave Chinner. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r--fs/fs-writeback.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index 7a24cc957f05..f6af81add459 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -487,10 +487,16 @@ static int writeback_sb_inodes(struct super_block *sb, struct bdi_writeback *wb,
487 return 0; 487 return 0;
488 } 488 }
489 489
490 if (inode->i_state & (I_NEW | I_WILL_FREE)) { 490 /*
491 * Don't bother with new inodes or inodes beeing freed, first
492 * kind does not need peridic writeout yet, and for the latter
493 * kind writeout is handled by the freer.
494 */
495 if (inode->i_state & (I_NEW | I_FREEING | I_WILL_FREE)) {
491 requeue_io(inode); 496 requeue_io(inode);
492 continue; 497 continue;
493 } 498 }
499
494 /* 500 /*
495 * Was this inode dirtied after sync_sb_inodes was called? 501 * Was this inode dirtied after sync_sb_inodes was called?
496 * This keeps sync from extra jobs and livelock. 502 * This keeps sync from extra jobs and livelock.
@@ -498,7 +504,6 @@ static int writeback_sb_inodes(struct super_block *sb, struct bdi_writeback *wb,
498 if (inode_dirtied_after(inode, wbc->wb_start)) 504 if (inode_dirtied_after(inode, wbc->wb_start))
499 return 1; 505 return 1;
500 506
501 BUG_ON(inode->i_state & I_FREEING);
502 __iget(inode); 507 __iget(inode);
503 pages_skipped = wbc->pages_skipped; 508 pages_skipped = wbc->pages_skipped;
504 writeback_single_inode(inode, wbc); 509 writeback_single_inode(inode, wbc);