From: Miklos Szeredi This patch fixes a hard-to-trigger condition, where the inode is on the inode_in_use list while it's state is dirty. In this state dirty pages are not written back in sync() or from kupdate, only from direct page reclaim. And this causes a livelock in balance_dirty_pages after a while. The actual sequence of events required to get into this state is: thread function inode state inode list ---------------------------------------------------------------------------- 1 __sync_single_inode (background) I_DIRTY sb->s_io 1 do_writepages ... I_LOCKED 2 __writeback_single_inode (sync) sleeps I_LOCKED 1 __sync_single_inode (background) finish 0 inode_in_use 2 __writeback_single_inode (sync) wakeup 0 2 __sync_single_inode (sync) 0 2 do_writepages ... I_LOCKED 3 __mark_inode_dirty I_LOCKED | I_DIRTY 2 __sync_single_inode (sync) finish I_DIRTY left on inode_in_use Signed-off-by: Miklos Szeredi Signed-off-by: Andrew Morton --- 25-akpm/fs/fs-writeback.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletion(-) diff -puN fs/fs-writeback.c~fix-inode-state-corruption-268-rc1-bk1 fs/fs-writeback.c --- 25/fs/fs-writeback.c~fix-inode-state-corruption-268-rc1-bk1 2004-07-13 11:57:58.420264216 -0700 +++ 25-akpm/fs/fs-writeback.c 2004-07-13 11:58:21.337780224 -0700 @@ -213,8 +213,9 @@ __sync_single_inode(struct inode *inode, } else if (inode->i_state & I_DIRTY) { /* * Someone redirtied the inode while were writing back - * the pages: nothing to do. + * the pages. */ + list_move(&inode->i_list, &sb->s_dirty); } else if (atomic_read(&inode->i_count)) { /* * The inode is clean, inuse _