lkml.org 
[lkml]   [2018]   [Jun]   [7]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Date
    Subject[PATCH 3.16 187/410] Btrfs: fix crash due to not cleaning up tree log block's dirty bits
    3.16.57-rc1 review patch.  If anyone has any objections, please let me know.

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

    From: Liu Bo <bo.li.liu@oracle.com>

    commit 1846430c24d66e85cc58286b3319c82cd54debb2 upstream.

    In cases that the whole fs flips into readonly status due to failures in
    critical sections, then log tree's blocks are still dirty, and this leads
    to a crash during umount time, the crash is about use-after-free,

    umount
    -> close_ctree
    -> stop workers
    -> iput(btree_inode)
    -> iput_final
    -> write_inode_now
    -> ...
    -> queue job on stop'd workers

    Fixes: 681ae50917df ("Btrfs: cleanup reserved space when freeing tree log on error")
    Signed-off-by: Liu Bo <bo.li.liu@oracle.com>
    Reviewed-by: Josef Bacik <jbacik@fb.com>
    Signed-off-by: David Sterba <dsterba@suse.com>
    Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
    ---
    fs/btrfs/tree-log.c | 9 +++++++++
    1 file changed, 9 insertions(+)

    --- a/fs/btrfs/tree-log.c
    +++ b/fs/btrfs/tree-log.c
    @@ -2197,6 +2197,9 @@ static noinline int walk_down_log_tree(s
    clean_tree_block(trans, root, next);
    btrfs_wait_tree_block_writeback(next);
    btrfs_tree_unlock(next);
    + } else {
    + if (test_and_clear_bit(EXTENT_BUFFER_DIRTY, &next->bflags))
    + clear_extent_buffer_dirty(next);
    }

    WARN_ON(root_owner !=
    @@ -2275,6 +2278,9 @@ static noinline int walk_up_log_tree(str
    clean_tree_block(trans, root, next);
    btrfs_wait_tree_block_writeback(next);
    btrfs_tree_unlock(next);
    + } else {
    + if (test_and_clear_bit(EXTENT_BUFFER_DIRTY, &next->bflags))
    + clear_extent_buffer_dirty(next);
    }

    WARN_ON(root_owner != BTRFS_TREE_LOG_OBJECTID);
    @@ -2351,6 +2357,9 @@ static int walk_log_tree(struct btrfs_tr
    clean_tree_block(trans, log, next);
    btrfs_wait_tree_block_writeback(next);
    btrfs_tree_unlock(next);
    + } else {
    + if (test_and_clear_bit(EXTENT_BUFFER_DIRTY, &next->bflags))
    + clear_extent_buffer_dirty(next);
    }

    WARN_ON(log->root_key.objectid !=
    \
     
     \ /
      Last update: 2018-06-07 16:53    [W:5.071 / U:1.456 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site