diff options
author | OGAWA Hirofumi <hirofumi@mail.parknet.co.jp> | 2012-12-31 03:24:33 +0900 |
---|---|---|
committer | Daniel Phillips <daniel@tux3.org> | 2012-12-31 03:24:33 +0900 |
commit | 162f6bf912022a9cf56cdf64ba1c1d1ca049ac8a (patch) | |
tree | f1ea0604c6360518c6c3e7e46aebaee5763e4f97 | |
parent | c8eba0329deed0dd7a1cb3235cb80936e85198a2 (diff) | |
download | linux-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.c | 7 | ||||
-rw-r--r-- | fs/tux3/super.c | 16 | ||||
-rw-r--r-- | fs/tux3/writeback.c | 5 |
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) */ |