Message ID | 20250409075557.3535745-14-hch@lst.de (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | [01/45] xfs: generalize the freespace and reserved blocks handling | expand |
On Wed, Apr 09, 2025 at 09:55:16AM +0200, Christoph Hellwig wrote: > Signed-off-by: Christoph Hellwig <hch@lst.de> > --- > 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 82b34b9d81c3..b968a2b88da3 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 7856acfb9f8e..bf9ebc25fc79 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 b5220d2d6ffd..13df88ae43a7 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"), Hum. This change means that if you call xfs_db -c info without supplying a realtime device, the info command output will claim an internal rt device: $ truncate -s 3g /tmp/a $ truncate -s 3g /tmp/b $ mkfs.xfs -f /tmp/a -r rtdev=/tmp/b $ xfs_db -c info /tmp/a meta-data=/tmp/a isize=512 agcount=4, agsize=196608 blks = sectsz=512 attr=2, projid32bit=1 = crc=1 finobt=1, sparse=1, rmapbt=0 = reflink=0 bigtime=1 inobtcount=1 nrext64=1 = exchange=0 metadir=0 data = bsize=4096 blocks=786432, imaxpct=25 = sunit=0 swidth=0 blks naming =version 2 bsize=4096 ascii-ci=0, ftype=1, parent=0 log =internal log bsize=4096 blocks=16384, version=2 = sectsz=512 sunit=0 blks, lazy-count=1 realtime =internal extsz=4096 blocks=786432, rtextents=786432 = rgcount=0 rgsize=0 extents = zoned=0 start=0 reserved=0 The realtime device is external, you just haven't supplied one. How about: static inline const char * rtdev_name( const struct xfs_fsop_geo *geo, const char *rtname) { if (!geo->rtblocks) return _("none"); if (geo->rtstart) return _("internal"); if (!rtname) return _("external"); return rtname; } instead? --D > 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 5b45ed347276..a186369f3fd8 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 35be785c435a..f06763b38bd8 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 327ba041671f..5bb4e47e0c5b 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.47.2 > >
On Wed, Apr 09, 2025 at 08:55:48AM -0700, Darrick J. Wong wrote: > Hum. This change means that if you call xfs_db -c info without > supplying a realtime device, the info command output will claim an > internal rt device: > > $ truncate -s 3g /tmp/a > $ truncate -s 3g /tmp/b > $ mkfs.xfs -f /tmp/a -r rtdev=/tmp/b > $ xfs_db -c info /tmp/a I guess this wants a regression test while we're at it. > static inline const char * > rtdev_name( > const struct xfs_fsop_geo *geo, > const char *rtname) > { > if (!geo->rtblocks) > return _("none"); > if (geo->rtstart) > return _("internal"); > if (!rtname) > return _("external"); > return rtname; > } > > instead? That should work. Although the rtstart handling needs to be later as it doesn't exist yet here. I've added the helper for now and will see how it works out while I finish the rebase.
diff --git a/include/libxfs.h b/include/libxfs.h index 82b34b9d81c3..b968a2b88da3 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 7856acfb9f8e..bf9ebc25fc79 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 b5220d2d6ffd..13df88ae43a7 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 5b45ed347276..a186369f3fd8 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 35be785c435a..f06763b38bd8 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 327ba041671f..5bb4e47e0c5b 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);
Signed-off-by: Christoph Hellwig <hch@lst.de> --- 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(-)