]> git-server-git.apps.pok.os.sepia.ceph.com Git - xfsprogs-dev.git/commitdiff
libfrog: lift common zone reporting code from mkfs and repair
authorDamien Le Moal <dlemoal@kernel.org>
Wed, 28 Jan 2026 04:32:58 +0000 (05:32 +0100)
committerAndrey Albershteyn <aalbersh@kernel.org>
Wed, 28 Jan 2026 09:54:36 +0000 (10:54 +0100)
Define the new helper function xfrog_report_zones() to report zones of
a zoned block device.  This function is implemented in the new file
libfrog/zones.c and defined in the header file libfrog/zones.h and
use it from mkfs and repair instead of the previous open coded versions.

xfrog_report_zones() allocates and returns a struct blk_zone_report
structure, which can be be reused by subsequent invocations.  It is the
responsibility of the caller to free this structure after use.

Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
[hch: refactored to allow buffer reuse]
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
libfrog/Makefile
libfrog/zones.c [new file with mode: 0644]
libfrog/zones.h [new file with mode: 0644]
mkfs/xfs_mkfs.c
repair/zoned.c

index 268fa26638d760204bec18712b575ee02edb7889..9f405ffe347566661cc0f16c47e1c1dc91fae60b 100644 (file)
@@ -35,7 +35,8 @@ radix-tree.c \
 randbytes.c \
 scrub.c \
 util.c \
-workqueue.c
+workqueue.c \
+zones.c
 
 HFILES = \
 avl64.h \
@@ -65,7 +66,8 @@ radix-tree.h \
 randbytes.h \
 scrub.h \
 statx.h \
-workqueue.h
+workqueue.h \
+zones.h
 
 GETTEXT_PY = \
        gettext.py
diff --git a/libfrog/zones.c b/libfrog/zones.c
new file mode 100644 (file)
index 0000000..2276c56
--- /dev/null
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2025, Western Digital Corporation or its affiliates.
+ */
+#include "platform_defs.h"
+#include "libfrog/zones.h"
+#include <sys/ioctl.h>
+
+/* random size that allows efficient processing */
+#define ZONES_PER_REPORT               16384
+
+struct xfrog_zone_report *
+xfrog_report_zones(
+       int                     fd,
+       uint64_t                sector,
+       struct xfrog_zone_report *rep)
+{
+       if (!rep) {
+               rep = calloc(1, struct_size(rep, zones, ZONES_PER_REPORT));
+               if (!rep) {
+                       fprintf(stderr, "%s\n",
+_("Failed to allocate memory for reporting zones."));
+                       return NULL;
+               }
+       }
+
+       rep->rep.sector = sector;
+       rep->rep.nr_zones = ZONES_PER_REPORT;
+
+       if (ioctl(fd, BLKREPORTZONE, &rep->rep)) {
+               fprintf(stderr, "%s %s\n",
+_("ioctl(BLKREPORTZONE) failed:\n"),
+                       strerror(-errno));
+               free(rep);
+               return NULL;
+       }
+
+       return rep;
+}
diff --git a/libfrog/zones.h b/libfrog/zones.h
new file mode 100644 (file)
index 0000000..3592d48
--- /dev/null
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2025, Western Digital Corporation or its affiliates.
+ */
+#ifndef __LIBFROG_ZONES_H__
+#define __LIBFROG_ZONES_H__
+
+struct xfrog_zone_report {
+       struct blk_zone_report  rep;
+       struct blk_zone         zones[];
+};
+
+struct xfrog_zone_report *
+xfrog_report_zones(int fd, uint64_t sector, struct xfrog_zone_report *rep);
+
+#endif /* __LIBFROG_ZONES_H__ */
index 2230e82a2dd8266d0194ce293c31eb672bdf8b6d..a11994027c2df1e61eece3bee24285323ad6fc23 100644 (file)
@@ -14,6 +14,7 @@
 #include "libfrog/crc32cselftest.h"
 #include "libfrog/dahashselftest.h"
 #include "libfrog/fsproperties.h"
+#include "libfrog/zones.h"
 #include "proto.h"
 #include <ini.h>
 
@@ -2541,9 +2542,6 @@ struct zone_topology {
        struct zone_info        log;
 };
 
