btrfs-progs: zoned: introduce max_zone_append_size
The zone append write command has a maximum IO size restriction it accepts. This is because a zone append write command cannot be split, as we ask the device to place the data into a specific target zone and the device responds with the actual written location of the data. Introduce max_zone_append_size to zone_info and fs_info to track the value, so we can limit all I/O to a zoned block device that we want to write using the zone append command to the device's limits. Zone append command is mandatory for zoned btrfs. So, reject a device with max_zone_append_size == 0. Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> Signed-off-by: Naohiro Aota <naohiro.aota@wdc.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
7e520022ff
commit
3c0f83e541
|
@ -1222,6 +1222,9 @@ struct btrfs_fs_info {
|
||||||
u64 zone_size;
|
u64 zone_size;
|
||||||
u64 zoned;
|
u64 zoned;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Max size to emit ZONE_APPEND write command */
|
||||||
|
u64 max_zone_append_size;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline bool btrfs_is_zoned(const struct btrfs_fs_info *fs_info)
|
static inline bool btrfs_is_zoned(const struct btrfs_fs_info *fs_info)
|
||||||
|
|
|
@ -58,6 +58,18 @@ u64 zone_size(const char *file)
|
||||||
return strtoull((const char *)chunk, NULL, 10) << SECTOR_SHIFT;
|
return strtoull((const char *)chunk, NULL, 10) << SECTOR_SHIFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u64 max_zone_append_size(const char *file)
|
||||||
|
{
|
||||||
|
char chunk[32];
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = queue_param(file, "zone_append_max_bytes", chunk, sizeof(chunk));
|
||||||
|
if (ret <= 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return strtoull((const char *)chunk, NULL, 10);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef BTRFS_ZONED
|
#ifdef BTRFS_ZONED
|
||||||
static int report_zones(int fd, const char *file,
|
static int report_zones(int fd, const char *file,
|
||||||
struct btrfs_zoned_device_info *zinfo)
|
struct btrfs_zoned_device_info *zinfo)
|
||||||
|
@ -101,9 +113,18 @@ static int report_zones(int fd, const char *file,
|
||||||
|
|
||||||
/* Allocate the zone information array */
|
/* Allocate the zone information array */
|
||||||
zinfo->zone_size = zone_bytes;
|
zinfo->zone_size = zone_bytes;
|
||||||
|
zinfo->max_zone_append_size = max_zone_append_size(file);
|
||||||
zinfo->nr_zones = device_size / zone_bytes;
|
zinfo->nr_zones = device_size / zone_bytes;
|
||||||
if (device_size & (zone_bytes - 1))
|
if (device_size & (zone_bytes - 1))
|
||||||
zinfo->nr_zones++;
|
zinfo->nr_zones++;
|
||||||
|
|
||||||
|
if (zoned_model(file) != ZONED_NONE &&
|
||||||
|
zinfo->max_zone_append_size == 0) {
|
||||||
|
error(
|
||||||
|
"zoned: device %s does not support ZONE_APPEND command", file);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
zinfo->zones = calloc(zinfo->nr_zones, sizeof(struct blk_zone));
|
zinfo->zones = calloc(zinfo->nr_zones, sizeof(struct blk_zone));
|
||||||
if (!zinfo->zones) {
|
if (!zinfo->zones) {
|
||||||
error("zoned: no memory for zone information");
|
error("zoned: no memory for zone information");
|
||||||
|
@ -246,6 +267,7 @@ int btrfs_check_zoned_mode(struct btrfs_fs_info *fs_info)
|
||||||
u64 zoned_devices = 0;
|
u64 zoned_devices = 0;
|
||||||
u64 nr_devices = 0;
|
u64 nr_devices = 0;
|
||||||
u64 zone_size = 0;
|
u64 zone_size = 0;
|
||||||
|
u64 max_zone_append_size = 0;
|
||||||
const bool incompat_zoned = btrfs_fs_incompat(fs_info, ZONED);
|
const bool incompat_zoned = btrfs_fs_incompat(fs_info, ZONED);
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
@ -280,6 +302,11 @@ int btrfs_check_zoned_mode(struct btrfs_fs_info *fs_info)
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
if (!max_zone_append_size ||
|
||||||
|
(zone_info->max_zone_append_size &&
|
||||||
|
zone_info->max_zone_append_size < max_zone_append_size))
|
||||||
|
max_zone_append_size =
|
||||||
|
zone_info->max_zone_append_size;
|
||||||
}
|
}
|
||||||
nr_devices++;
|
nr_devices++;
|
||||||
}
|
}
|
||||||
|
@ -319,6 +346,7 @@ int btrfs_check_zoned_mode(struct btrfs_fs_info *fs_info)
|
||||||
}
|
}
|
||||||
|
|
||||||
fs_info->zone_size = zone_size;
|
fs_info->zone_size = zone_size;
|
||||||
|
fs_info->max_zone_append_size = max_zone_append_size;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -31,6 +31,7 @@ enum btrfs_zoned_model {
|
||||||
struct btrfs_zoned_device_info {
|
struct btrfs_zoned_device_info {
|
||||||
enum btrfs_zoned_model model;
|
enum btrfs_zoned_model model;
|
||||||
u64 zone_size;
|
u64 zone_size;
|
||||||
|
u64 max_zone_append_size;
|
||||||
u32 nr_zones;
|
u32 nr_zones;
|
||||||
struct blk_zone *zones;
|
struct blk_zone *zones;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue