xfs: support inode btree blockcounts in online repair

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>
This commit is contained in:
Darrick J. Wong 2020-08-26 10:48:50 -07:00
parent 1dbbff029f
commit 11f744234f
2 changed files with 37 additions and 3 deletions

View file

@ -501,19 +501,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);
}
}

View file

@ -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);