btrfs: factor out gather_device_info()
authorNaohiro Aota <naohiro.aota@wdc.com>
Tue, 25 Feb 2020 03:56:12 +0000 (12:56 +0900)
committerDavid Sterba <dsterba@suse.com>
Mon, 23 Mar 2020 16:01:49 +0000 (17:01 +0100)
Factor out gather_device_info() from __btrfs_alloc_chunk(). This
function iterates over devices list and gather information about
devices. This commit also introduces "max_avail" and
"dev_extent_min" to fold the same calculation to one variable.
This commit has no functional changes.

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 9ae5f0c..84c12ff 100644 (file)
@@ -4865,60 +4865,25 @@ static void init_alloc_chunk_ctl(struct btrfs_fs_devices *fs_devices,
        }
 }
 
-static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
-                              u64 start, u64 type)
+static int gather_device_info(struct btrfs_fs_devices *fs_devices,
+                             struct alloc_chunk_ctl *ctl,
+                             struct btrfs_device_info *devices_info)
 {
-       struct btrfs_fs_info *info = trans->fs_info;
-       struct btrfs_fs_devices *fs_devices = info->fs_devices;
+       struct btrfs_fs_info *info = fs_devices->fs_info;
        struct btrfs_device *device;
-       struct map_lookup *map = NULL;
-       struct extent_map_tree *em_tree;
-       struct extent_map *em;
-       struct btrfs_device_info *devices_info = NULL;
-       struct alloc_chunk_ctl ctl;
        u64 total_avail;
-       int data_stripes;       /* number of stripes that count for
-                                  block group size */
+       u64 dev_extent_want = ctl->max_stripe_size * ctl->dev_stripes;
+       u64 dev_extent_min = BTRFS_STRIPE_LEN * ctl->dev_stripes;
        int ret;
-       int ndevs;
-       int i;
-       int j;
-
-       if (!alloc_profile_is_valid(type, 0)) {
-               ASSERT(0);
-               return -EINVAL;
-       }
-
-       if (list_empty(&fs_devices->alloc_list)) {
-               if (btrfs_test_opt(info, ENOSPC_DEBUG))
-                       btrfs_debug(info, "%s: no writable device", __func__);
-               return -ENOSPC;
-       }
-
-       if (!(type & BTRFS_BLOCK_GROUP_TYPE_MASK)) {
-               btrfs_err(info, "invalid chunk type 0x%llx requested", type);
-               ASSERT(0);
-               return -EINVAL;
-       }
-
-       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);
-       if (!devices_info)
-               return -ENOMEM;
+       int ndevs = 0;
+       u64 max_avail;
+       u64 dev_offset;
 
        /*
         * in the first pass through the devices list, we gather information
         * about the available holes on each device.
         */
-       ndevs = 0;
        list_for_each_entry(device, &fs_devices->alloc_list, dev_alloc_list) {
-               u64 max_avail;
-               u64 dev_offset;
-
                if (!test_bit(BTRFS_DEV_STATE_WRITEABLE, &device->dev_state)) {
                        WARN(1, KERN_ERR
                               "BTRFS: read-only device in alloc_list\n");
@@ -4939,21 +4904,20 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
                if (total_avail == 0)
                        continue;
 
-               ret = find_free_dev_extent(
-                       device, ctl.max_stripe_size * ctl.dev_stripes,
-                       &dev_offset, &max_avail);
+               ret = find_free_dev_extent(device, dev_extent_want, &dev_offset,
+                                          &max_avail);
                if (ret && ret != -ENOSPC)
-                       goto error;
+                       return ret;
 
                if (ret == 0)
-                       max_avail = ctl.max_stripe_size * ctl.dev_stripes;
+                       max_avail = dev_extent_want;
 
-               if (max_avail < BTRFS_STRIPE_LEN * ctl.dev_stripes) {
+               if (max_avail < dev_extent_min) {
                        if (btrfs_test_opt(info, ENOSPC_DEBUG))
                                btrfs_debug(info,
-                       "%s: devid %llu has no free space, have=%llu want=%u",
+                       "%s: devid %llu has no free space, have=%llu want=%llu",
                                            __func__, device->devid, max_avail,
-                                           BTRFS_STRIPE_LEN * ctl.dev_stripes);
+                                           dev_extent_min);
                        continue;
                }
 
@@ -4968,14 +4932,63 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
                devices_info[ndevs].dev = device;
                ++ndevs;
        }
-       ctl.ndevs = ndevs;
+       ctl->ndevs = ndevs;
 
        /*
         * now sort the devices by hole size / available space
         */
-       sort(devices_info, ctl.ndevs, sizeof(struct btrfs_device_info),
+       sort(devices_info, ndevs, sizeof(struct btrfs_device_info),
             btrfs_cmp_device_info, NULL);
 
+       return 0;
+}
+
+static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
+                              u64 start, u64 type)
+{
+       struct btrfs_fs_info *info = trans->fs_info;
+       struct btrfs_fs_devices *fs_devices = info->fs_devices;
+       struct map_lookup *map = NULL;
+       struct extent_map_tree *em_tree;
+       struct extent_map *em;
+       struct btrfs_device_info *devices_info = NULL;
+       struct alloc_chunk_ctl ctl;
+       /* Number of stripes that count for block group size */
+       int data_stripes;
+       int ret;
+       int i;
+       int j;
+
+       if (!alloc_profile_is_valid(type, 0)) {
+               ASSERT(0);
+               return -EINVAL;
+       }
+
+       if (list_empty(&fs_devices->alloc_list)) {
+               if (btrfs_test_opt(info, ENOSPC_DEBUG))
+                       btrfs_debug(info, "%s: no writable device", __func__);
+               return -ENOSPC;
+       }
+
+       if (!(type & BTRFS_BLOCK_GROUP_TYPE_MASK)) {
+               btrfs_err(info, "invalid chunk type 0x%llx requested", type);
+               ASSERT(0);
+               return -EINVAL;
+       }
+
+       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);
+       if (!devices_info)
+               return -ENOMEM;
+
+       ret = gather_device_info(fs_devices, &ctl, devices_info);
+       if (ret < 0)
+               goto error;
+
        /*
         * Round down to number of usable stripes, devs_increment can be any
         * number so we can't use round_down()