btrfs: factor out init_alloc_chunk_ctl
authorNaohiro Aota <naohiro.aota@wdc.com>
Tue, 25 Feb 2020 03:56:11 +0000 (12:56 +0900)
committerDavid Sterba <dsterba@suse.com>
Mon, 23 Mar 2020 16:01:48 +0000 (17:01 +0100)
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>
fs/btrfs/volumes.c

index 39a4700..9ae5f0c 100644 (file)
@@ -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);