Commit 27c314d5 authored by Naohiro Aota's avatar Naohiro Aota Committed by David Sterba

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: default avatarJosef Bacik <josef@toxicpanda.com>
Signed-off-by: default avatarNaohiro Aota <naohiro.aota@wdc.com>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent 4f2bafe8
...@@ -4810,6 +4810,61 @@ struct alloc_chunk_ctl { ...@@ -4810,6 +4810,61 @@ struct alloc_chunk_ctl {
int ndevs; 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, static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
u64 start, u64 type) u64 start, u64 type)
{ {
...@@ -4828,7 +4883,6 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans, ...@@ -4828,7 +4883,6 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
int ndevs; int ndevs;
int i; int i;
int j; int j;
int index;
if (!alloc_profile_is_valid(type, 0)) { if (!alloc_profile_is_valid(type, 0)) {
ASSERT(0); ASSERT(0);
...@@ -4841,45 +4895,15 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans, ...@@ -4841,45 +4895,15 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
return -ENOSPC; return -ENOSPC;
} }
ctl.start = start; if (!(type & BTRFS_BLOCK_GROUP_TYPE_MASK)) {
ctl.type = type; btrfs_err(info, "invalid chunk type 0x%llx requested", type);
ASSERT(0);
index = btrfs_bg_flags_to_raid_index(type); return -EINVAL;
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();
} }
/* We don't want a chunk larger than 10% of writable space */ ctl.start = start;
ctl.max_chunk_size = min(div_factor(fs_devices->total_rw_bytes, 1), ctl.type = type;
ctl.max_chunk_size); init_alloc_chunk_ctl(fs_devices, &ctl);
devices_info = kcalloc(fs_devices->rw_devices, sizeof(*devices_info), devices_info = kcalloc(fs_devices->rw_devices, sizeof(*devices_info),
GFP_NOFS); GFP_NOFS);
......
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