On Tue, Sep 01, 2020 at 07:56:17PM -0700, Darrick J. Wong wrote: > From: Darrick J. Wong <darrick.wong@xxxxxxxxxx> > > Add the necessary bits to the online repair code to support logging the > inode btree counters when rebuilding the btrees, and to support fixing > the counters when rebuilding the AGI. > > Signed-off-by: Darrick J. Wong <darrick.wong@xxxxxxxxxx> > --- Reviewed-by: Brian Foster <bfoster@xxxxxxxxxx> > fs/xfs/libxfs/xfs_ialloc_btree.c | 16 +++++++++++++--- > fs/xfs/scrub/agheader_repair.c | 24 ++++++++++++++++++++++++ > 2 files changed, 37 insertions(+), 3 deletions(-) > > > diff --git a/fs/xfs/libxfs/xfs_ialloc_btree.c b/fs/xfs/libxfs/xfs_ialloc_btree.c > index 1df04e48bd87..219f57f4b5a7 100644 > --- a/fs/xfs/libxfs/xfs_ialloc_btree.c > +++ b/fs/xfs/libxfs/xfs_ialloc_btree.c > @@ -504,19 +504,29 @@ xfs_inobt_commit_staged_btree( > { > struct xfs_agi *agi = agbp->b_addr; > struct xbtree_afakeroot *afake = cur->bc_ag.afake; > + int fields; > > ASSERT(cur->bc_flags & XFS_BTREE_STAGING); > > if (cur->bc_btnum == XFS_BTNUM_INO) { > + fields = XFS_AGI_ROOT | XFS_AGI_LEVEL; > agi->agi_root = cpu_to_be32(afake->af_root); > agi->agi_level = cpu_to_be32(afake->af_levels); > - xfs_ialloc_log_agi(tp, agbp, XFS_AGI_ROOT | XFS_AGI_LEVEL); > + if (xfs_sb_version_hasinobtcounts(&cur->bc_mp->m_sb)) { > + agi->agi_iblocks = cpu_to_be32(afake->af_blocks); > + fields |= XFS_AGI_IBLOCKS; > + } > + xfs_ialloc_log_agi(tp, agbp, fields); > xfs_btree_commit_afakeroot(cur, tp, agbp, &xfs_inobt_ops); > } else { > + fields = XFS_AGI_FREE_ROOT | XFS_AGI_FREE_LEVEL; > agi->agi_free_root = cpu_to_be32(afake->af_root); > agi->agi_free_level = cpu_to_be32(afake->af_levels); > - xfs_ialloc_log_agi(tp, agbp, XFS_AGI_FREE_ROOT | > - XFS_AGI_FREE_LEVEL); > + if (xfs_sb_version_hasinobtcounts(&cur->bc_mp->m_sb)) { > + agi->agi_fblocks = cpu_to_be32(afake->af_blocks); > + fields |= XFS_AGI_IBLOCKS; > + } > + xfs_ialloc_log_agi(tp, agbp, fields); > xfs_btree_commit_afakeroot(cur, tp, agbp, &xfs_finobt_ops); > } > } > diff --git a/fs/xfs/scrub/agheader_repair.c b/fs/xfs/scrub/agheader_repair.c > index bca2ab1d4be9..401f71579ce6 100644 > --- a/fs/xfs/scrub/agheader_repair.c > +++ b/fs/xfs/scrub/agheader_repair.c > @@ -810,10 +810,34 @@ xrep_agi_calc_from_btrees( > error = xfs_ialloc_count_inodes(cur, &count, &freecount); > if (error) > goto err; > + if (xfs_sb_version_hasinobtcounts(&mp->m_sb)) { > + xfs_agblock_t blocks; > + > + error = xfs_btree_count_blocks(cur, &blocks); > + if (error) > + goto err; > + agi->agi_iblocks = cpu_to_be32(blocks); > + } > xfs_btree_del_cursor(cur, error); > > agi->agi_count = cpu_to_be32(count); > agi->agi_freecount = cpu_to_be32(freecount); > + > + if (xfs_sb_version_hasfinobt(&mp->m_sb) && > + xfs_sb_version_hasinobtcounts(&mp->m_sb)) { > + xfs_agblock_t blocks; > + > + cur = xfs_inobt_init_cursor(mp, sc->tp, agi_bp, sc->sa.agno, > + XFS_BTNUM_FINO); > + if (error) > + goto err; > + error = xfs_btree_count_blocks(cur, &blocks); > + if (error) > + goto err; > + xfs_btree_del_cursor(cur, error); > + agi->agi_fblocks = cpu_to_be32(blocks); > + } > + > return 0; > err: > xfs_btree_del_cursor(cur, error); >