]> git-server-git.apps.pok.os.sepia.ceph.com Git - xfsprogs-dev.git/commitdiff
xfs: split and refactor zone validation
authorChristoph Hellwig <hch@lst.de>
Sun, 22 Feb 2026 22:41:07 +0000 (14:41 -0800)
committerAndrey Albershteyn <aalbersh@kernel.org>
Wed, 8 Apr 2026 19:39:56 +0000 (21:39 +0200)
Source kernel commit: 19c5b6051ed62d8c4b1cf92e463c1bcf629107f4

Currently xfs_zone_validate mixes validating the software zone state in
the XFS realtime group with validating the hardware state reported in
struct blk_zone and deriving the write pointer from that.

Move all code that works on the realtime group to xfs_init_zone, and only
keep the hardware state validation in xfs_zone_validate.  This makes the
code more clear, and allows for better reuse in userspace.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
libxfs/libxfs_api_defs.h
libxfs/xfs_zones.c
libxfs/xfs_zones.h
repair/zoned.c

index fe00e19bada9d8016e85f5a2751697682b01e04b..d7c912e778799cc48c0f6552b02ab14f8ab055b6 100644 (file)
 #define xfs_verify_rgbno               libxfs_verify_rgbno
 #define xfs_verify_rtbno               libxfs_verify_rtbno
 #define xfs_zero_extent                        libxfs_zero_extent
-#define xfs_zone_validate              libxfs_zone_validate
+#define xfs_validate_blk_zone          libxfs_validate_blk_zone
 
 /* Please keep this list alphabetized. */
 
index e31e1dc0913efeff546f1a2be5dda5d9142fa4f6..4f9820dc54197ec3ee1b10c8e84ea61afc117497 100644 (file)
 #include "xfs_zones.h"
 
 static bool
-xfs_zone_validate_empty(
+xfs_validate_blk_zone_seq(
+       struct xfs_mount        *mp,
        struct blk_zone         *zone,
-       struct xfs_rtgroup      *rtg,
+       unsigned int            zone_no,
        xfs_rgblock_t           *write_pointer)
 {
-       struct xfs_mount        *mp = rtg_mount(rtg);
-
-       if (rtg_rmap(rtg)->i_used_blocks > 0) {
-               xfs_warn(mp, "empty zone %u has non-zero used counter (0x%x).",
-                        rtg_rgno(rtg), rtg_rmap(rtg)->i_used_blocks);
-               return false;
-       }
-
-       *write_pointer = 0;
-       return true;
-}
-
-static bool
-xfs_zone_validate_wp(
-       struct blk_zone         *zone,
-       struct xfs_rtgroup      *rtg,
-       xfs_rgblock_t           *write_pointer)
-{
-       struct xfs_mount        *mp = rtg_mount(rtg);
-       xfs_rtblock_t           wp_fsb = xfs_daddr_to_rtb(mp, zone->wp);
-
-       if (rtg_rmap(rtg)->i_used_blocks > rtg->rtg_extents) {
-               xfs_warn(mp, "zone %u has too large used counter (0x%x).",
-                        rtg_rgno(rtg), rtg_rmap(rtg)->i_used_blocks);
-               return false;
-       }
-
-       if (xfs_rtb_to_rgno(mp, wp_fsb) != rtg_rgno(rtg)) {
-               xfs_warn(mp, "zone %u write pointer (0x%llx) outside of zone.",
-                        rtg_rgno(rtg), wp_fsb);
-               return false;
-       }
-
-       *write_pointer = xfs_rtb_to_rgbno(mp, wp_fsb);
-       if (*write_pointer >= rtg->rtg_extents) {
-               xfs_warn(mp, "zone %u has invalid write pointer (0x%x).",
-                        rtg_rgno(rtg), *write_pointer);
-               return false;
-       }
-
-       return true;
-}
-
-static bool
-xfs_zone_validate_full(
-       struct blk_zone         *zone,
-       struct xfs_rtgroup      *rtg,
-       xfs_rgblock_t           *write_pointer)
-{
-       struct xfs_mount        *mp = rtg_mount(rtg);
-
-       if (rtg_rmap(rtg)->i_used_blocks > rtg->rtg_extents) {
-               xfs_warn(mp, "zone %u has too large used counter (0x%x).",
-                        rtg_rgno(rtg), rtg_rmap(rtg)->i_used_blocks);
-               return false;
-       }
-
-       *write_pointer = rtg->rtg_extents;
-       return true;
-}
-
-static bool
-xfs_zone_validate_seq(
-       struct blk_zone         *zone,
-       struct xfs_rtgroup      *rtg,
-       xfs_rgblock_t           *write_pointer)
-{
-       struct xfs_mount        *mp = rtg_mount(rtg);
-
        switch (zone->cond) {
        case BLK_ZONE_COND_EMPTY:
-               return xfs_zone_validate_empty(zone, rtg, write_pointer);
+               *write_pointer = 0;
+               return true;
        case BLK_ZONE_COND_IMP_OPEN:
        case BLK_ZONE_COND_EXP_OPEN:
        case BLK_ZONE_COND_CLOSED:
        case BLK_ZONE_COND_ACTIVE:
-               return xfs_zone_validate_wp(zone, rtg, write_pointer);
+               if (zone->wp < zone->start ||
+                   zone->wp >= zone->start + zone->capacity) {
+                       xfs_warn(mp,
+       "zone %u write pointer (%llu) outside of zone.",
+                               zone_no, zone->wp);
+                       return false;
+               }
+
+               *write_pointer = XFS_BB_TO_FSB(mp, zone->wp - zone->start);
+               return true;
        case BLK_ZONE_COND_FULL:
-               return xfs_zone_validate_full(zone, rtg, write_pointer);
+               *write_pointer = XFS_BB_TO_FSB(mp, zone->capacity);
+               return true;
        case BLK_ZONE_COND_NOT_WP:
        case BLK_ZONE_COND_OFFLINE:
        case BLK_ZONE_COND_READONLY:
                xfs_warn(mp, "zone %u has unsupported zone condition 0x%x.",
-                       rtg_rgno(rtg), zone->cond);
+                       zone_no, zone->cond);
                return false;
        default:
                xfs_warn(mp, "zone %u has unknown zone condition 0x%x.",
-                       rtg_rgno(rtg), zone->cond);
+                       zone_no, zone->cond);
                return false;
        }
 }
 
 static bool
