[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [RFC v5 04/11] file-posix: introduce get_sysfs_str_val for device zo
From: |
Stefan Hajnoczi |
Subject: |
Re: [RFC v5 04/11] file-posix: introduce get_sysfs_str_val for device zoned model |
Date: |
Mon, 1 Aug 2022 10:42:00 -0400 |
On Sun, 31 Jul 2022 at 21:34, Sam Li <faithilikerun@gmail.com> wrote:
>
> 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>
> ---
> block/file-posix.c | 86 ++++++++++++++++++++++++++++++++
> include/block/block_int-common.h | 3 ++
> 2 files changed, 89 insertions(+)
>
> diff --git a/block/file-posix.c b/block/file-posix.c
> index bcf898f0cb..0d8b4acdc7 100644
> --- a/block/file-posix.c
> +++ b/block/file-posix.c
> @@ -1271,6 +1271,85 @@ out:
> #endif
> }
>
> +/*
> + * Convert the zoned attribute file in sysfs to internal value.
> + */
> +static int get_sysfs_str_val(int fd, struct stat *st,
> + const char *attribute,
> + char **val) {
> +#ifdef CONFIG_LINUX
> + char buf[32];
> + char *sysfspath = NULL;
This can be g_autofree and then the explicit g_free(sysfspath) call is
no longer necessary.
> + int ret, offset;
> + int sysfd = -1;
> +
> + if (S_ISCHR(st->st_mode)) {
> + if (ioctl(fd, SG_GET_SG_TABLESIZE, &ret) == 0) {
> + return ret;
> + }
> + return -ENOTSUP;
> + }
This is for max_segments only. See my comment on the previous patch.
> +
> + if (!S_ISBLK(st->st_mode)) {
> + return -ENOTSUP;
> + }
> +
> + sysfspath = g_strdup_printf("/sys/dev/block/%u:%u/queue/%s",
> + major(st->st_rdev), minor(st->st_rdev),
> + attribute);
The code that follows can be replaced by a call to g_file_get_contents():
https://docs.gtk.org/glib/func.file_get_contents.html
Then the caller doesn't need to pre-allocate a 32-byte buffer. Instead
this function returns a string on the heap. The caller can free it
with g_free().
> + sysfd = open(sysfspath, O_RDONLY);
> + if (sysfd == -1) {
> + ret = -errno;
> + goto out;
> + }
> + offset = 0;
> + do {
> + ret = read(sysfd, buf + offset, sizeof(buf) - 1 + offset);
> + if (ret > 0) {
> + offset += ret;
> + }
> + } while (ret == -1);
I think this should be:
} while (ret == -1 && errno == EINTR);
if (ret < 0) {
ret = -errno;
goto out;
}
Otherwise there is an infinite loop when an unrecoverable error occurs.
> + /* The file is ended with '\n' */
> + if (buf[ret - 1] == '\n') {
> + buf[ret - 1] = '\0';
> + }
> +
> + if (!strncpy(*val, buf, ret)) {
> + goto out;
> + }
> +
> +out:
> + if (sysfd != -1) {
> + close(sysfd);
> + }
> + g_free(sysfspath);
> + return ret;
> +#else
> + return -ENOTSUP;
> +#endif
> +}
> +
> +static int get_sysfs_zoned_model(int fd, struct stat *st,
> + BlockZoneModel *zoned) {
> + g_autofree char *val = NULL;
> + val = g_malloc(32);
> + get_sysfs_str_val(fd, st, "zoned", &val);
> + if (!val) {
> + return -ENOTSUP;
> + }
> +
> + 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;
> +}
> +
> static int hdev_get_max_segments(int fd, struct stat *st) {
> return get_sysfs_long_val(fd, st, "max_segments");
> }
> @@ -1279,6 +1358,8 @@ 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);
> @@ -1316,6 +1397,11 @@ 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;
QEMU coding style always uses {}:
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
>
>
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Re: [RFC v5 04/11] file-posix: introduce get_sysfs_str_val for device zoned model,
Stefan Hajnoczi <=