From 27c314d5ca090e046c7f49892fde7708dbd877a2 Mon Sep 17 00:00:00 2001 From: Naohiro Aota Date: Tue, 25 Feb 2020 12:56:11 +0900 Subject: btrfs: factor out init_alloc_chunk_ctl Factor out init_alloc_chunk_ctl() from __btrfs_alloc_chunk(). This function initialises parameters of "struct alloc_chunk_ctl" for allocation. init_alloc_chunk_ctl() handles a common part of the initialisation to load the RAID parameters from btrfs_raid_array. init_alloc_chunk_ctl_policy_regular() decides some parameters for its allocation. The last "else" case in the original code is moved to __btrfs_alloc_chunk() to handle the error case in the common code. Replace the BUG_ON with ASSERT() and error return at the same time. Reviewed-by: Josef Bacik Signed-off-by: Naohiro Aota Reviewed-by: David Sterba Signed-off-by: David Sterba --- fs/btrfs/volumes.c | 100 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 62 insertions(+), 38 deletions(-) diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 39a4700ee2ca..9ae5f0c1346c 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -4810,6 +4810,61 @@ struct alloc_chunk_ctl { int ndevs; }; +static void init_alloc_chunk_ctl_policy_regular( + struct btrfs_fs_devices *fs_devices, + struct alloc_chunk_ctl *ctl) +{ + u64 type = ctl->type; + + if (type & BTRFS_BLOCK_GROUP_DATA) { + ctl->max_stripe_size = SZ_1G; + ctl->max_chunk_size = BTRFS_MAX_DATA_CHUNK_SIZE; + } else if (type & BTRFS_BLOCK_GROUP_METADATA) { + /* For larger filesystems, use larger metadata chunks */ + if (fs_devices->total_rw_bytes > 50ULL * SZ_1G) + ctl->max_stripe_size = SZ_1G; + else + ctl->max_stripe_size = SZ_256M; + ctl->max_chunk_size = ctl->max_stripe_size; + } else if (type & BTRFS_BLOCK_GROUP_SYSTEM) { + ctl->max_stripe_size = SZ_32M; + ctl->max_chunk_size = 2 * ctl->max_stripe_size; + ctl->devs_max = min_t(int, ctl->devs_max, + BTRFS_MAX_DEVS_SYS_CHUNK); + } else { + BUG(); + } + + /* We don't want a chunk larger than 10% of writable space */ + ctl->max_chunk_size = min(div_factor(fs_devices->total_rw_bytes, 1), + ctl->max_chunk_size); +} + +static void init_alloc_chunk_ctl(struct btrfs_fs_devices *fs_devices, + struct alloc_chunk_ctl *ctl) +{ + int index = btrfs_bg_flags_to_raid_index(ctl->type); + + ctl->sub_stripes = btrfs_raid_array[index].sub_stripes; + ctl->dev_stripes = btrfs_raid_array[index].dev_stripes; + ctl->devs_max = btrfs_raid_array[index].devs_max; + if (!ctl->devs_max) + ctl->devs_max = BTRFS_MAX_DEVS(fs_devices->fs_info); + ctl->devs_min = btrfs_raid_array[index].devs_min; + ctl->devs_increment = btrfs_raid_array[index].devs_increment; + ctl->ncopies = btrfs_raid_array[index].ncopies; + ctl->nparity = btrfs_raid_array[index].nparity; + ctl->ndevs = 0; + + switch (fs_devices->chunk_alloc_policy) { + case BTRFS_CHUNK_ALLOC_REGULAR: + init_alloc_chunk_ctl_policy_regular(fs_devices, ctl); + break; + default: + BUG(); + } +} + static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans, u64 start, u64 type) { @@ -4828,7 +4883,6 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans, int ndevs; int i; int j; - int index; if (!alloc_profile_is_valid(type, 0)) { ASSERT(0); @@ -4841,45 +4895,15 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans, return -ENOSPC; } - ctl.start = start; - ctl.type = type; - - index = btrfs_bg_flags_to_raid_index(type); - - ctl.sub_stripes = btrfs_raid_array[index].sub_stripes; - ctl.dev_stripes = btrfs_raid_array[index].dev_stripes; - ctl.devs_max = btrfs_raid_array[index].devs_max; - if (!ctl.devs_max) - ctl.devs_max = BTRFS_MAX_DEVS(info); - ctl.devs_min = btrfs_raid_array[index].devs_min; - ctl.devs_increment = btrfs_raid_array[index].devs_increment; - ctl.ncopies = btrfs_raid_array[index].ncopies; - ctl.nparity = btrfs_raid_array[index].nparity; - - if (type & BTRFS_BLOCK_GROUP_DATA) { - ctl.max_stripe_size = SZ_1G; - ctl.max_chunk_size = BTRFS_MAX_DATA_CHUNK_SIZE; - } else if (type & BTRFS_BLOCK_GROUP_METADATA) { - /* for larger filesystems, use larger metadata chunks */ - if (fs_devices->total_rw_bytes > 50ULL * SZ_1G) - ctl.max_stripe_size = SZ_1G; - else - ctl.max_stripe_size = SZ_256M; - ctl.max_chunk_size = ctl.max_stripe_size; - } else if (type & BTRFS_BLOCK_GROUP_SYSTEM) { - ctl.max_stripe_size = SZ_32M; - ctl.max_chunk_size = 2 * ctl.max_stripe_size; - ctl.devs_max = min_t(int, ctl.devs_max, - BTRFS_MAX_DEVS_SYS_CHUNK); - } else { - btrfs_err(info, "invalid chunk type 0x%llx requested", - type); - BUG(); + if (!(type & BTRFS_BLOCK_GROUP_TYPE_MASK)) { + btrfs_err(info, "invalid chunk type 0x%llx requested", type); + ASSERT(0); + return -EINVAL; } - /* We don't want a chunk larger than 10% of writable space */ - ctl.max_chunk_size = min(div_factor(fs_devices->total_rw_bytes, 1), - ctl.max_chunk_size); + ctl.start = start; + ctl.type = type; + init_alloc_chunk_ctl(fs_devices, &ctl); devices_info = kcalloc(fs_devices->rw_devices, sizeof(*devices_info), GFP_NOFS); -- cgit v1.2.3