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

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


    From: Ryusuke Konishi <>

    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

    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 <>
    Tested-by: Ryusuke Konishi <>
    Signed-off-by: Andrew Morton <>
    Signed-off-by: Linus Torvalds <>
    Signed-off-by: Greg Kroah-Hartman <>

    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);
    + truncate_inode_pages(&ii->vfs_inode.i_data, 0);
    + nilfs_btnode_cache_clear(&ii->i_btnode_cache);
    --- 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))
    + truncate_inode_pages(&ii->vfs_inode.i_data, 0);
    + nilfs_btnode_cache_clear(&ii->i_btnode_cache);

     \ /
      Last update: 2012-07-13 05:43    [W:0.023 / U:46.708 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site