-xfs_zone_validate_conv(
+xfs_validate_blk_zone_conv(
+       struct xfs_mount        *mp,
        struct blk_zone         *zone,
-       struct xfs_rtgroup      *rtg)
+       unsigned int            zone_no)
 {
-       struct xfs_mount        *mp = rtg_mount(rtg);
-
        switch (zone->cond) {
        case BLK_ZONE_COND_NOT_WP:
                return true;
        default:
                xfs_warn(mp,
 "conventional zone %u has unsupported zone condition 0x%x.",
-                        rtg_rgno(rtg), zone->cond);
+                        zone_no, zone->cond);
                return false;
        }
 }
 
 bool
-xfs_zone_validate(
+xfs_validate_blk_zone(
+       struct xfs_mount        *mp,
        struct blk_zone         *zone,
-       struct xfs_rtgroup      *rtg,
+       unsigned int            zone_no,
+       uint32_t                expected_size,
+       uint32_t                expected_capacity,
        xfs_rgblock_t           *write_pointer)
 {
-       struct xfs_mount        *mp = rtg_mount(rtg);
-       struct xfs_groups       *g = &mp->m_groups[XG_TYPE_RTG];
-       uint32_t                expected_size;
-
        /*
         * Check that the zone capacity matches the rtgroup size stored in the
         * superblock.  Note that all zones including the last one must have a
         * uniform capacity.
         */
-       if (XFS_BB_TO_FSB(mp, zone->capacity) != g->blocks) {
+       if (XFS_BB_TO_FSB(mp, zone->capacity) != expected_capacity) {
                xfs_warn(mp,
-"zone %u capacity (0x%llx) does not match RT group size (0x%x).",
-                       rtg_rgno(rtg), XFS_BB_TO_FSB(mp, zone->capacity),
-                       g->blocks);
+"zone %u capacity (%llu) does not match RT group size (%u).",
+                       zone_no, XFS_BB_TO_FSB(mp, zone->capacity),
+                       expected_capacity);
                return false;
        }
 
-       if (g->has_daddr_gaps) {
-               expected_size = 1 << g->blklog;
-       } else {
-               if (zone->len != zone->capacity) {
-                       xfs_warn(mp,
-"zone %u has capacity != size ((0x%llx vs 0x%llx)",
-                               rtg_rgno(rtg),
-                               XFS_BB_TO_FSB(mp, zone->len),
-                               XFS_BB_TO_FSB(mp, zone->capacity));
-                       return false;
-               }
-               expected_size = g->blocks;
-       }
-
        if (XFS_BB_TO_FSB(mp, zone->len) != expected_size) {
                xfs_warn(mp,
-"zone %u length (0x%llx) does match geometry (0x%x).",
-                       rtg_rgno(rtg), XFS_BB_TO_FSB(mp, zone->len),
+"zone %u length (%llu) does not match geometry (%u).",
+                       zone_no, XFS_BB_TO_FSB(mp, zone->len),
                        expected_size);
+               return false;
        }
 
        switch (zone->type) {
        case BLK_ZONE_TYPE_CONVENTIONAL:
-               return xfs_zone_validate_conv(zone, rtg);
+               return xfs_validate_blk_zone_conv(mp, zone, zone_no);
        case BLK_ZONE_TYPE_SEQWRITE_REQ:
-               return xfs_zone_validate_seq(zone, rtg, write_pointer);
+               return xfs_validate_blk_zone_seq(mp, zone, zone_no,
+                               write_pointer);
        default:
                xfs_warn(mp, "zoned %u has unsupported type 0x%x.",
-                       rtg_rgno(rtg), zone->type);
+                       zone_no, zone->type);
                return false;
        }
 }
index df10a34da71d6473ddebb40f10cdc89350f74d31..c16089c9a652da395743be20343841938e789b41 100644 (file)
@@ -37,7 +37,8 @@ struct blk_zone;
  */
 #define XFS_DEFAULT_MAX_OPEN_ZONES     128
 
-bool xfs_zone_validate(struct blk_zone *zone, struct xfs_rtgroup *rtg,
-       xfs_rgblock_t *write_pointer);
+bool xfs_validate_blk_zone(struct xfs_mount *mp, struct blk_zone *zone,
+       unsigned int zone_no, uint32_t expected_size,
+       uint32_t expected_capacity, xfs_rgblock_t *write_pointer);
 
 #endif /* _LIBXFS_ZONES_H */
index c721709d137064851975a6f8be591ec554d479d6..6ab91371d95af64e7228a42beba24ccd08329cfb 100644 (file)
@@ -39,7 +39,10 @@ report_zones_cb(
        if (!rtg_rmap(rtg))
                do_warn(_("no rmap inode for zone %u."), rgno);
        else
-               libxfs_zone_validate(zone, rtg, &write_pointer);
+               libxfs_validate_blk_zone(mp, zone, rtg_rgno(rtg),
+                               xfs_rtgroup_raw_size(mp),
+                               mp->m_groups[XG_TYPE_RTG].blocks,
+                               &write_pointer);
        libxfs_rtgroup_rele(rtg);
 }