lkml.org 
[lkml]   [2020]   [Jan]   [2]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.9 001/171] btrfs: skip log replay on orphaned roots
    Date
    From: Josef Bacik <josef@toxicpanda.com>

    commit 9bc574de590510eff899c3ca8dbaf013566b5efe upstream.

    My fsstress modifications coupled with generic/475 uncovered a failure
    to mount and replay the log if we hit a orphaned root. We do not want
    to replay the log for an orphan root, but it's completely legitimate to
    have an orphaned root with a log attached. Fix this by simply skipping
    replaying the log. We still need to pin it's root node so that we do
    not overwrite it while replaying other logs, as we re-read the log root
    at every stage of the replay.

    CC: stable@vger.kernel.org # 4.4+
    Reviewed-by: Filipe Manana <fdmanana@suse.com>
    Signed-off-by: Josef Bacik <josef@toxicpanda.com>
    Signed-off-by: David Sterba <dsterba@suse.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    fs/btrfs/tree-log.c | 23 +++++++++++++++++++++--
    1 file changed, 21 insertions(+), 2 deletions(-)

    --- a/fs/btrfs/tree-log.c
    +++ b/fs/btrfs/tree-log.c
    @@ -5702,9 +5702,28 @@ again:
    wc.replay_dest = btrfs_read_fs_root_no_name(fs_info, &tmp_key);
    if (IS_ERR(wc.replay_dest)) {
    ret = PTR_ERR(wc.replay_dest);
    +
    + /*
    + * We didn't find the subvol, likely because it was
    + * deleted. This is ok, simply skip this log and go to
    + * the next one.
    + *
    + * We need to exclude the root because we can't have
    + * other log replays overwriting this log as we'll read
    + * it back in a few more times. This will keep our
    + * block from being modified, and we'll just bail for
    + * each subsequent pass.
    + */
    + if (ret == -ENOENT)
    + ret = btrfs_pin_extent_for_log_replay(fs_info->extent_root,
    + log->node->start,
    + log->node->len);
    free_extent_buffer(log->node);
    free_extent_buffer(log->commit_root);
    kfree(log);
    +
    + if (!ret)
    + goto next;
    btrfs_handle_fs_error(fs_info, ret,
    "Couldn't read target root for tree log recovery.");
    goto error;
    @@ -5736,7 +5755,6 @@ again:
    &root->highest_objectid);
    }

    - key.offset = found_key.offset - 1;
    wc.replay_dest->log_root = NULL;
    free_extent_buffer(log->node);
    free_extent_buffer(log->commit_root);
    @@ -5744,9 +5762,10 @@ again:

    if (ret)
    goto error;
    -
    +next:
    if (found_key.offset == 0)
    break;
    + key.offset = found_key.offset - 1;
    }
    btrfs_release_path(path);


    \
     
     \ /
      Last update: 2020-01-02 23:27    [W:3.683 / U:0.272 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site