Commit 560156cb authored by Naohiro Aota's avatar Naohiro Aota Committed by David Sterba

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: 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 27c314d5
...@@ -4865,60 +4865,25 @@ static void init_alloc_chunk_ctl(struct btrfs_fs_devices *fs_devices, ...@@ -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, static int gather_device_info(struct btrfs_fs_devices *fs_devices,
u64 start, u64 type) struct alloc_chunk_ctl *ctl,
struct btrfs_device_info *devices_info)
{ {
struct btrfs_fs_info *info = trans->fs_info; struct btrfs_fs_info *info = fs_devices->fs_info;
struct btrfs_fs_devices *fs_devices = info->fs_devices;
struct btrfs_device *device; 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; u64 total_avail;
int data_stripes; /* number of stripes that count for u64 dev_extent_want = ctl->max_stripe_size * ctl->dev_stripes;
block group size */ u64 dev_extent_min = BTRFS_STRIPE_LEN * ctl->dev_stripes;
int ret; int ret;
int ndevs; int ndevs = 0;
int i; u64 max_avail;
int j; u64 dev_offset;
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;
/* /*
* in the first pass through the devices list, we gather information * in the first pass through the devices list, we gather information
* about the available holes on each device. * about the available holes on each device.
*/ */
ndevs = 0;
list_for_each_entry(device, &fs_devices->alloc_list, dev_alloc_list) { 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)) { if (!test_bit(BTRFS_DEV_STATE_WRITEABLE, &device->dev_state)) {
WARN(1, KERN_ERR WARN(1, KERN_ERR
"BTRFS: read-only device in alloc_list\n"); "BTRFS: read-only device in alloc_list\n");
...@@ -4939,21 +4904,20 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans, ...@@ -4939,21 +4904,20 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
if (total_avail == 0) if (total_avail == 0)
continue; continue;
ret = find_free_dev_extent( ret = find_free_dev_extent(device, dev_extent_want, &dev_offset,
device, ctl.max_stripe_size * ctl.dev_stripes, &max_avail);
&dev_offset, &max_avail);
if (ret && ret != -ENOSPC) if (ret && ret != -ENOSPC)
goto error; return ret;
if (ret == 0) 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)) if (btrfs_test_opt(info, ENOSPC_DEBUG))
btrfs_debug(info, 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, __func__, device->devid, max_avail,
BTRFS_STRIPE_LEN * ctl.dev_stripes); dev_extent_min);
continue; continue;
} }
...@@ -4968,14 +4932,63 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans, ...@@ -4968,14 +4932,63 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
devices_info[ndevs].dev = device; devices_info[ndevs].dev = device;
++ndevs; ++ndevs;
} }
ctl.ndevs = ndevs; ctl->ndevs = ndevs;
/* /*
* now sort the devices by hole size / available space * 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); 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 * Round down to number of usable stripes, devs_increment can be any
* number so we can't use round_down() * number so we can't use round_down()
......
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