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>
This commit is contained in:
parent
27c314d5ca
commit
560156cb25
|
@ -4865,22 +4865,97 @@ static void init_alloc_chunk_ctl(struct btrfs_fs_devices *fs_devices,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 = fs_devices->fs_info;
|
||||||
|
struct btrfs_device *device;
|
||||||
|
u64 total_avail;
|
||||||
|
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 = 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.
|
||||||
|
*/
|
||||||
|
list_for_each_entry(device, &fs_devices->alloc_list, dev_alloc_list) {
|
||||||
|
if (!test_bit(BTRFS_DEV_STATE_WRITEABLE, &device->dev_state)) {
|
||||||
|
WARN(1, KERN_ERR
|
||||||
|
"BTRFS: read-only device in alloc_list\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!test_bit(BTRFS_DEV_STATE_IN_FS_METADATA,
|
||||||
|
&device->dev_state) ||
|
||||||
|
test_bit(BTRFS_DEV_STATE_REPLACE_TGT, &device->dev_state))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (device->total_bytes > device->bytes_used)
|
||||||
|
total_avail = device->total_bytes - device->bytes_used;
|
||||||
|
else
|
||||||
|
total_avail = 0;
|
||||||
|
|
||||||
|
/* If there is no space on this device, skip it. */
|
||||||
|
if (total_avail == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ret = find_free_dev_extent(device, dev_extent_want, &dev_offset,
|
||||||
|
&max_avail);
|
||||||
|
if (ret && ret != -ENOSPC)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (ret == 0)
|
||||||
|
max_avail = dev_extent_want;
|
||||||
|
|
||||||
|
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=%llu",
|
||||||
|
__func__, device->devid, max_avail,
|
||||||
|
dev_extent_min);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ndevs == fs_devices->rw_devices) {
|
||||||
|
WARN(1, "%s: found more than %llu devices\n",
|
||||||
|
__func__, fs_devices->rw_devices);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
devices_info[ndevs].dev_offset = dev_offset;
|
||||||
|
devices_info[ndevs].max_avail = max_avail;
|
||||||
|
devices_info[ndevs].total_avail = total_avail;
|
||||||
|
devices_info[ndevs].dev = device;
|
||||||
|
++ndevs;
|
||||||
|
}
|
||||||
|
ctl->ndevs = ndevs;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* now sort the devices by hole size / available space
|
||||||
|
*/
|
||||||
|
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,
|
static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
|
||||||
u64 start, u64 type)
|
u64 start, u64 type)
|
||||||
{
|
{
|
||||||
struct btrfs_fs_info *info = trans->fs_info;
|
struct btrfs_fs_info *info = trans->fs_info;
|
||||||
struct btrfs_fs_devices *fs_devices = info->fs_devices;
|
struct btrfs_fs_devices *fs_devices = info->fs_devices;
|
||||||
struct btrfs_device *device;
|
|
||||||
struct map_lookup *map = NULL;
|
struct map_lookup *map = NULL;
|
||||||
struct extent_map_tree *em_tree;
|
struct extent_map_tree *em_tree;
|
||||||
struct extent_map *em;
|
struct extent_map *em;
|
||||||
struct btrfs_device_info *devices_info = NULL;
|
struct btrfs_device_info *devices_info = NULL;
|
||||||
struct alloc_chunk_ctl ctl;
|
struct alloc_chunk_ctl ctl;
|
||||||
u64 total_avail;
|
/* Number of stripes that count for block group size */
|
||||||
int data_stripes; /* number of stripes that count for
|
int data_stripes;
|
||||||
block group size */
|
|
||||||
int ret;
|
int ret;
|
||||||
int ndevs;
|
|
||||||
int i;
|
int i;
|
||||||
int j;
|
int j;
|
||||||
|
|
||||||
|
@ -4910,71 +4985,9 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
|
||||||
if (!devices_info)
|
if (!devices_info)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
/*
|
ret = gather_device_info(fs_devices, &ctl, devices_info);
|
||||||
* in the first pass through the devices list, we gather information
|
if (ret < 0)
|
||||||
* about the available holes on each device.
|
goto error;
|
||||||
*/
|
|
||||||
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");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!test_bit(BTRFS_DEV_STATE_IN_FS_METADATA,
|
|
||||||
&device->dev_state) ||
|
|
||||||
test_bit(BTRFS_DEV_STATE_REPLACE_TGT, &device->dev_state))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (device->total_bytes > device->bytes_used)
|
|
||||||
total_avail = device->total_bytes - device->bytes_used;
|
|
||||||
else
|
|
||||||
total_avail = 0;
|
|
||||||
|
|
||||||
/* If there is no space on this device, skip it. */
|
|
||||||
if (total_avail == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
ret = find_free_dev_extent(
|
|
||||||
device, ctl.max_stripe_size * ctl.dev_stripes,
|
|
||||||
&dev_offset, &max_avail);
|
|
||||||
if (ret && ret != -ENOSPC)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
if (ret == 0)
|
|
||||||
max_avail = ctl.max_stripe_size * ctl.dev_stripes;
|
|
||||||
|
|
||||||
if (max_avail < BTRFS_STRIPE_LEN * ctl.dev_stripes) {
|
|
||||||
if (btrfs_test_opt(info, ENOSPC_DEBUG))
|
|
||||||
btrfs_debug(info,
|
|
||||||
"%s: devid %llu has no free space, have=%llu want=%u",
|
|
||||||
__func__, device->devid, max_avail,
|
|
||||||
BTRFS_STRIPE_LEN * ctl.dev_stripes);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ndevs == fs_devices->rw_devices) {
|
|
||||||
WARN(1, "%s: found more than %llu devices\n",
|
|
||||||
__func__, fs_devices->rw_devices);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
devices_info[ndevs].dev_offset = dev_offset;
|
|
||||||
devices_info[ndevs].max_avail = max_avail;
|
|
||||||
devices_info[ndevs].total_avail = total_avail;
|
|
||||||
devices_info[ndevs].dev = device;
|
|
||||||
++ndevs;
|
|
||||||
}
|
|
||||||
ctl.ndevs = ndevs;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* now sort the devices by hole size / available space
|
|
||||||
*/
|
|
||||||
sort(devices_info, ctl.ndevs, sizeof(struct btrfs_device_info),
|
|
||||||
btrfs_cmp_device_info, NULL);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Round down to number of usable stripes, devs_increment can be any
|
* Round down to number of usable stripes, devs_increment can be any
|
||||||
|
|
Loading…
Reference in New Issue