mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-05 02:19:51 +00:00
btrfs: Fix lost-data-profile caused by balance 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" btrfs balance start -dusage=0 $TEST_DIR btrfs filesystem usage $TEST_DIR dd if=/dev/zero of="$TEST_DIR"/file count=100 btrfs filesystem usage $TEST_DIR Result: We can see "no data chunk" in first "btrfs filesystem usage": # btrfs filesystem usage $TEST_DIR Overall: ... Metadata,single: Size:8.00MiB, Used:0.00B /dev/vdg 8.00MiB Metadata,RAID1: Size:122.88MiB, Used:112.00KiB /dev/vdg 122.88MiB /dev/vdh 122.88MiB System,single: Size:4.00MiB, Used:0.00B /dev/vdg 4.00MiB System,RAID1: Size:8.00MiB, Used:16.00KiB /dev/vdg 8.00MiB /dev/vdh 8.00MiB Unallocated: /dev/vdg 1.06GiB /dev/vdh 1.07GiB And "data chunks changed from raid1 to single" in second "btrfs filesystem usage": # btrfs filesystem usage $TEST_DIR Overall: ... Data,single: Size:256.00MiB, Used:0.00B /dev/vdh 256.00MiB Metadata,single: Size:8.00MiB, Used:0.00B /dev/vdg 8.00MiB Metadata,RAID1: Size:122.88MiB, Used:112.00KiB /dev/vdg 122.88MiB /dev/vdh 122.88MiB System,single: Size:4.00MiB, Used:0.00B /dev/vdg 4.00MiB System,RAID1: Size:8.00MiB, Used:16.00KiB /dev/vdg 8.00MiB /dev/vdh 8.00MiB Unallocated: /dev/vdg 1.06GiB /dev/vdh 841.92MiB Reason: btrfs balance delete last data chunk in case of no data in the filesystem, then we can see "no data chunk" by "fi usage" command. And when we do write operation to fs, the only available data profile is 0x0, result is all new chunks are allocated single type. Fix: Allocate a data chunk explicitly to ensure we don't lose the raid profile for data. Test: Test by above script, and confirmed the logic by debug output. Reviewed-by: Filipe Manana <fdmanana@suse.com> Signed-off-by: Zhao Lei <zhaolei@cn.fujitsu.com> Signed-off-by: Chris Mason <clm@fb.com>
This commit is contained in:
parent
aefbe9a633
commit
2c9fe83552
1 changed files with 21 additions and 0 deletions
|
@ -3400,6 +3400,7 @@ static int __btrfs_balance(struct btrfs_fs_info *fs_info)
|
|||
u32 count_data = 0;
|
||||
u32 count_meta = 0;
|
||||
u32 count_sys = 0;
|
||||
int chunk_reserved = 0;
|
||||
|
||||
/* step one make some room on all the devices */
|
||||
devices = &fs_info->fs_devices->devices;
|
||||
|
@ -3501,6 +3502,7 @@ static int __btrfs_balance(struct btrfs_fs_info *fs_info)
|
|||
|
||||
ret = should_balance_chunk(chunk_root, leaf, chunk,
|
||||
found_key.offset);
|
||||
|
||||
btrfs_release_path(path);
|
||||
if (!ret) {
|
||||
mutex_unlock(&fs_info->delete_unused_bgs_mutex);
|
||||
|
@ -3537,6 +3539,25 @@ static int __btrfs_balance(struct btrfs_fs_info *fs_info)
|
|||
goto loop;
|
||||
}
|
||||
|
||||
if ((chunk_type & BTRFS_BLOCK_GROUP_DATA) && !chunk_reserved) {
|
||||
trans = btrfs_start_transaction(chunk_root, 0);
|
||||
if (IS_ERR(trans)) {
|
||||
mutex_unlock(&fs_info->delete_unused_bgs_mutex);
|
||||
ret = PTR_ERR(trans);
|
||||
goto error;
|
||||
}
|
||||
|
||||
ret = btrfs_force_chunk_alloc(trans, chunk_root,
|
||||
BTRFS_BLOCK_GROUP_DATA);
|
||||
if (ret < 0) {
|
||||
mutex_unlock(&fs_info->delete_unused_bgs_mutex);
|
||||
goto error;
|
||||
}
|
||||
|
||||
btrfs_end_transaction(trans, chunk_root);
|
||||
chunk_reserved = 1;
|
||||
}
|
||||
|
||||
ret = btrfs_relocate_chunk(chunk_root,
|
||||
found_key.offset);
|
||||
mutex_unlock(&fs_info->delete_unused_bgs_mutex);
|
||||
|
|
Loading…
Reference in a new issue