aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZhao Lei <zhaolei@cn.fujitsu.com>2015-11-08 22:51:32 -0500
committerChris Mason <clm@fb.com>2015-11-10 22:27:20 -0500
commit2c9fe835525896077e7e6d8e416b97f2f868edef (patch)
tree6620ef5699f2426a05fcff4fa493e21305c651f4
parentaefbe9a633b50a6124dbeb33a5d4efcdc6de6c30 (diff)
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>
-rw-r--r--fs/btrfs/volumes.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 17ed76d18eb6..d198dd3360d3 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -3400,6 +3400,7 @@ static int __btrfs_balance(struct btrfs_fs_info *fs_info)
3400 u32 count_data = 0; 3400 u32 count_data = 0;
3401 u32 count_meta = 0; 3401 u32 count_meta = 0;
3402 u32 count_sys = 0; 3402 u32 count_sys = 0;
3403 int chunk_reserved = 0;
3403 3404
3404 /* step one make some room on all the devices */ 3405 /* step one make some room on all the devices */
3405 devices = &fs_info->fs_devices->devices; 3406 devices = &fs_info->fs_devices->devices;
@@ -3501,6 +3502,7 @@ again:
3501 3502
3502 ret = should_balance_chunk(chunk_root, leaf, chunk, 3503 ret = should_balance_chunk(chunk_root, leaf, chunk,
3503 found_key.offset); 3504 found_key.offset);
3505
3504 btrfs_release_path(path); 3506 btrfs_release_path(path);
3505 if (!ret) { 3507 if (!ret) {
3506 mutex_unlock(&fs_info->delete_unused_bgs_mutex); 3508 mutex_unlock(&fs_info->delete_unused_bgs_mutex);
@@ -3537,6 +3539,25 @@ again:
3537 goto loop; 3539 goto loop;
3538 } 3540 }
3539 3541
3542 if ((chunk_type & BTRFS_BLOCK_GROUP_DATA) && !chunk_reserved) {
3543 trans = btrfs_start_transaction(chunk_root, 0);
3544 if (IS_ERR(trans)) {
3545 mutex_unlock(&fs_info->delete_unused_bgs_mutex);
3546 ret = PTR_ERR(trans);
3547 goto error;
3548 }
3549
3550 ret = btrfs_force_chunk_alloc(trans, chunk_root,
3551 BTRFS_BLOCK_GROUP_DATA);
3552 if (ret < 0) {
3553 mutex_unlock(&fs_info->delete_unused_bgs_mutex);
3554 goto error;
3555 }
3556
3557 btrfs_end_transaction(trans, chunk_root);
3558 chunk_reserved = 1;
3559 }
3560
3540 ret = btrfs_relocate_chunk(chunk_root, 3561 ret = btrfs_relocate_chunk(chunk_root,
3541 found_key.offset); 3562 found_key.offset);
3542 mutex_unlock(&fs_info->delete_unused_bgs_mutex); 3563 mutex_unlock(&fs_info->delete_unused_bgs_mutex);