aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorAndrew Morton <akpm@linux-foundation.org>2007-10-17 02:30:34 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-17 11:43:02 -0400
commitf57b9b7b4f68e1723ca99381dc10c8bc07d6df14 (patch)
tree2d622e2878b86d74a9c2d0cff3d1261c55864abf /fs
parent9852a0e76cd9c89e71f84e784212fdd7a97ae93a (diff)
writeback: fix time ordering of the per superblock dirty inode lists 3
While writeback is working against a dirty inode it does a check after trying to write some of the inode's pages: "did the lower layers skip some of the inode's dirty pages because they were locked (or under writeback, or whatever)" If this turns out to be true, we must move the inode back onto s_dirty and redirty it. The reason for doing this is that fsync() and friends only check the s_dirty list, and those functions want to know about those pages which were locked, so they can be waited upon and, if necessary, rewritten. Problem is, that redirtying was putting the inode onto the tail of s_dirty without updating its timestamp. This causes a violation of s_dirty ordering. Fix this by updating inode->dirtied_when when moving the inode onto s_dirty. But the code is still a bit buggy? If the inode was _already_ dirty then we don't need to move it at all. Oh well, hopefully it doesn't matter too much, as that was a redirtying, which was very recent anwyay. Cc: Mike Waychison <mikew@google.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/fs-writeback.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
index f8618e0bb62b..66889b06d00f 100644
--- a/fs/fs-writeback.c
+++ b/fs/fs-writeback.c
@@ -413,7 +413,7 @@ sync_sb_inodes(struct super_block *sb, struct writeback_control *wbc)
413 * writeback is not making progress due to locked 413 * writeback is not making progress due to locked
414 * buffers. Skip this inode for now. 414 * buffers. Skip this inode for now.
415 */ 415 */
416 list_move(&inode->i_list, &sb->s_dirty); 416 redirty_tail(inode);
417 } 417 }
418 spin_unlock(&inode_lock); 418 spin_unlock(&inode_lock);
419 iput(inode); 419 iput(inode);