lkml.org 
[lkml]   [2012]   [Jul]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[ 049/187] nilfs2: ensure proper cache clearing for gc-inodes
    Date
    From: Greg KH <gregkh@linuxfoundation.org>

    3.4-stable review patch. If anyone has any objections, please let me know.

    ------------------

    From: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>

    commit fbb24a3a915f105016f1c828476be11aceac8504 upstream.

    A gc-inode is a pseudo inode used to buffer the blocks to be moved by
    garbage collection.

    Block caches of gc-inodes must be cleared every time a garbage collection
    function (nilfs_clean_segments) completes. Otherwise, stale blocks
    buffered in the caches may be wrongly reused in successive calls of the GC
    function.

    For user files, this is not a problem because their gc-inodes are
    distinguished by a checkpoint number as well as an inode number. They
    never buffer different blocks if either an inode number, a checkpoint
    number, or a block offset differs.

    However, gc-inodes of sufile, cpfile and DAT file can store different data
    for the same block offset. Thus, the nilfs_clean_segments function can
    move incorrect block for these meta-data files if an old block is cached.
    I found this is really causing meta-data corruption in nilfs.

    This fixes the issue by ensuring cache clear of gc-inodes and resolves
    reported GC problems including checkpoint file corruption, b-tree
    corruption, and the following warning during GC.

    nilfs_palloc_freev: entry number 307234 already freed.
    ...

    Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
    Tested-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
    Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
    Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    fs/nilfs2/gcinode.c | 2 ++
    fs/nilfs2/segment.c | 2 ++
    2 files changed, 4 insertions(+)

    --- a/fs/nilfs2/gcinode.c
    +++ b/fs/nilfs2/gcinode.c
    @@ -191,6 +191,8 @@ void nilfs_remove_all_gcinodes(struct th
    while (!list_empty(head)) {
    ii = list_first_entry(head, struct nilfs_inode_info, i_dirty);
    list_del_init(&ii->i_dirty);
    + truncate_inode_pages(&ii->vfs_inode.i_data, 0);
    + nilfs_btnode_cache_clear(&ii->i_btnode_cache);
    iput(&ii->vfs_inode);
    }
    }
    --- a/fs/nilfs2/segment.c
    +++ b/fs/nilfs2/segment.c
    @@ -2309,6 +2309,8 @@ nilfs_remove_written_gcinodes(struct the
    if (!test_bit(NILFS_I_UPDATED, &ii->i_state))
    continue;
    list_del_init(&ii->i_dirty);
    + truncate_inode_pages(&ii->vfs_inode.i_data, 0);
    + nilfs_btnode_cache_clear(&ii->i_btnode_cache);
    iput(&ii->vfs_inode);
    }
    }



    \
     
     \ /
      Last update: 2012-07-13 05:43    [W:2.384 / U:0.044 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site