aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOGAWA Hirofumi <hirofumi@mail.parknet.co.jp>2012-12-31 03:24:33 +0900
committerDaniel Phillips <daniel@tux3.org>2012-12-31 03:24:33 +0900
commit162f6bf912022a9cf56cdf64ba1c1d1ca049ac8a (patch)
treef1ea0604c6360518c6c3e7e46aebaee5763e4f97
parentc8eba0329deed0dd7a1cb3235cb80936e85198a2 (diff)
downloadlinux-tux3-162f6bf912022a9cf56cdf64ba1c1d1ca049ac8a.tar.gz
tux3: Fix cleanup_dirty_for_umount() for volmap
volmap inode can be dirtied by rollup buffer via mark_buffer_dirty(). It dirty ->i_state as I_DIRTY_PAGES, without changing tuxnode->flags. FIXME: we would not want to set I_DIRTY_PAGES for rollup buffes. Because we don't use dirty flags of inode, and we just check the list of dirty buffers in do_commit() without checking I_DIRTY flags. So, we would be better to clear I_DIRTY_PAGES on umount path(). This adds the comments for this, and fixes umount path. Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
-rw-r--r--fs/tux3/inode.c7
-rw-r--r--fs/tux3/super.c16
-rw-r--r--fs/tux3/writeback.c5
3 files changed, 24 insertions, 4 deletions
diff --git a/fs/tux3/inode.c b/fs/tux3/inode.c
index ca46883fd9283e..fdf43a87507bfb 100644
--- a/fs/tux3/inode.c
+++ b/fs/tux3/inode.c
@@ -616,7 +616,12 @@ int tux3_drop_inode(struct inode *inode)
if (inode->i_state & I_DIRTY) {
#ifdef __KERNEL__
/* If unmount path, inode should be clean */
- assert(inode->i_sb->s_flags & MS_ACTIVE);
+ if (!(inode->i_sb->s_flags & MS_ACTIVE)) {
+ warn("inode %p, inum %Lu, state %lx/%x",
+ inode, tux_inode(inode)->inum,
+ inode->i_state, tux_inode(inode)->flags);
+ assert(inode->i_sb->s_flags & MS_ACTIVE);
+ }
#endif
return 0;
}
diff --git a/fs/tux3/super.c b/fs/tux3/super.c
index e2d750d82f8a1a..8ad2b4c867e639 100644
--- a/fs/tux3/super.c
+++ b/fs/tux3/super.c
@@ -70,7 +70,17 @@ static void cleanup_dirty_for_umount(struct sb *sb)
cleanup_dirty_buffers(sb->bitmap, head, rollup);
cleanup_dirty_inode(sb->bitmap);
}
- cleanup_dirty_buffers(sb->volmap, &sb->rollup_buffers, rollup);
+ if (sb->volmap) {
+ cleanup_dirty_buffers(sb->volmap, &sb->rollup_buffers, rollup);
+ /*
+ * FIXME: mark_buffer_dirty() for rollup buffers marks
+ * volmap as I_DIRTY_PAGES (we don't need I_DIRTY_PAGES
+ * actually) without changing tuxnode->flags.
+ *
+ * So this is called to clear I_DIRTY_PAGES.
+ */
+ cleanup_dirty_inode(sb->volmap);
+ }
/* orphan_add should be empty */
assert(list_empty(&sb->orphan_add));
@@ -88,6 +98,8 @@ static inline void cleanup_dirty_for_umount(struct sb *sb)
static void __tux3_put_super(struct sb *sbi)
{
+ cleanup_dirty_for_umount(sbi);
+
tux3_exit_flusher(sbi);
/* All forked buffers should be freed here */
@@ -355,8 +367,6 @@ static void tux3_put_super(struct super_block *sb)
{
struct sb *sbi = tux_sb(sb);
- cleanup_dirty_for_umount(sbi);
-
__tux3_put_super(sbi);
sb->s_fs_info = NULL;
kfree(sbi);
diff --git a/fs/tux3/writeback.c b/fs/tux3/writeback.c
index 55e41797483a4e..42202c1cee6a5c 100644
--- a/fs/tux3/writeback.c
+++ b/fs/tux3/writeback.c
@@ -284,6 +284,11 @@ void tux3_mark_buffer_rollup(struct buffer_head *buffer)
tux3_set_buffer_dirty_list(mapping(inode), buffer, sb->rollup,
&sb->rollup_buffers);
+ /*
+ * FIXME: we don't call __tux3_mark_buffer_dirty() here, but
+ * mark_buffer_dirty() marks inode as I_DIRTY_PAGES. This
+ * makes inconsistent state on inode->i_state and tuxnode->flags.
+ */
}
/* Caller must hold tuxnode->lock, or replay (no frontend) */