qemu-block
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [RFC v3 3/5] file-posix: introduce get_sysfs_long_val for zoned devi


From: Hannes Reinecke
Subject: Re: [RFC v3 3/5] file-posix: introduce get_sysfs_long_val for zoned device information.
Date: Mon, 27 Jun 2022 09:31:23 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.4.0

On 6/27/22 02:19, Sam Li wrote:
Use sysfs attribute files to get the zoned device information in case
that ioctl() commands of zone management interface won't work. It can
return long type of value like chunk_sectors, zoned_append_max_bytes,
max_open_zones, max_active_zones.
---
  block/file-posix.c | 37 +++++++++++++++++++++++++------------
  1 file changed, 25 insertions(+), 12 deletions(-)

diff --git a/block/file-posix.c b/block/file-posix.c
index 1b8b0d351f..73c2cdfbca 100644
--- a/block/file-posix.c
+++ b/block/file-posix.c
@@ -1216,15 +1216,19 @@ static int hdev_get_max_hw_transfer(int fd, struct stat 
*st)
  #endif
  }
-static int hdev_get_max_segments(int fd, struct stat *st)
-{
+/*
+ * Get zoned device information (chunk_sectors, zoned_append_max_bytes,
+ * max_open_zones, max_active_zones) through sysfs attribute files.
+ */
+static long get_sysfs_long_val(int fd, struct stat *st,
+                               const char *attribute) {
  #ifdef CONFIG_LINUX
      char buf[32];
      const char *end;
      char *sysfspath = NULL;
      int ret;
      int sysfd = -1;
-    long max_segments;
+    long val;
if (S_ISCHR(st->st_mode)) {
          if (ioctl(fd, SG_GET_SG_TABLESIZE, &ret) == 0) {
@@ -1237,8 +1241,9 @@ static int hdev_get_max_segments(int fd, struct stat *st)
          return -ENOTSUP;
      }
- sysfspath = g_strdup_printf("/sys/dev/block/%u:%u/queue/max_segments",
-                                major(st->st_rdev), minor(st->st_rdev));
+    sysfspath = g_strdup_printf("/sys/dev/block/%u:%u/queue/%s",
+                                major(st->st_rdev), minor(st->st_rdev),
+                                attribute);
      sysfd = open(sysfspath, O_RDONLY);
      if (sysfd == -1) {
          ret = -errno;
@@ -1256,9 +1261,9 @@ static int hdev_get_max_segments(int fd, struct stat *st)
      }
      buf[ret] = 0;
      /* The file is ended with '\n', pass 'end' to accept that. */
-    ret = qemu_strtol(buf, &end, 10, &max_segments);
+    ret = qemu_strtol(buf, &end, 10, &val);
      if (ret == 0 && end && *end == '\n') {
-        ret = max_segments;
+        ret = val;
      }
out:
@@ -1272,6 +1277,15 @@ out:
  #endif
  }
+static int hdev_get_max_segments(int fd, struct stat *st) {
+    int ret;
+    ret = get_sysfs_long_val(fd, st, "max_segments");
+    if (ret < 0) {
+        return -1;
+    }
+    return ret;
+}
+
  static void raw_refresh_limits(BlockDriverState *bs, Error **errp)
  {
      BDRVRawState *s = bs->opaque;
@@ -1872,6 +1886,7 @@ static int handle_aiocb_zone_report(void *opaque) {
static int handle_aiocb_zone_mgmt(void *opaque) {
      RawPosixAIOData *aiocb = opaque;
+    BlockDriverState *s = aiocb->bs;
      int fd = aiocb->aio_fildes;
      int64_t offset = aiocb->aio_offset;
      int64_t len = aiocb->aio_nbytes;
@@ -1884,11 +1899,9 @@ static int handle_aiocb_zone_mgmt(void *opaque) {
      int64_t zone_size_mask;
      int ret;
- ret = ioctl(fd, BLKGETZONESZ, &zone_size);
-    if (ret) {
-        return -1;
-    }
-
+    g_autofree struct stat *file = g_new(struct stat, 1);
+    stat(s->filename, file);
+    zone_size = get_sysfs_long_val(fd, file, "chunk_sectors");
      zone_size_mask = zone_size - 1;
      if (offset & zone_size_mask) {
          error_report("offset is not the start of a zone");

Round of applause.

Reviewed-by: Hannes Reinecke <hare@suse.de>

Cheers,

Hannes
--
Dr. Hannes Reinecke                        Kernel Storage Architect
hare@suse.de                                      +49 911 74053 688
SUSE Software Solutions Germany GmbH, Maxfeldstr. 5, 90409 Nürnberg
HRB 36809 (AG Nürnberg), GF: Felix Imendörffer



reply via email to

[Prev in Thread] Current Thread [Next in Thread]