Message ID | 20250414053629.360672-28-hch@lst.de (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | [01/43] xfs: generalize the freespace and reserved blocks handling | expand |
On Mon, Apr 14, 2025 at 07:36:10AM +0200, Christoph Hellwig wrote: > Note really much to do here. Mostly ignore the validation and > regeneration of the bitmap and summary inodes. Eventually this > could grow a bit of validation of the hardware zone state. > > Signed-off-by: Christoph Hellwig <hch@lst.de> LGTM Reviewed-by: "Darrick J. Wong" <djwong@kernel.org> --D > --- > repair/dinode.c | 4 +++- > repair/phase5.c | 13 +++++++++++++ > repair/phase6.c | 6 ++++-- > repair/rt.c | 2 ++ > repair/rtrmap_repair.c | 33 +++++++++++++++++++++++++++++++++ > repair/xfs_repair.c | 9 ++++++--- > 6 files changed, 61 insertions(+), 6 deletions(-) > > diff --git a/repair/dinode.c b/repair/dinode.c > index 8696a838087f..7bdd3dcf15c1 100644 > --- a/repair/dinode.c > +++ b/repair/dinode.c > @@ -3585,7 +3585,9 @@ _("bad (negative) size %" PRId64 " on inode %" PRIu64 "\n"), > > validate_extsize(mp, dino, lino, dirty); > > - if (dino->di_version >= 3) > + if (dino->di_version >= 3 && > + (!xfs_has_zoned(mp) || > + dino->di_metatype != cpu_to_be16(XFS_METAFILE_RTRMAP))) > validate_cowextsize(mp, dino, lino, dirty); > > /* nsec fields cannot be larger than 1 billion */ > diff --git a/repair/phase5.c b/repair/phase5.c > index 4cf28d8ae1a2..e350b411c243 100644 > --- a/repair/phase5.c > +++ b/repair/phase5.c > @@ -630,6 +630,19 @@ void > check_rtmetadata( > struct xfs_mount *mp) > { > + if (xfs_has_zoned(mp)) { > + /* > + * Here we could/should verify the zone state a bit when we are > + * on actual zoned devices: > + * - compare hw write pointer to last written > + * - compare zone state to last written > + * > + * Note much we can do when running in zoned mode on a > + * conventional device. > + */ > + return; > + } > + > generate_rtinfo(mp); > check_rtbitmap(mp); > check_rtsummary(mp); > diff --git a/repair/phase6.c b/repair/phase6.c > index dbc090a54139..a7187e84daae 100644 > --- a/repair/phase6.c > +++ b/repair/phase6.c > @@ -3460,8 +3460,10 @@ _(" - resetting contents of realtime bitmap and summary inodes\n")); > return; > > while ((rtg = xfs_rtgroup_next(mp, rtg))) { > - ensure_rtgroup_bitmap(rtg); > - ensure_rtgroup_summary(rtg); > + if (!xfs_has_zoned(mp)) { > + ensure_rtgroup_bitmap(rtg); > + ensure_rtgroup_summary(rtg); > + } > ensure_rtgroup_rmapbt(rtg, est_fdblocks); > ensure_rtgroup_refcountbt(rtg, est_fdblocks); > } > diff --git a/repair/rt.c b/repair/rt.c > index e0a4943ee3b7..a2478fb635e3 100644 > --- a/repair/rt.c > +++ b/repair/rt.c > @@ -222,6 +222,8 @@ check_rtfile_contents( > xfs_fileoff_t bno = 0; > int error; > > + ASSERT(!xfs_has_zoned(mp)); > + > if (!ip) { > do_warn(_("unable to open %s file\n"), filename); > return; > diff --git a/repair/rtrmap_repair.c b/repair/rtrmap_repair.c > index 2b07e8943e59..955db1738fe2 100644 > --- a/repair/rtrmap_repair.c > +++ b/repair/rtrmap_repair.c > @@ -141,6 +141,37 @@ xrep_rtrmap_btree_load( > return error; > } > > +static void > +rtgroup_update_counters( > + struct xfs_rtgroup *rtg) > +{ > + struct xfs_inode *rmapip = rtg->rtg_inodes[XFS_RTGI_RMAP]; > + struct xfs_mount *mp = rtg_mount(rtg); > + uint64_t end = > + xfs_rtbxlen_to_blen(mp, rtg->rtg_extents); > + xfs_agblock_t gbno = 0; > + uint64_t used = 0; > + > + do { > + int bstate; > + xfs_extlen_t blen; > + > + bstate = get_bmap_ext(rtg_rgno(rtg), gbno, end, &blen, true); > + switch (bstate) { > + case XR_E_INUSE: > + case XR_E_INUSE_FS: > + used += blen; > + break; > + default: > + break; > + } > + > + gbno += blen; > + } while (gbno < end); > + > + rmapip->i_used_blocks = used; > +} > + > /* Update the inode counters. */ > STATIC int > xrep_rtrmap_reset_counters( > @@ -153,6 +184,8 @@ xrep_rtrmap_reset_counters( > * generated. > */ > sc->ip->i_nblocks = rr->new_fork_info.ifake.if_blocks; > + if (xfs_has_zoned(sc->mp)) > + rtgroup_update_counters(rr->rtg); > libxfs_trans_log_inode(sc->tp, sc->ip, XFS_ILOG_CORE); > > /* Quotas don't exist so we're done. */ > diff --git a/repair/xfs_repair.c b/repair/xfs_repair.c > index eeaaf6434689..7bf75c09b945 100644 > --- a/repair/xfs_repair.c > +++ b/repair/xfs_repair.c > @@ -1388,16 +1388,19 @@ main(int argc, char **argv) > * Done with the block usage maps, toss them. Realtime metadata aren't > * rebuilt until phase 6, so we have to keep them around. > */ > - if (mp->m_sb.sb_rblocks == 0) > + if (mp->m_sb.sb_rblocks == 0) { > rmaps_free(mp); > - free_bmaps(mp); > + free_bmaps(mp); > + } > > if (!bad_ino_btree) { > phase6(mp); > phase_end(mp, 6); > > - if (mp->m_sb.sb_rblocks != 0) > + if (mp->m_sb.sb_rblocks != 0) { > rmaps_free(mp); > + free_bmaps(mp); > + } > free_rtgroup_inodes(); > > phase7(mp, phase2_threads); > -- > 2.47.2 > >
diff --git a/repair/dinode.c b/repair/dinode.c index 8696a838087f..7bdd3dcf15c1 100644 --- a/repair/dinode.c +++ b/repair/dinode.c @@ -3585,7 +3585,9 @@ _("bad (negative) size %" PRId64 " on inode %" PRIu64 "\n"), validate_extsize(mp, dino, lino, dirty); - if (dino->di_version >= 3) + if (dino->di_version >= 3 && + (!xfs_has_zoned(mp) || + dino->di_metatype != cpu_to_be16(XFS_METAFILE_RTRMAP))) validate_cowextsize(mp, dino, lino, dirty); /* nsec fields cannot be larger than 1 billion */ diff --git a/repair/phase5.c b/repair/phase5.c index 4cf28d8ae1a2..e350b411c243 100644 --- a/repair/phase5.c +++ b/repair/phase5.c @@ -630,6 +630,19 @@ void check_rtmetadata( struct xfs_mount *mp) { + if (xfs_has_zoned(mp)) { + /* + * Here we could/should verify the zone state a bit when we are + * on actual zoned devices: + * - compare hw write pointer to last written + * - compare zone state to last written + * + * Note much we can do when running in zoned mode on a + * conventional device. + */ + return; + } + generate_rtinfo(mp); check_rtbitmap(mp); check_rtsummary(mp); diff --git a/repair/phase6.c b/repair/phase6.c index dbc090a54139..a7187e84daae 100644 --- a/repair/phase6.c +++ b/repair/phase6.c @@ -3460,8 +3460,10 @@ _(" - resetting contents of realtime bitmap and summary inodes\n")); return; while ((rtg = xfs_rtgroup_next(mp, rtg))) { - ensure_rtgroup_bitmap(rtg); - ensure_rtgroup_summary(rtg); + if (!xfs_has_zoned(mp)) { + ensure_rtgroup_bitmap(rtg); + ensure_rtgroup_summary(rtg); + } ensure_rtgroup_rmapbt(rtg, est_fdblocks); ensure_rtgroup_refcountbt(rtg, est_fdblocks); } diff --git a/repair/rt.c b/repair/rt.c index e0a4943ee3b7..a2478fb635e3 100644 --- a/repair/rt.c +++ b/repair/rt.c @@ -222,6 +222,8 @@ check_rtfile_contents( xfs_fileoff_t bno = 0; int error; + ASSERT(!xfs_has_zoned(mp)); + if (!ip) { do_warn(_("unable to open %s file\n"), filename); return; diff --git a/repair/rtrmap_repair.c b/repair/rtrmap_repair.c index 2b07e8943e59..955db1738fe2 100644 --- a/repair/rtrmap_repair.c +++ b/repair/rtrmap_repair.c @@ -141,6 +141,37 @@ xrep_rtrmap_btree_load( return error; } +static void +rtgroup_update_counters( + struct xfs_rtgroup *rtg) +{ + struct xfs_inode *rmapip = rtg->rtg_inodes[XFS_RTGI_RMAP]; + struct xfs_mount *mp = rtg_mount(rtg); + uint64_t end = + xfs_rtbxlen_to_blen(mp, rtg->rtg_extents); + xfs_agblock_t gbno = 0; + uint64_t used = 0; + + do { + int bstate; + xfs_extlen_t blen; + + bstate = get_bmap_ext(rtg_rgno(rtg), gbno, end, &blen, true); + switch (bstate) { + case XR_E_INUSE: + case XR_E_INUSE_FS: + used += blen; + break; + default: + break; + } + + gbno += blen; + } while (gbno < end); + + rmapip->i_used_blocks = used; +} + /* Update the inode counters. */ STATIC int xrep_rtrmap_reset_counters( @@ -153,6 +184,8 @@ xrep_rtrmap_reset_counters( * generated. */ sc->ip->i_nblocks = rr->new_fork_info.ifake.if_blocks; + if (xfs_has_zoned(sc->mp)) + rtgroup_update_counters(rr->rtg); libxfs_trans_log_inode(sc->tp, sc->ip, XFS_ILOG_CORE); /* Quotas don't exist so we're done. */ diff --git a/repair/xfs_repair.c b/repair/xfs_repair.c index eeaaf6434689..7bf75c09b945 100644 --- a/repair/xfs_repair.c +++ b/repair/xfs_repair.c @@ -1388,16 +1388,19 @@ main(int argc, char **argv) * Done with the block usage maps, toss them. Realtime metadata aren't * rebuilt until phase 6, so we have to keep them around. */ - if (mp->m_sb.sb_rblocks == 0) + if (mp->m_sb.sb_rblocks == 0) { rmaps_free(mp); - free_bmaps(mp); + free_bmaps(mp); + } if (!bad_ino_btree) { phase6(mp); phase_end(mp, 6); - if (mp->m_sb.sb_rblocks != 0) + if (mp->m_sb.sb_rblocks != 0) { rmaps_free(mp); + free_bmaps(mp); + } free_rtgroup_inodes(); phase7(mp, phase2_threads);
Note really much to do here. Mostly ignore the validation and regeneration of the bitmap and summary inodes. Eventually this could grow a bit of validation of the hardware zone state. Signed-off-by: Christoph Hellwig <hch@lst.de> --- repair/dinode.c | 4 +++- repair/phase5.c | 13 +++++++++++++ repair/phase6.c | 6 ++++-- repair/rt.c | 2 ++ repair/rtrmap_repair.c | 33 +++++++++++++++++++++++++++++++++ repair/xfs_repair.c | 9 ++++++--- 6 files changed, 61 insertions(+), 6 deletions(-)