aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Mason <clm@fb.com>2016-10-10 16:43:31 -0400
committerChris Mason <clm@fb.com>2016-10-10 16:43:31 -0400
commit19c4d2f994788a954af1aa7e53b0fdb46fd7925a (patch)
tree1c2a40e3866668a68b4bfc4ff774295f3f660bc5
parent196e02490c934398f894e5cb0ee1ac8ad13ca576 (diff)
Revert "btrfs: let btrfs_delete_unused_bgs() to clean relocated bgs"
This reverts commit 5d8eb6fe517583f9c6d5b94faf2254a0207a45c9. 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: Chris Mason <clm@fb.com>
-rw-r--r--fs/btrfs/extent-tree.c2
-rw-r--r--fs/btrfs/volumes.c24
2 files changed, 15 insertions, 11 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 11802eaaab54..210c94ac8818 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -10849,7 +10849,7 @@ void btrfs_delete_unused_bgs(struct btrfs_fs_info *fs_info)
10849 spin_lock(&block_group->lock); 10849 spin_lock(&block_group->lock);
10850 if (block_group->reserved || 10850 if (block_group->reserved ||
10851 btrfs_block_group_used(&block_group->item) || 10851 btrfs_block_group_used(&block_group->item) ||
10852 (block_group->ro && !block_group->removed) || 10852 block_group->ro ||
10853 list_is_singular(&block_group->list)) { 10853 list_is_singular(&block_group->list)) {
10854 /* 10854 /*
10855 * We want to bail if we made new allocations or have 10855 * We want to bail if we made new allocations or have
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index b4048c1b3d9b..71a60cc01451 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -2906,8 +2906,8 @@ out:
2906static int btrfs_relocate_chunk(struct btrfs_root *root, u64 chunk_offset) 2906static int btrfs_relocate_chunk(struct btrfs_root *root, u64 chunk_offset)
2907{ 2907{
2908 struct btrfs_root *extent_root; 2908 struct btrfs_root *extent_root;
2909 struct btrfs_trans_handle *trans;
2909 int ret; 2910 int ret;
2910 struct btrfs_block_group_cache *block_group;
2911 2911
2912 root = root->fs_info->chunk_root; 2912 root = root->fs_info->chunk_root;
2913 extent_root = root->fs_info->extent_root; 2913 extent_root = root->fs_info->extent_root;
@@ -2937,17 +2937,21 @@ static int btrfs_relocate_chunk(struct btrfs_root *root, u64 chunk_offset)
2937 if (ret) 2937 if (ret)
2938 return ret; 2938 return ret;
2939 2939
2940 trans = btrfs_start_trans_remove_block_group(root->fs_info,
2941 chunk_offset);
2942 if (IS_ERR(trans)) {
2943 ret = PTR_ERR(trans);
2944 btrfs_handle_fs_error(root->fs_info, ret, NULL);
2945 return ret;
2946 }
2947
2940 /* 2948 /*
2941 * step two, flag the chunk as removed and let 2949 * step two, delete the device extents and the
2942 * btrfs_delete_unused_bgs() remove it. 2950 * chunk tree entries
2943 */ 2951 */
2944 block_group = btrfs_lookup_block_group(root->fs_info, chunk_offset); 2952 ret = btrfs_remove_chunk(trans, root, chunk_offset);
2945 spin_lock(&block_group->lock); 2953 btrfs_end_transaction(trans, extent_root);
2946 block_group->removed = 1; 2954 return ret;
2947 spin_unlock(&block_group->lock);
2948 btrfs_put_block_group(block_group);
2949
2950 return 0;
2951} 2955}
2952 2956
2953static int btrfs_relocate_sys_chunks(struct btrfs_root *root) 2957static int btrfs_relocate_sys_chunks(struct btrfs_root *root)