summaryrefslogtreecommitdiff
path: root/fs/btrfs/volumes.c
diff options
context:
space:
mode:
authorNaohiro Aota <naohiro.aota@wdc.com>2020-02-25 12:56:11 +0900
committerDavid Sterba <dsterba@suse.com>2020-03-23 17:01:48 +0100
commit27c314d5ca090e046c7f49892fde7708dbd877a2 (patch)
tree2005db2ffff70477c0172e8571ae8c37d4a42b2d /fs/btrfs/volumes.c
parent4f2bafe8a49e5f5e5cf821117ddd6b868c7dc0e7 (diff)
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 <josef@toxicpanda.com> Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'fs/btrfs/volumes.c')
-rw-r--r--fs/btrfs/volumes.c100
1 files 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);