Commit cf25ce51 authored by Liu Bo's avatar Liu Bo Committed by David Sterba

Btrfs: do not create empty block group if we have allocated data

Now we force to create empty block group to keep data profile alive,
however, in the below example, we eventually get an empty block group
while we're trying to get more space for other types (metadata/system),

- Before,
block group "A": size=2G, used=1.2G
block group "B": size=2G, used=512M

- After "btrfs balance start -dusage=50 mount_point",
block group "A": size=2G, used=(1.2+0.5)G
block group "C": size=2G, used=0

Since there is no data in block group C, it won't be deleted
automatically and we have to get the unused 2G until the next mount.

Balance itself just moves data and doesn't remove data, so it's safe
to not create such a empty block group if we already have data
 allocated in other block groups.
Signed-off-by: default avatarLiu Bo <bo.li.liu@oracle.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent a2af23b7
...@@ -3402,6 +3402,7 @@ static int __btrfs_balance(struct btrfs_fs_info *fs_info) ...@@ -3402,6 +3402,7 @@ static int __btrfs_balance(struct btrfs_fs_info *fs_info)
u32 count_meta = 0; u32 count_meta = 0;
u32 count_sys = 0; u32 count_sys = 0;
int chunk_reserved = 0; int chunk_reserved = 0;
u64 bytes_used = 0;
/* step one make some room on all the devices */ /* step one make some room on all the devices */
devices = &fs_info->fs_devices->devices; devices = &fs_info->fs_devices->devices;
...@@ -3540,7 +3541,13 @@ static int __btrfs_balance(struct btrfs_fs_info *fs_info) ...@@ -3540,7 +3541,13 @@ static int __btrfs_balance(struct btrfs_fs_info *fs_info)
goto loop; goto loop;
} }
if ((chunk_type & BTRFS_BLOCK_GROUP_DATA) && !chunk_reserved) { ASSERT(fs_info->data_sinfo);
spin_lock(&fs_info->data_sinfo->lock);
bytes_used = fs_info->data_sinfo->bytes_used;
spin_unlock(&fs_info->data_sinfo->lock);
if ((chunk_type & BTRFS_BLOCK_GROUP_DATA) &&
!chunk_reserved && !bytes_used) {
trans = btrfs_start_transaction(chunk_root, 0); trans = btrfs_start_transaction(chunk_root, 0);
if (IS_ERR(trans)) { if (IS_ERR(trans)) {
mutex_unlock(&fs_info->delete_unused_bgs_mutex); mutex_unlock(&fs_info->delete_unused_bgs_mutex);
......
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