]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs: allow internal RT devices for zoned mode
authorChristoph Hellwig <hch@lst.de>
Mon, 14 Apr 2025 05:35:55 +0000 (07:35 +0200)
committerAndrey Albershteyn <aalbersh@kernel.org>
Tue, 29 Apr 2025 16:09:57 +0000 (18:09 +0200)
Source kernel commit: bdc03eb5f98f6f1ae4bd5e020d1582a23efb7799

Allow creating an RT subvolume on the same device as the main data
device.  This is mostly used for SMR HDDs where the conventional zones
are used for the data device and the sequential write required zones
for the zoned RT section.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Christoph Hellwig <hch@lst.de>
include/libxfs.h
include/xfs_mount.h
libxfs/init.c
libxfs/rdwr.c
libxfs/xfs_group.h
libxfs/xfs_rtgroup.h
libxfs/xfs_sb.c
repair/agheader.c

index 82b34b9d81c3a7a6817a10d0fedb7ad32b0e69ff..b968a2b88da372bddeab6786ab1a307ef7f2f62a 100644 (file)
@@ -293,4 +293,10 @@ static inline bool xfs_sb_version_hassparseinodes(struct xfs_sb *sbp)
                xfs_sb_has_incompat_feature(sbp, XFS_SB_FEAT_INCOMPAT_SPINODES);
 }
 
+static inline bool xfs_sb_version_haszoned(struct xfs_sb *sbp)
+{
+       return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5 &&
+               xfs_sb_has_incompat_feature(sbp, XFS_SB_FEAT_INCOMPAT_ZONED);
+}
+
 #endif /* __LIBXFS_H__ */
index 7856acfb9f8e8e555547bf0e254bdf353a0b9c19..bf9ebc25fc795a9775dad65ad40c3c349ee7a8ef 100644 (file)
@@ -53,6 +53,13 @@ struct xfs_groups {
         * rtgroup, so this mask must be 64-bit.
         */
        uint64_t                blkmask;
+
+       /*
+        * Start of the first group in the device.  This is used to support a
+        * RT device following the data device on the same block device for
+        * SMR hard drives.
+        */
+       xfs_fsblock_t           start_fsb;
 };
 
 /*
index 5b45ed3472762ca20319b0f5735ecc0eb1611eae..a186369f3fd804e330b25c84163eae2ad88f3418 100644 (file)
@@ -560,7 +560,7 @@ libxfs_buftarg_init(
                                progname);
                        exit(1);
                }
-               if (xi->rt.dev &&
+               if ((xi->rt.dev || xi->rt.dev == xi->data.dev) &&
                    (mp->m_rtdev_targp->bt_bdev != xi->rt.dev ||
                     mp->m_rtdev_targp->bt_mount != mp)) {
                        fprintf(stderr,
@@ -577,7 +577,11 @@ libxfs_buftarg_init(
        else
                mp->m_logdev_targp = libxfs_buftarg_alloc(mp, xi, &xi->log,
                                lfail);
-       mp->m_rtdev_targp = libxfs_buftarg_alloc(mp, xi, &xi->rt, rfail);
+       if (!xi->rt.dev || xi->rt.dev == xi->data.dev)
+               mp->m_rtdev_targp = mp->m_ddev_targp;
+       else
+               mp->m_rtdev_targp = libxfs_buftarg_alloc(mp, xi, &xi->rt,
+                               rfail);
 }
 
 /* Compute maximum possible height for per-AG btree types for this fs. */
@@ -978,7 +982,7 @@ libxfs_flush_mount(
                        error = err2;
        }
 
