Commit 19c4d2f9 authored by Chris Mason's avatar Chris Mason

Revert "btrfs: let btrfs_delete_unused_bgs() to clean relocated bgs"

This reverts commit 5d8eb6fe.

When we remove devices, we free the device structures.  Delaying
btfs_remove_chunk() ends up hitting a use-after-free on them.
Signed-off-by: default avatarChris Mason <clm@fb.com>
parent 196e0249
...@@ -10849,7 +10849,7 @@ void btrfs_delete_unused_bgs(struct btrfs_fs_info *fs_info) ...@@ -10849,7 +10849,7 @@ void btrfs_delete_unused_bgs(struct btrfs_fs_info *fs_info)
spin_lock(&block_group->lock); spin_lock(&block_group->lock);
if (block_group->reserved || if (block_group->reserved ||
btrfs_block_group_used(&block_group->item) || btrfs_block_group_used(&block_group->item) ||
(block_group->ro && !block_group->removed) || block_group->ro ||
list_is_singular(&block_group->list)) { list_is_singular(&block_group->list)) {
/* /*
* We want to bail if we made new allocations or have * We want to bail if we made new allocations or have
......
...@@ -2906,8 +2906,8 @@ int btrfs_remove_chunk(struct btrfs_trans_handle *trans, ...@@ -2906,8 +2906,8 @@ int btrfs_remove_chunk(struct btrfs_trans_handle *trans,
static int btrfs_relocate_chunk(struct btrfs_root *root, u64 chunk_offset) static int btrfs_relocate_chunk(struct btrfs_root *root, u64 chunk_offset)
{ {
struct btrfs_root *extent_root; struct btrfs_root *extent_root;
struct btrfs_trans_handle *trans;
int ret; int ret;
struct btrfs_block_group_cache *block_group;
root = root->fs_info->chunk_root; root = root->fs_info->chunk_root;
extent_root = root->fs_info->extent_root; extent_root = root->fs_info->extent_root;
...@@ -2937,17 +2937,21 @@ static int btrfs_relocate_chunk(struct btrfs_root *root, u64 chunk_offset) ...@@ -2937,17 +2937,21 @@ static int btrfs_relocate_chunk(struct btrfs_root *root, u64 chunk_offset)
if (ret) if (ret)
return ret; return ret;
trans = btrfs_start_trans_remove_block_group(root->fs_info,
chunk_offset);
if (IS_ERR(trans)) {
ret = PTR_ERR(trans);
btrfs_handle_fs_error(root->fs_info, ret, NULL);
return ret;
}
/* /*
* step two, flag the chunk as removed and let * step two, delete the device extents and the
* btrfs_delete_unused_bgs() remove it. * chunk tree entries
*/ */
block_group = btrfs_lookup_block_group(root->fs_info, chunk_offset); ret = btrfs_remove_chunk(trans, root, chunk_offset);
spin_lock(&block_group->lock); btrfs_end_transaction(trans, extent_root);
block_group->removed = 1; return ret;
spin_unlock(&block_group->lock);
btrfs_put_block_group(block_group);
return 0;
} }
static int btrfs_relocate_sys_chunks(struct btrfs_root *root) static int btrfs_relocate_sys_chunks(struct btrfs_root *root)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment