Commit 15c82763 authored by Nikolay Borisov's avatar Nikolay Borisov Committed by David Sterba

btrfs: Remove 1st shrink/grow phase from balance

The first step of the rebalance process ensures there is 1MiB free on
each device. This number seems rather small. And in fact when talking to
the original authors their opinions were:

"man that's a little bonkers"
"i don't think we even need that code anymore"
"I think it was there to make sure we had room for the blank 1M at the
beginning. I bet it goes all the way back to v0"
"we just don't need any of that tho, i say we just delete it"

Clearly, this piece of code has lost its original intent throughout the
years. It doesn't really bring any real practical benefits to the
relocation process.

Additionally, this patch makes the balance process more lightweight by
removing a pair of shrink/grow operations which are rather expensive for
heavily populated filesystems. This is mainly due to shrink requiring
relocating block groups, involving heavy use of the btree.

The intermediate shrink/grow can fail and leave the filesystem in a
middle state that would need to be changed back by the user.
Suggested-by: default avatarJosef Bacik <josef@toxicpanda.com>
Reviewed-by: default avatarJosef Bacik <josef@toxicpanda.com>
Signed-off-by: default avatarNikolay Borisov <nborisov@suse.com>
[ update changelog ]
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent be6821f8
......@@ -3700,17 +3700,11 @@ static int __btrfs_balance(struct btrfs_fs_info *fs_info)
{
struct btrfs_balance_control *bctl = fs_info->balance_ctl;
struct btrfs_root *chunk_root = fs_info->chunk_root;
struct btrfs_root *dev_root = fs_info->dev_root;
struct list_head *devices;
struct btrfs_device *device;
u64 old_size;
u64 size_to_free;
u64 chunk_type;
struct btrfs_chunk *chunk;
struct btrfs_path *path = NULL;
struct btrfs_key key;
struct btrfs_key found_key;
struct btrfs_trans_handle *trans;
struct extent_buffer *leaf;
int slot;
int ret;
......@@ -3725,53 +3719,6 @@ static int __btrfs_balance(struct btrfs_fs_info *fs_info)
u32 count_sys = 0;
int chunk_reserved = 0;
/* step one make some room on all the devices */
devices = &fs_info->fs_devices->devices;
list_for_each_entry(device, devices, dev_list) {
old_size = btrfs_device_get_total_bytes(device);
size_to_free = div_factor(old_size, 1);
size_to_free = min_t(u64, size_to_free, SZ_1M);
if (!test_bit(BTRFS_DEV_STATE_WRITEABLE, &device->dev_state) ||
btrfs_device_get_total_bytes(device) -
btrfs_device_get_bytes_used(device) > size_to_free ||
test_bit(BTRFS_DEV_STATE_REPLACE_TGT, &device->dev_state))
continue;
ret = btrfs_shrink_device(device, old_size - size_to_free);
if (ret == -ENOSPC)
break;
if (ret) {
/* btrfs_shrink_device never returns ret > 0 */
WARN_ON(ret > 0);
goto error;
}
trans = btrfs_start_transaction(dev_root, 0);
if (IS_ERR(trans)) {
ret = PTR_ERR(trans);
btrfs_info_in_rcu(fs_info,
"resize: unable to start transaction after shrinking device %s (error %d), old size %llu, new size %llu",
rcu_str_deref(device->name), ret,
old_size, old_size - size_to_free);
goto error;
}
ret = btrfs_grow_device(trans, device, old_size);
if (ret) {
btrfs_end_transaction(trans);
/* btrfs_grow_device never returns ret > 0 */
WARN_ON(ret > 0);
btrfs_info_in_rcu(fs_info,
"resize: unable to grow device after shrinking device %s (error %d), old size %llu, new size %llu",
rcu_str_deref(device->name), ret,
old_size, old_size - size_to_free);
goto error;
}
btrfs_end_transaction(trans);
}
/* step two, relocate all the chunks */
path = btrfs_alloc_path();
if (!path) {
ret = -ENOMEM;
......
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