summaryrefslogtreecommitdiff
path: root/fs/btrfs/volumes.c
diff options
context:
space:
mode:
authorNaohiro Aota <naohiro.aota@wdc.com>2020-02-25 12:56:12 +0900
committerDavid Sterba <dsterba@suse.com>2020-03-23 17:01:49 +0100
commit560156cb25fcb423969543d8bc93fe95eedc6b4c (patch)
treeaa650d6eb92cdd9e9933548946acf62fd42364b5 /fs/btrfs/volumes.c
parent27c314d5ca090e046c7f49892fde7708dbd877a2 (diff)
btrfs: factor out gather_device_info()
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>
Diffstat (limited to 'fs/btrfs/volumes.c')
-rw-r--r--fs/btrfs/volumes.c121
1 files changed, 67 insertions, 54 deletions
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 9ae5f0c1346c..84c12ff94eb7 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -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()