xfs: support inode btree blockcounts in online repair
authorDarrick J. Wong <darrick.wong@oracle.com>
Wed, 26 Aug 2020 17:48:50 +0000 (10:48 -0700)
committerDarrick J. Wong <darrick.wong@oracle.com>
Wed, 16 Sep 2020 03:52:40 +0000 (20:52 -0700)
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
fs/xfs/scrub/agheader_repair.c

index 28b179d..cc919a2 100644 (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);
        }
 }
index bca2ab1..401f715 100644 (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);