lkml.org 
[lkml]   [2019]   [Apr]   [18]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.0 79/93] f2fs: sync filesystem after roll-forward recovery
    Date
    [ Upstream commit 812a95977fd2f0d1f220c716a98a7f22e22f488d ]

    Some works after roll-forward recovery can get an error which will release
    all the data structures. Let's flush them in order to make it clean.

    One possible corruption came from:

    [ 90.400500] list_del corruption. prev->next should be ffffffed1f566208, but was (null)
    [ 90.675349] Call trace:
    [ 90.677869] __list_del_entry_valid+0x94/0xb4
    [ 90.682351] remove_dirty_inode+0xac/0x114
    [ 90.686563] __f2fs_write_data_pages+0x6a8/0x6c8
    [ 90.691302] f2fs_write_data_pages+0x40/0x4c
    [ 90.695695] do_writepages+0x80/0xf0
    [ 90.699372] __writeback_single_inode+0xdc/0x4ac
    [ 90.704113] writeback_sb_inodes+0x280/0x440
    [ 90.708501] wb_writeback+0x1b8/0x3d0
    [ 90.712267] wb_workfn+0x1a8/0x4d4
    [ 90.715765] process_one_work+0x1c0/0x3d4
    [ 90.719883] worker_thread+0x224/0x344
    [ 90.723739] kthread+0x120/0x130
    [ 90.727055] ret_from_fork+0x10/0x18

    Reported-by: Sahitya Tummala <stummala@codeaurora.org>
    Reviewed-by: Chao Yu <yuchao0@huawei.com>
    Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    fs/f2fs/checkpoint.c | 5 +++--
    fs/f2fs/node.c | 4 +++-
    fs/f2fs/super.c | 44 +++++++++++++++++++++++++++++++++-----------
    3 files changed, 39 insertions(+), 14 deletions(-)

    diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
    index f955cd3e0677..ccccf0ce2f06 100644
    --- a/fs/f2fs/checkpoint.c
    +++ b/fs/f2fs/checkpoint.c
    @@ -306,8 +306,9 @@ static int f2fs_write_meta_pages(struct address_space *mapping,
    goto skip_write;

    /* collect a number of dirty meta pages and write together */
    - if (wbc->for_kupdate ||
    - get_pages(sbi, F2FS_DIRTY_META) < nr_pages_to_skip(sbi, META))
    + if (wbc->sync_mode != WB_SYNC_ALL &&
    + get_pages(sbi, F2FS_DIRTY_META) <
    + nr_pages_to_skip(sbi, META))
    goto skip_write;

    /* if locked failed, cp will flush dirty pages instead */
    diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
    index 4f450e573312..f6ff84e29749 100644
    --- a/fs/f2fs/node.c
    +++ b/fs/f2fs/node.c
    @@ -1920,7 +1920,9 @@ static int f2fs_write_node_pages(struct address_space *mapping,
    f2fs_balance_fs_bg(sbi);

    /* collect a number of dirty node pages and write together */
    - if (get_pages(sbi, F2FS_DIRTY_NODES) < nr_pages_to_skip(sbi, NODE))
    + if (wbc->sync_mode != WB_SYNC_ALL &&
    + get_pages(sbi, F2FS_DIRTY_NODES) <
    + nr_pages_to_skip(sbi, NODE))
    goto skip_write;

    if (wbc->sync_mode == WB_SYNC_ALL)
    diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
    index 5892fa3c885f..144ffba3ec5a 100644
    --- a/fs/f2fs/super.c
    +++ b/fs/f2fs/super.c
    @@ -1460,9 +1460,16 @@ static int f2fs_enable_quotas(struct super_block *sb);

    static int f2fs_disable_checkpoint(struct f2fs_sb_info *sbi)
    {
    + unsigned int s_flags = sbi->sb->s_flags;
    struct cp_control cpc;
    - int err;
    + int err = 0;
    + int ret;

    + if (s_flags & SB_RDONLY) {
    + f2fs_msg(sbi->sb, KERN_ERR,
    + "checkpoint=disable on readonly fs");
    + return -EINVAL;
    + }
    sbi->sb->s_flags |= SB_ACTIVE;

    f2fs_update_time(sbi, DISABLE_TIME);
    @@ -1470,18 +1477,24 @@ static int f2fs_disable_checkpoint(struct f2fs_sb_info *sbi)
    while (!f2fs_time_over(sbi, DISABLE_TIME)) {
    mutex_lock(&sbi->gc_mutex);
    err = f2fs_gc(sbi, true, false, NULL_SEGNO);
    - if (err == -ENODATA)
    + if (err == -ENODATA) {
    + err = 0;
    break;
    + }
    if (err && err != -EAGAIN)
    - return err;
    + break;
    }

    - err = sync_filesystem(sbi->sb);
    - if (err)
    - return err;
    + ret = sync_filesystem(sbi->sb);
    + if (ret || err) {
    + err = ret ? ret: err;
    + goto restore_flag;
    + }

    - if (f2fs_disable_cp_again(sbi))
    - return -EAGAIN;
    + if (f2fs_disable_cp_again(sbi)) {
    + err = -EAGAIN;
    + goto restore_flag;
    + }

    mutex_lock(&sbi->gc_mutex);
    cpc.reason = CP_PAUSE;
    @@ -1490,7 +1503,9 @@ static int f2fs_disable_checkpoint(struct f2fs_sb_info *sbi)

    sbi->unusable_block_count = 0;
    mutex_unlock(&sbi->gc_mutex);
    - return 0;
    +restore_flag:
    + sbi->sb->s_flags = s_flags; /* Restore MS_RDONLY status */
    + return err;
    }

    static void f2fs_enable_checkpoint(struct f2fs_sb_info *sbi)
    @@ -3359,7 +3374,7 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
    if (test_opt(sbi, DISABLE_CHECKPOINT)) {
    err = f2fs_disable_checkpoint(sbi);
    if (err)
    - goto free_meta;
    + goto sync_free_meta;
    } else if (is_set_ckpt_flags(sbi, CP_DISABLED_FLAG)) {
    f2fs_enable_checkpoint(sbi);
    }
    @@ -3372,7 +3387,7 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
    /* After POR, we can run background GC thread.*/
    err = f2fs_start_gc_thread(sbi);
    if (err)
    - goto free_meta;
    + goto sync_free_meta;
    }
    kvfree(options);

    @@ -3394,6 +3409,11 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
    f2fs_update_time(sbi, REQ_TIME);
    return 0;

    +sync_free_meta:
    + /* safe to flush all the data */
    + sync_filesystem(sbi->sb);
    + retry = false;
    +
    free_meta:
    #ifdef CONFIG_QUOTA
    f2fs_truncate_quota_inode_pages(sb);
    @@ -3407,6 +3427,8 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
    * falls into an infinite loop in f2fs_sync_meta_pages().
    */
    truncate_inode_pages_final(META_MAPPING(sbi));
    + /* evict some inodes being cached by GC */
    + evict_inodes(sb);
    f2fs_unregister_sysfs(sbi);
    free_root_inode:
    dput(sb->s_root);
    --
    2.19.1


    \
     
     \ /
      Last update: 2019-04-18 20:16    [W:7.837 / U:1.168 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site