Message ID | 159901537765.547164.7777551130535148618.stgit@magnolia (mailing list archive) |
---|---|
State | Accepted |
Headers | show |
Series | xfs: add inode btree blocks counters to the AGI header | expand |
On Tue, Sep 01, 2020 at 07:56:17PM -0700, Darrick J. Wong wrote: > From: Darrick J. Wong <darrick.wong@oracle.com> > > 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@oracle.com> > --- Reviewed-by: Brian Foster <bfoster@redhat.com> > 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); >
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);