-/* random size that allows efficient processing */
-#define ZONES_PER_IOCTL                        16384
-
 static void
 zone_validate_capacity(
        struct zone_info        *zi,
@@ -2571,12 +2569,11 @@ report_zones(
        const char              *name,
        struct zone_info        *zi)
 {
-       struct blk_zone_report  *rep;
+       struct xfrog_zone_report *rep = NULL;
        bool                    found_seq = false;
-       int                     fd, ret = 0;
+       int                     fd;
        uint64_t                device_size;
        uint64_t                sector = 0;
-       size_t                  rep_size;
        unsigned int            i, n = 0;
        struct stat             st;
 
@@ -2603,32 +2600,18 @@ report_zones(
        zi->nr_zones = device_size / zi->zone_size;
        zi->nr_conv_zones = 0;
 
-       rep_size = sizeof(struct blk_zone_report) +
-                  sizeof(struct blk_zone) * ZONES_PER_IOCTL;
-       rep = malloc(rep_size);
-       if (!rep) {
-               fprintf(stderr,
-_("Failed to allocate memory for zone reporting.\n"));
-               exit(1);
-       }
-
        while (n < zi->nr_zones) {
-               struct blk_zone *zones = (struct blk_zone *)(rep + 1);
+               struct blk_zone *zones;
 
-               memset(rep, 0, rep_size);
-               rep->sector = sector;
-               rep->nr_zones = ZONES_PER_IOCTL;
-
-               ret = ioctl(fd, BLKREPORTZONE, rep);
-               if (ret) {
-                       fprintf(stderr,
-_("ioctl(BLKREPORTZONE) failed: %d!\n"), -errno);
+               rep = xfrog_report_zones(fd, sector, rep);
+               if (!rep)
                        exit(1);
-               }
-               if (!rep->nr_zones)
+
+               if (!rep->rep.nr_zones)
                        break;
 
-               for (i = 0; i < rep->nr_zones; i++) {
+               zones = rep->zones;
+               for (i = 0; i < rep->rep.nr_zones; i++) {
                        if (n >= zi->nr_zones)
                                break;
 
@@ -2675,8 +2658,8 @@ _("Unknown zone type (0x%x) found.\n"), zones[i].type);
 
                        n++;
                }
-               sector = zones[rep->nr_zones - 1].start +
-                        zones[rep->nr_zones - 1].len;
+               sector = zones[rep->rep.nr_zones - 1].start +
+                        zones[rep->rep.nr_zones - 1].len;
        }
 
        free(rep);
index 49cc43984883dcf30389407db060471ab585cfec..07e676ac7fd3f62d0ad7eb7d579354a45f04074a 100644 (file)
@@ -6,6 +6,7 @@
 #include "libxfs_priv.h"
 #include "libxfs.h"
 #include "xfs_zones.h"
+#include "libfrog/zones.h"
 #include "err_protos.h"
 #include "zoned.h"
 
@@ -50,8 +51,7 @@ check_zones(
        uint64_t                sector = XFS_FSB_TO_BB(mp, mp->m_sb.sb_rtstart);
        unsigned int            zone_size, zone_capacity;
        uint64_t                device_size;
-       size_t                  rep_size;
-       struct blk_zone_report  *rep;
+       struct xfrog_zone_report *rep = NULL;
        unsigned int            i, n = 0;
 
        if (ioctl(fd, BLKGETSIZE64, &device_size))
@@ -66,31 +66,18 @@ check_zones(
                return;
        }
 
-       rep_size = sizeof(struct blk_zone_report) +
-                  sizeof(struct blk_zone) * ZONES_PER_IOCTL;
-       rep = malloc(rep_size);
-       if (!rep) {
-               do_warn(_("malloc failed for zone report\n"));
-               return;
-       }
-
        while (n < mp->m_sb.sb_rgcount) {
-               struct blk_zone *zones = (struct blk_zone *)(rep + 1);
-               int ret;
+               struct blk_zone *zones;
 
-               memset(rep, 0, rep_size);
-               rep->sector = sector;
-               rep->nr_zones = ZONES_PER_IOCTL;
+               rep = xfrog_report_zones(fd, sector, rep);
+               if (!rep)
+                       return;
 
-               ret = ioctl(fd, BLKREPORTZONE, rep);
-               if (ret) {
-                       do_error(_("ioctl(BLKREPORTZONE) failed: %d!\n"), ret);
-                       goto out_free;
-               }
-               if (!rep->nr_zones)
+               if (!rep->rep.nr_zones)
                        break;
 
-               for (i = 0; i < rep->nr_zones; i++) {
+               zones = rep->zones;
+               for (i = 0; i < rep->rep.nr_zones; i++) {
                        if (n >= mp->m_sb.sb_rgcount)
                                break;
 
@@ -129,8 +116,8 @@ _("Inconsistent zone capacity!\n"));
                        report_zones_cb(mp, &zones[i]);
                        n++;
                }
-               sector = zones[rep->nr_zones - 1].start +
-                        zones[rep->nr_zones - 1].len;
+               sector = zones[rep->rep.nr_zones - 1].start +
+                        zones[rep->rep.nr_zones - 1].len;
        }
 
 out_free: