Commit aefbe9a6 authored by Zhao Lei's avatar Zhao Lei Committed by Chris Mason

btrfs: Fix lost-data-profile caused by auto removing bg

Reproduce:
 (In integration-4.3 branch)

 TEST_DEV=(/dev/vdg /dev/vdh)
 TEST_DIR=/mnt/tmp

 umount "$TEST_DEV" >/dev/null
 mkfs.btrfs -f -d raid1 "${TEST_DEV[@]}"

 mount -o nospace_cache "$TEST_DEV" "$TEST_DIR"
 umount "$TEST_DEV"

 mount -o nospace_cache "$TEST_DEV" "$TEST_DIR"
 btrfs filesystem usage $TEST_DIR

We can see the data chunk changed from raid1 to single:
 # btrfs filesystem usage $TEST_DIR
 Data,single: Size:8.00MiB, Used:0.00B
    /dev/vdg        8.00MiB
 #

Reason:
 When a empty filesystem mount with -o nospace_cache, the last
 data blockgroup will be auto-removed in umount.

 Then if we mount it again, there is no data chunk in the
 filesystem, so the only available data profile is 0x0, result
 is all new chunks are created as single type.

Fix:
 Don't auto-delete last blockgroup for a raid type.

Test:
 Test by above script, and confirmed the logic by debug output.
Reviewed-by: default avatarFilipe Manana <fdmanana@suse.com>
Signed-off-by: default avatarZhao Lei <zhaolei@cn.fujitsu.com>
Signed-off-by: default avatarChris Mason <clm@fb.com>
parent 3b5753ec
...@@ -10279,8 +10279,10 @@ void btrfs_delete_unused_bgs(struct btrfs_fs_info *fs_info) ...@@ -10279,8 +10279,10 @@ void btrfs_delete_unused_bgs(struct btrfs_fs_info *fs_info)
block_group = list_first_entry(&fs_info->unused_bgs, block_group = list_first_entry(&fs_info->unused_bgs,
struct btrfs_block_group_cache, struct btrfs_block_group_cache,
bg_list); bg_list);
space_info = block_group->space_info;
list_del_init(&block_group->bg_list); list_del_init(&block_group->bg_list);
space_info = block_group->space_info;
if (ret || btrfs_mixed_space_info(space_info)) { if (ret || btrfs_mixed_space_info(space_info)) {
btrfs_put_block_group(block_group); btrfs_put_block_group(block_group);
continue; continue;
...@@ -10294,7 +10296,8 @@ void btrfs_delete_unused_bgs(struct btrfs_fs_info *fs_info) ...@@ -10294,7 +10296,8 @@ 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->ro ||
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
* outstanding allocations in this block group. We do * outstanding allocations in this block group. We do
......
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