lkml.org 
[lkml]   [2017]   [May]   [18]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.11 088/114] f2fs: fix fs corruption due to zero inode page
    Date
    4.11-stable review patch.  If anyone has any objections, please let me know.

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

    From: Jaegeuk Kim <jaegeuk@kernel.org>

    commit 9bb02c3627f46e50246bf7ab957b56ffbef623cb upstream.

    This patch fixes the following scenario.

    - f2fs_create/f2fs_mkdir - write_checkpoint
    - f2fs_mark_inode_dirty_sync - block_operations
    - f2fs_lock_all
    - f2fs_sync_inode_meta
    - f2fs_unlock_all
    - sync_inode_metadata
    - f2fs_lock_op
    - f2fs_write_inode
    - update_inode_page
    - get_node_page
    return -ENOENT
    - new_inode_page
    - fill_node_footer
    - f2fs_mark_inode_dirty_sync
    - ...
    - f2fs_unlock_op
    - f2fs_inode_synced
    - f2fs_lock_all
    - do_checkpoint

    In this checkpoint, we can get an inode page which contains zeros having valid
    node footer only.

    Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    fs/f2fs/inode.c | 2 +-
    fs/f2fs/namei.c | 20 ++++++++++----------
    2 files changed, 11 insertions(+), 11 deletions(-)

    --- a/fs/f2fs/inode.c
    +++ b/fs/f2fs/inode.c
    @@ -316,7 +316,6 @@ retry:
    } else if (err != -ENOENT) {
    f2fs_stop_checkpoint(sbi, false);
    }
    - f2fs_inode_synced(inode);
    return 0;
    }
    ret = update_inode(inode, node_page);
    @@ -448,6 +447,7 @@ void handle_failed_inode(struct inode *i
    * in a panic when flushing dirty inodes in gdirty_list.
    */
    update_inode_page(inode);
    + f2fs_inode_synced(inode);

    /* don't make bad inode, since it becomes a regular file. */
    unlock_new_inode(inode);
    --- a/fs/f2fs/namei.c
    +++ b/fs/f2fs/namei.c
    @@ -148,8 +148,6 @@ static int f2fs_create(struct inode *dir
    inode->i_mapping->a_ops = &f2fs_dblock_aops;
    ino = inode->i_ino;

    - f2fs_balance_fs(sbi, true);
    -
    f2fs_lock_op(sbi);
    err = f2fs_add_link(dentry, inode);
    if (err)
    @@ -163,6 +161,8 @@ static int f2fs_create(struct inode *dir

    if (IS_DIRSYNC(dir))
    f2fs_sync_fs(sbi->sb, 1);
    +
    + f2fs_balance_fs(sbi, true);
    return 0;
    out:
    handle_failed_inode(inode);
    @@ -423,8 +423,6 @@ static int f2fs_symlink(struct inode *di
    inode_nohighmem(inode);
    inode->i_mapping->a_ops = &f2fs_dblock_aops;

    - f2fs_balance_fs(sbi, true);
    -
    f2fs_lock_op(sbi);
    err = f2fs_add_link(dentry, inode);
    if (err)
    @@ -487,6 +485,8 @@ err_out:
    }

    kfree(sd);
    +
    + f2fs_balance_fs(sbi, true);
    return err;
    out:
    handle_failed_inode(inode);
    @@ -508,8 +508,6 @@ static int f2fs_mkdir(struct inode *dir,
    inode->i_mapping->a_ops = &f2fs_dblock_aops;
    mapping_set_gfp_mask(inode->i_mapping, GFP_F2FS_HIGH_ZERO);

    - f2fs_balance_fs(sbi, true);
    -
    set_inode_flag(inode, FI_INC_LINK);
    f2fs_lock_op(sbi);
    err = f2fs_add_link(dentry, inode);
    @@ -524,6 +522,8 @@ static int f2fs_mkdir(struct inode *dir,

    if (IS_DIRSYNC(dir))
    f2fs_sync_fs(sbi->sb, 1);
    +
    + f2fs_balance_fs(sbi, true);
    return 0;

    out_fail:
    @@ -554,8 +554,6 @@ static int f2fs_mknod(struct inode *dir,
    init_special_inode(inode, inode->i_mode, rdev);
    inode->i_op = &f2fs_special_inode_operations;

    - f2fs_balance_fs(sbi, true);
    -
    f2fs_lock_op(sbi);
    err = f2fs_add_link(dentry, inode);
    if (err)
    @@ -569,6 +567,8 @@ static int f2fs_mknod(struct inode *dir,

    if (IS_DIRSYNC(dir))
    f2fs_sync_fs(sbi->sb, 1);
    +
    + f2fs_balance_fs(sbi, true);
    return 0;
    out:
    handle_failed_inode(inode);
    @@ -595,8 +595,6 @@ static int __f2fs_tmpfile(struct inode *
    inode->i_mapping->a_ops = &f2fs_dblock_aops;
    }

    - f2fs_balance_fs(sbi, true);
    -
    f2fs_lock_op(sbi);
    err = acquire_orphan_inode(sbi);
    if (err)
    @@ -622,6 +620,8 @@ static int __f2fs_tmpfile(struct inode *
    /* link_count was changed by d_tmpfile as well. */
    f2fs_unlock_op(sbi);
    unlock_new_inode(inode);
    +
    + f2fs_balance_fs(sbi, true);
    return 0;

    release_out:

    \
     
     \ /
      Last update: 2017-05-18 13:57    [W:4.171 / U:0.520 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site