From 1c8d69ef0a164dc00eb5eda5dddacacb8d8222a0 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Thu, 19 Dec 2024 19:49:36 -0800 Subject: [PATCH] FIXUP: xfs: allow internal RT devices for zoned mode Signed-off-by: Christoph Hellwig --- include/libxfs.h | 6 ++++++ include/xfs_mount.h | 7 +++++++ libfrog/fsgeom.c | 2 +- libxfs/init.c | 13 +++++++++---- libxfs/rdwr.c | 2 ++ repair/agheader.c | 4 +++- 6 files changed, 28 insertions(+), 6 deletions(-) diff --git a/include/libxfs.h b/include/libxfs.h index 82b34b9d8..b968a2b88 100644 --- a/include/libxfs.h +++ b/include/libxfs.h @@ -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__ */ diff --git a/include/xfs_mount.h b/include/xfs_mount.h index 7856acfb9..bf9ebc25f 100644 --- a/include/xfs_mount.h +++ b/include/xfs_mount.h @@ -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; }; /* diff --git a/libfrog/fsgeom.c b/libfrog/fsgeom.c index b5220d2d6..13df88ae4 100644 --- a/libfrog/fsgeom.c +++ b/libfrog/fsgeom.c @@ -81,7 +81,7 @@ xfs_report_geom( isint ? _("internal log") : logname ? logname : _("external"), geo->blocksize, geo->logblocks, logversion, "", geo->logsectsize, geo->logsunit / geo->blocksize, lazycount, - !geo->rtblocks ? _("none") : rtname ? rtname : _("external"), + !geo->rtblocks ? _("none") : rtname ? rtname : _("internal"), geo->rtextsize * geo->blocksize, (unsigned long long)geo->rtblocks, (unsigned long long)geo->rtextents, "", geo->rgcount, geo->rgextents); diff --git a/libxfs/init.c b/libxfs/init.c index 5b45ed347..a186369f3 100644 --- a/libxfs/init.c +++ b/libxfs/init.c @@ -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); diff --git a/libxfs/rdwr.c b/libxfs/rdwr.c index 35be785c4..f06763b38 100644 --- a/libxfs/rdwr.c +++ b/libxfs/rdwr.c @@ -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) diff --git a/repair/agheader.c b/repair/agheader.c index 327ba0416..5bb4e47e0 100644 --- a/repair/agheader.c +++ b/repair/agheader.c @@ -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_rtstart); + 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); -- 2.50.1