-       if (mp->m_rtdev_targp) {
+       if (mp->m_rtdev_targp && mp->m_rtdev_targp != mp->m_ddev_targp) {
                err2 = libxfs_flush_buftarg(mp->m_rtdev_targp,
                                _("realtime device"));
                if (!error)
@@ -1031,7 +1035,8 @@ libxfs_umount(
        free(mp->m_fsname);
        mp->m_fsname = NULL;
 
-       libxfs_buftarg_free(mp->m_rtdev_targp);
+       if (mp->m_rtdev_targp != mp->m_ddev_targp)
+               libxfs_buftarg_free(mp->m_rtdev_targp);
        if (mp->m_logdev_targp != mp->m_ddev_targp)
                libxfs_buftarg_free(mp->m_logdev_targp);
        libxfs_buftarg_free(mp->m_ddev_targp);
index 35be785c435a974f036ec42615b6c09174ebe7f5..f06763b38bd88c97dd46f2b8301a970b41ff6a0a 100644 (file)
@@ -175,6 +175,8 @@ libxfs_getrtsb(
        if (!mp->m_rtdev_targp->bt_bdev)
                return NULL;
 
+       ASSERT(!mp->m_sb.sb_rtstart);
+
        error = libxfs_buf_read_uncached(mp->m_rtdev_targp, XFS_RTSB_DADDR,
                        XFS_FSB_TO_BB(mp, 1), 0, &bp, &xfs_rtsb_buf_ops);
        if (error)
index 242b05627c7a6ea862c8dc0b30fc4a93281d0682..a70096113384e019ae0b095d2458d3aba379c496 100644 (file)
@@ -107,9 +107,11 @@ xfs_gbno_to_daddr(
        xfs_agblock_t           gbno)
 {
        struct xfs_mount        *mp = xg->xg_mount;
-       uint32_t                blocks = mp->m_groups[xg->xg_type].blocks;
+       struct xfs_groups       *g = &mp->m_groups[xg->xg_type];
+       xfs_fsblock_t           fsbno;
 
-       return XFS_FSB_TO_BB(mp, (xfs_fsblock_t)xg->xg_gno * blocks + gbno);
+       fsbno = (xfs_fsblock_t)xg->xg_gno * g->blocks + gbno;
+       return XFS_FSB_TO_BB(mp, g->start_fsb + fsbno);
 }
 
 static inline uint32_t
index 9c7e03f913cb5322fb16ec3fa3d699e1a111c83e..e35d1d7983275ca8e8a6e2e65fb4d738b0b87459 100644 (file)
@@ -230,7 +230,8 @@ xfs_rtb_to_daddr(
        xfs_rgnumber_t          rgno = xfs_rtb_to_rgno(mp, rtbno);
        uint64_t                start_bno = (xfs_rtblock_t)rgno * g->blocks;
 
-       return XFS_FSB_TO_BB(mp, start_bno + (rtbno & g->blkmask));
+       return XFS_FSB_TO_BB(mp,
+               g->start_fsb + start_bno + (rtbno & g->blkmask));
 }
 
 static inline xfs_rtblock_t
@@ -238,10 +239,11 @@ xfs_daddr_to_rtb(
        struct xfs_mount        *mp,
        xfs_daddr_t             daddr)
 {
-       xfs_rfsblock_t          bno = XFS_BB_TO_FSBT(mp, daddr);
+       struct xfs_groups       *g = &mp->m_groups[XG_TYPE_RTG];
+       xfs_rfsblock_t          bno;
 
+       bno = XFS_BB_TO_FSBT(mp, daddr) - g->start_fsb;
        if (xfs_has_rtgroups(mp)) {
-               struct xfs_groups *g = &mp->m_groups[XG_TYPE_RTG];
                xfs_rgnumber_t  rgno;
                uint32_t        rgbno;
 
index bc84792c565cbcb94fa2c0253f1aedbde83bda7c..a95d712363fa2b396e151e5fe1567811f1457162 100644 (file)
@@ -1201,6 +1201,7 @@ xfs_sb_mount_rextsize(
                rgs->blocks = sbp->sb_rgextents * sbp->sb_rextsize;
                rgs->blklog = mp->m_sb.sb_rgblklog;
                rgs->blkmask = xfs_mask32lo(mp->m_sb.sb_rgblklog);
+               rgs->start_fsb = mp->m_sb.sb_rtstart;
        } else {
                rgs->blocks = 0;
                rgs->blklog = 0;
index 327ba041671f9f0606c91f2afa43b98946770e7f..048e6c3143b5cf0ce7b883a59860557f8f778fd8 100644 (file)
@@ -485,7 +485,9 @@ secondary_sb_whack(
         *
         * size is the size of data which is valid for this sb.
         */
-       if (xfs_sb_version_hasmetadir(sb))
+       if (xfs_sb_version_haszoned(sb))
+               size = offsetofend(struct xfs_dsb, sb_rtreserved);
+       else if (xfs_sb_version_hasmetadir(sb))
                size = offsetofend(struct xfs_dsb, sb_pad);
        else if (xfs_sb_version_hasmetauuid(sb))
                size = offsetofend(struct xfs_dsb, sb_meta_uuid);