[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH v7 2/8] file-posix: introduce get_sysfs_str_val for device zo
From: |
Sam Li |
Subject: |
Re: [PATCH v7 2/8] file-posix: introduce get_sysfs_str_val for device zoned model |
Date: |
Wed, 17 Aug 2022 00:11:41 +0800 |
Sam Li <faithilikerun@gmail.com> 于2022年8月16日周二 14:25写道:
>
> Use sysfs attribute files to get the string value of device
> zoned model. Then get_sysfs_zoned_model can convert it to
> BlockZoneModel type in QEMU.
>
> Signed-off-by: Sam Li <faithilikerun@gmail.com>
> Reviewed-by: Hannes Reinecke <hare@suse.de>
> ---
> block/file-posix.c | 93 ++++++++++++++++++--------------
> include/block/block_int-common.h | 3 ++
> 2 files changed, 55 insertions(+), 41 deletions(-)
>
> diff --git a/block/file-posix.c b/block/file-posix.c
> index 48cd096624..c07ac4c697 100644
> --- a/block/file-posix.c
> +++ b/block/file-posix.c
> @@ -1210,66 +1210,71 @@ static int hdev_get_max_hw_transfer(int fd, struct
> stat *st)
> #endif
> }
>
> -static int hdev_get_max_segments(int fd, struct stat *st)
> -{
> +/*
> + * Convert the zoned attribute file in sysfs to internal value.
> + */
> +static int get_sysfs_str_val(struct stat *st, const char *attribute,
> + char **val) {
> #ifdef CONFIG_LINUX
> - char buf[32];
> - const char *end;
> - char *sysfspath = NULL;
> + g_autofree char *sysfspath = NULL;
> int ret;
> - int sysfd = -1;
> - long max_segments;
> -
> - if (S_ISCHR(st->st_mode)) {
> - if (ioctl(fd, SG_GET_SG_TABLESIZE, &ret) == 0) {
> - return ret;
> - }
> - return -ENOTSUP;
> - }
> + size_t len;
>
> if (!S_ISBLK(st->st_mode)) {
> return -ENOTSUP;
> }
>
> - sysfspath = g_strdup_printf("/sys/dev/block/%u:%u/queue/max_segments",
> - major(st->st_rdev), minor(st->st_rdev));
> - sysfd = open(sysfspath, O_RDONLY);
> - if (sysfd == -1) {
> - ret = -errno;
> - goto out;
> + sysfspath = g_strdup_printf("/sys/dev/block/%u:%u/queue/%s",
> + major(st->st_rdev), minor(st->st_rdev),
> + attribute);
> + ret = g_file_get_contents(sysfspath, val, &len, NULL);
> + if (ret == -1) {
> + return -ENOENT;
> }
+/* The file is ended with '\n' */
+char *p;
+p = *val;
+if (*(p + len - 1) == '\n') {
+ *(p + len - 1) = '\0';
+}
I'm sorry to miss this part to make the str end with '\0'.
> - do {
> - ret = read(sysfd, buf, sizeof(buf) - 1);
> - } while (ret == -1 && errno == EINTR);
> + return ret;
> +#else
> + return -ENOTSUP;
> +#endif
> +}
> +
> +static int get_sysfs_zoned_model(struct stat *st, BlockZoneModel *zoned) {
> + g_autofree char *val = NULL;
> + int ret;
> +
> + ret = get_sysfs_str_val(st, "zoned", &val);
> if (ret < 0) {
> - ret = -errno;
> - goto out;
> - } else if (ret == 0) {
> - ret = -EIO;
> - goto out;
> + return ret;
> }
> - buf[ret] = 0;
> - /* The file is ended with '\n', pass 'end' to accept that. */
> - ret = qemu_strtol(buf, &end, 10, &max_segments);
> - if (ret == 0 && end && *end == '\n') {
> - ret = max_segments;
> +
> + if (strcmp(val, "host-managed") == 0) {
> + *zoned = BLK_Z_HM;
> + } else if (strcmp(val, "host-aware") == 0) {
> + *zoned = BLK_Z_HA;
> + } else if (strcmp(val, "none") == 0) {
> + *zoned = BLK_Z_NONE;
> + } else {
> + return -ENOTSUP;
> }
> + return 0;
> +}
>
> -out:
> - if (sysfd != -1) {
> - close(sysfd);
> +static int hdev_get_max_segments(int fd, struct stat *st) {
> + int ret;
> + if (S_ISCHR(st->st_mode)) {
> + if (ioctl(fd, SG_GET_SG_TABLESIZE, &ret) == 0) {
> + return ret;
> + }
> + return -ENOTSUP;
> }
> - g_free(sysfspath);
> - return ret;
> -#else
> - return -ENOTSUP;
> -#endif
> + return get_sysfs_long_val(st, "max_segments");
> }
>
> static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
> {
> BDRVRawState *s = bs->opaque;
> struct stat st;
> + int ret;
> + BlockZoneModel zoned;
>
> s->needs_alignment = raw_needs_alignment(bs);
> raw_probe_alignment(bs, s->fd, errp);
> @@ -1307,6 +1312,12 @@ static void raw_refresh_limits(BlockDriverState *bs,
> Error **errp)
> bs->bl.max_hw_iov = ret;
> }
> }
> +
> + ret = get_sysfs_zoned_model(s->fd, &st, &zoned);
> + if (ret < 0) {
> + zoned = BLK_Z_NONE;
> + }
> + bs->bl.zoned = zoned;
> }
>
> static int check_for_dasd(int fd)
> diff --git a/include/block/block_int-common.h
> b/include/block/block_int-common.h
> index 8947abab76..7f7863cc9e 100644
> --- a/include/block/block_int-common.h
> +++ b/include/block/block_int-common.h
> @@ -825,6 +825,9 @@ typedef struct BlockLimits {
>
> /* maximum number of iovec elements */
> int max_iov;
> +
> + /* device zone model */
> + BlockZoneModel zoned;
> } BlockLimits;
>
> typedef struct BdrvOpBlocker BdrvOpBlocker;
> --
> 2.37.1
>