From: Christoph Hellwig Date: Mon, 14 Apr 2025 05:36:10 +0000 (+0200) Subject: xfs_repair: support repairing zoned file systems X-Git-Tag: v6.15.0~23 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=09836e4da195904174f658a7c1303e3baba711d5;p=thirdparty%2Fxfsprogs-dev.git xfs_repair: support repairing zoned file systems 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 Reviewed-by: Darrick J. Wong --- diff --git a/repair/dinode.c b/repair/dinode.c index 8696a838..7bdd3dcf 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 4cf28d8a..e350b411 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 a67cc0ab..75429d4c 100644 --- a/repair/phase6.c +++ b/repair/phase6.c @@ -3469,8 +3469,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 e0a4943e..a2478fb6 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 2b07e894..955db173 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 eeaaf643..7bf75c09 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);