aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorMiklos Szeredi <miklos@szeredi.hu>2004-07-16 04:44:49 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2004-07-16 04:44:49 -0700
commitf044bba32770c258f7baacde36dd0e1fa84b7120 (patch)
treee27d9a69226373a2f2976e989b5047e2c3ba2eb3 /fs
parent5cea9705bcc0fb3592e9a856d22aa57841264765 (diff)
downloadhistory-f044bba32770c258f7baacde36dd0e1fa84b7120.tar.gz
[PATCH] fix inode state incoherency
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 <miklos@szeredi.hu> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/fs-writeback.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index 2aac26e9f1beee..430afc37dec4ca 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -213,8 +213,9 @@ __sync_single_inode(struct inode *inode, struct writeback_control *wbc)
} 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