LCOV - code coverage report
Current view: top level - fs/xfs/scrub - agheader_repair.c (source / functions) Hit Total Coverage
Test: fstests of 6.5.0-rc4-xfsx @ Mon Jul 31 20:08:34 PDT 2023 Lines: 577 722 79.9 %
Date: 2023-07-31 20:08:34 Functions: 34 37 91.9 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0-or-later
       2             : /*
       3             :  * Copyright (C) 2018-2023 Oracle.  All Rights Reserved.
       4             :  * Author: Darrick J. Wong <djwong@kernel.org>
       5             :  */
       6             : #include "xfs.h"
       7             : #include "xfs_fs.h"
       8             : #include "xfs_shared.h"
       9             : #include "xfs_format.h"
      10             : #include "xfs_trans_resv.h"
      11             : #include "xfs_mount.h"
      12             : #include "xfs_btree.h"
      13             : #include "xfs_btree_staging.h"
      14             : #include "xfs_log_format.h"
      15             : #include "xfs_trans.h"
      16             : #include "xfs_sb.h"
      17             : #include "xfs_alloc.h"
      18             : #include "xfs_alloc_btree.h"
      19             : #include "xfs_ialloc.h"
      20             : #include "xfs_ialloc_btree.h"
      21             : #include "xfs_rmap.h"
      22             : #include "xfs_rmap_btree.h"
      23             : #include "xfs_refcount_btree.h"
      24             : #include "xfs_ag.h"
      25             : #include "xfs_inode.h"
      26             : #include "xfs_iunlink_item.h"
      27             : #include "scrub/scrub.h"
      28             : #include "scrub/common.h"
      29             : #include "scrub/trace.h"
      30             : #include "scrub/repair.h"
      31             : #include "scrub/bitmap.h"
      32             : #include "scrub/reap.h"
      33             : #include "scrub/xfile.h"
      34             : #include "scrub/xfarray.h"
      35             : 
      36             : /* Superblock */
      37             : 
      38             : /* Repair the superblock. */
      39             : int
      40      288194 : xrep_superblock(
      41             :         struct xfs_scrub        *sc)
      42             : {
      43      288194 :         struct xfs_mount        *mp = sc->mp;
      44      288194 :         struct xfs_buf          *bp;
      45      288194 :         xfs_agnumber_t          agno;
      46      288194 :         int                     error;
      47             : 
      48             :         /* Don't try to repair AG 0's sb; let xfs_repair deal with it. */
      49      288194 :         agno = sc->sm->sm_agno;
      50      288194 :         if (agno == 0)
      51             :                 return -EOPNOTSUPP;
      52             : 
      53      281296 :         error = xfs_sb_get_secondary(mp, sc->tp, agno, &bp);
      54      281136 :         if (error)
      55             :                 return error;
      56             : 
      57             :         /* Last chance to abort before we start committing fixes. */
      58      281147 :         if (xchk_should_terminate(sc, &error))
      59           0 :                 return error;
      60             : 
      61             :         /* Copy AG 0's superblock to this one. */
      62      281194 :         xfs_buf_zero(bp, 0, BBTOB(bp->b_length));
      63      281230 :         xfs_sb_to_disk(bp->b_addr, &mp->m_sb);
      64             : 
      65             :         /*
      66             :          * Don't write out a secondary super with NEEDSREPAIR or log incompat
      67             :          * features set, since both are ignored when set on a secondary.
      68             :          */
      69      281135 :         if (xfs_has_crc(mp)) {
      70      281149 :                 struct xfs_dsb          *sb = bp->b_addr;
      71             : 
      72      281149 :                 sb->sb_features_incompat &=
      73             :                                 ~cpu_to_be32(XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR);
      74      281149 :                 sb->sb_features_log_incompat = 0;
      75             :         }
      76             : 
      77             :         /* Write this to disk. */
      78      281135 :         xfs_trans_buf_set_type(sc->tp, bp, XFS_BLFT_SB_BUF);
      79      281159 :         xfs_trans_log_buf(sc->tp, bp, 0, BBTOB(bp->b_length) - 1);
      80      281114 :         return error;
      81             : }
      82             : 
      83             : /* AGF */
      84             : 
      85             : struct xrep_agf_allocbt {
      86             :         struct xfs_scrub        *sc;
      87             :         xfs_agblock_t           freeblks;
      88             :         xfs_agblock_t           longest;
      89             : };
      90             : 
      91             : /* Record free space shape information. */
      92             : STATIC int
      93   373849089 : xrep_agf_walk_allocbt(
      94             :         struct xfs_btree_cur            *cur,
      95             :         const struct xfs_alloc_rec_incore *rec,
      96             :         void                            *priv)
      97             : {
      98   373849089 :         struct xrep_agf_allocbt         *raa = priv;
      99   373849089 :         int                             error = 0;
     100             : 
     101   373849089 :         if (xchk_should_terminate(raa->sc, &error))
     102           0 :                 return error;
     103             : 
     104   373849301 :         raa->freeblks += rec->ar_blockcount;
     105   373849301 :         if (rec->ar_blockcount > raa->longest)
     106      950681 :                 raa->longest = rec->ar_blockcount;
     107   373849301 :         return error;
     108             : }
     109             : 
     110             : /* Does this AGFL block look sane? */
     111             : STATIC int
     112     1609489 : xrep_agf_check_agfl_block(
     113             :         struct xfs_mount        *mp,
     114             :         xfs_agblock_t           agbno,
     115             :         void                    *priv)
     116             : {
     117     1609489 :         struct xfs_scrub        *sc = priv;
     118             : 
     119     1609489 :         if (!xfs_verify_agbno(sc->sa.pag, agbno))
     120           0 :                 return -EFSCORRUPTED;
     121             :         return 0;
     122             : }
     123             : 
     124             : /*
     125             :  * Offset within the xrep_find_ag_btree array for each btree type.  Avoid the
     126             :  * XFS_BTNUM_ names here to avoid creating a sparse array.
     127             :  */
     128             : enum {
     129             :         XREP_AGF_BNOBT = 0,
     130             :         XREP_AGF_CNTBT,
     131             :         XREP_AGF_RMAPBT,
     132             :         XREP_AGF_REFCOUNTBT,
     133             :         XREP_AGF_END,
     134             :         XREP_AGF_MAX
     135             : };
     136             : 
     137             : /* Check a btree root candidate. */
     138             : static inline bool
     139             : xrep_check_btree_root(
     140             :         struct xfs_scrub                *sc,
     141             :         struct xrep_find_ag_btree       *fab)
     142             : {
     143      868685 :         return xfs_verify_agbno(sc->sa.pag, fab->root) &&
     144     1314047 :                fab->height <= fab->maxlevels;
     145             : }
     146             : 
     147             : /*
     148             :  * Given the btree roots described by *fab, find the roots, check them for
     149             :  * sanity, and pass the root data back out via *fab.
     150             :  *
     151             :  * This is /also/ a chicken and egg problem because we have to use the rmapbt
     152             :  * (rooted in the AGF) to find the btrees rooted in the AGF.  We also have no
     153             :  * idea if the btrees make any sense.  If we hit obvious corruptions in those
     154             :  * btrees we'll bail out.
     155             :  */
     156             : STATIC int
     157      211737 : xrep_agf_find_btrees(
     158             :         struct xfs_scrub                *sc,
     159             :         struct xfs_buf                  *agf_bp,
     160             :         struct xrep_find_ag_btree       *fab,
     161             :         struct xfs_buf                  *agfl_bp)
     162             : {
     163      211737 :         struct xfs_agf                  *old_agf = agf_bp->b_addr;
     164      211737 :         int                             error;
     165             : 
     166             :         /* Go find the root data. */
     167      211737 :         error = xrep_find_ag_btree_roots(sc, agf_bp, fab, agfl_bp);
     168      211738 :         if (error)
     169             :                 return error;
     170             : 
     171             :         /* We must find the bnobt, cntbt, and rmapbt roots. */
     172      635214 :         if (!xrep_check_btree_root(sc, &fab[XREP_AGF_BNOBT]) ||
     173      211738 :             !xrep_check_btree_root(sc, &fab[XREP_AGF_CNTBT]) ||
     174             :             !xrep_check_btree_root(sc, &fab[XREP_AGF_RMAPBT]))
     175             :                 return -EFSCORRUPTED;
     176             : 
     177             :         /*
     178             :          * We relied on the rmapbt to reconstruct the AGF.  If we get a
     179             :          * different root then something's seriously wrong.
     180             :          */
     181      211738 :         if (fab[XREP_AGF_RMAPBT].root !=
     182      211738 :             be32_to_cpu(old_agf->agf_roots[XFS_BTNUM_RMAPi]))
     183             :                 return -EFSCORRUPTED;
     184             : 
     185             :         /* We must find the refcountbt root if that feature is enabled. */
     186      423419 :         if (xfs_has_reflink(sc->mp) &&
     187             :             !xrep_check_btree_root(sc, &fab[XREP_AGF_REFCOUNTBT]))
     188           0 :                 return -EFSCORRUPTED;
     189             : 
     190             :         return 0;
     191             : }
     192             : 
     193             : /*
     194             :  * Reinitialize the AGF header, making an in-core copy of the old contents so
     195             :  * that we know which in-core state needs to be reinitialized.
     196             :  */
     197             : STATIC void
     198      211707 : xrep_agf_init_header(
     199             :         struct xfs_scrub        *sc,
     200             :         struct xfs_buf          *agf_bp,
     201             :         struct xfs_agf          *old_agf)
     202             : {
     203      211707 :         struct xfs_mount        *mp = sc->mp;
     204      211707 :         struct xfs_perag        *pag = sc->sa.pag;
     205      211707 :         struct xfs_agf          *agf = agf_bp->b_addr;
     206             : 
     207      423414 :         memcpy(old_agf, agf, sizeof(*old_agf));
     208      211707 :         memset(agf, 0, BBTOB(agf_bp->b_length));
     209      211707 :         agf->agf_magicnum = cpu_to_be32(XFS_AGF_MAGIC);
     210      211707 :         agf->agf_versionnum = cpu_to_be32(XFS_AGF_VERSION);
     211      211707 :         agf->agf_seqno = cpu_to_be32(pag->pag_agno);
     212      211707 :         agf->agf_length = cpu_to_be32(pag->block_count);
     213      211707 :         agf->agf_flfirst = old_agf->agf_flfirst;
     214      211707 :         agf->agf_fllast = old_agf->agf_fllast;
     215      211707 :         agf->agf_flcount = old_agf->agf_flcount;
     216      211707 :         if (xfs_has_crc(mp))
     217      211690 :                 uuid_copy(&agf->agf_uuid, &mp->m_sb.sb_meta_uuid);
     218             : 
     219             :         /* Mark the incore AGF data stale until we're done fixing things. */
     220      423220 :         ASSERT(xfs_perag_initialised_agf(pag));
     221      211610 :         clear_bit(XFS_AGSTATE_AGF_INIT, &pag->pag_opstate);
     222      211735 : }
     223             : 
     224             : /* Set btree root information in an AGF. */
     225             : STATIC void
     226      211718 : xrep_agf_set_roots(
     227             :         struct xfs_scrub                *sc,
     228             :         struct xfs_agf                  *agf,
     229             :         struct xrep_find_ag_btree       *fab)
     230             : {
     231      211718 :         agf->agf_roots[XFS_BTNUM_BNOi] =
     232      211718 :                         cpu_to_be32(fab[XREP_AGF_BNOBT].root);
     233      211718 :         agf->agf_levels[XFS_BTNUM_BNOi] =
     234      211718 :                         cpu_to_be32(fab[XREP_AGF_BNOBT].height);
     235             : 
     236      211718 :         agf->agf_roots[XFS_BTNUM_CNTi] =
     237      211718 :                         cpu_to_be32(fab[XREP_AGF_CNTBT].root);
     238      211718 :         agf->agf_levels[XFS_BTNUM_CNTi] =
     239      211718 :                         cpu_to_be32(fab[XREP_AGF_CNTBT].height);
     240             : 
     241      211718 :         agf->agf_roots[XFS_BTNUM_RMAPi] =
     242      211718 :                         cpu_to_be32(fab[XREP_AGF_RMAPBT].root);
     243      211718 :         agf->agf_levels[XFS_BTNUM_RMAPi] =
     244      211718 :                         cpu_to_be32(fab[XREP_AGF_RMAPBT].height);
     245             : 
     246      211718 :         if (xfs_has_reflink(sc->mp)) {
     247      211693 :                 agf->agf_refcount_root =
     248      211693 :                                 cpu_to_be32(fab[XREP_AGF_REFCOUNTBT].root);
     249      211693 :                 agf->agf_refcount_level =
     250      211693 :                                 cpu_to_be32(fab[XREP_AGF_REFCOUNTBT].height);
     251             :         }
     252      211718 : }
     253             : 
     254             : /* Update all AGF fields which derive from btree contents. */
     255             : STATIC int
     256      211716 : xrep_agf_calc_from_btrees(
     257             :         struct xfs_scrub        *sc,
     258             :         struct xfs_buf          *agf_bp)
     259             : {
     260      211716 :         struct xrep_agf_allocbt raa = { .sc = sc };
     261      211716 :         struct xfs_btree_cur    *cur = NULL;
     262      211716 :         struct xfs_agf          *agf = agf_bp->b_addr;
     263      211716 :         struct xfs_mount        *mp = sc->mp;
     264      211716 :         xfs_agblock_t           btreeblks;
     265      211716 :         xfs_agblock_t           blocks;
     266      211716 :         int                     error;
     267             : 
     268             :         /* Update the AGF counters from the bnobt. */
     269      211716 :         cur = xfs_allocbt_init_cursor(mp, sc->tp, agf_bp,
     270             :                         sc->sa.pag, XFS_BTNUM_BNO);
     271      211742 :         error = xfs_alloc_query_all(cur, xrep_agf_walk_allocbt, &raa);
     272      211758 :         if (error)
     273           0 :                 goto err;
     274      211758 :         error = xfs_btree_count_blocks(cur, &blocks);
     275      211717 :         if (error)
     276           0 :                 goto err;
     277      211717 :         xfs_btree_del_cursor(cur, error);
     278      211782 :         btreeblks = blocks - 1;
     279      211782 :         agf->agf_freeblks = cpu_to_be32(raa.freeblks);
     280      211782 :         agf->agf_longest = cpu_to_be32(raa.longest);
     281             : 
     282             :         /* Update the AGF counters from the cntbt. */
     283      211782 :         cur = xfs_allocbt_init_cursor(mp, sc->tp, agf_bp,
     284             :                         sc->sa.pag, XFS_BTNUM_CNT);
     285      211774 :         error = xfs_btree_count_blocks(cur, &blocks);
     286      211772 :         if (error)
     287           0 :                 goto err;
     288      211772 :         xfs_btree_del_cursor(cur, error);
     289      211786 :         btreeblks += blocks - 1;
     290             : 
     291             :         /* Update the AGF counters from the rmapbt. */
     292      211786 :         cur = xfs_rmapbt_init_cursor(mp, sc->tp, agf_bp, sc->sa.pag);
     293      211778 :         error = xfs_btree_count_blocks(cur, &blocks);
     294      211763 :         if (error)
     295           0 :                 goto err;
     296      211763 :         xfs_btree_del_cursor(cur, error);
     297      211783 :         agf->agf_rmap_blocks = cpu_to_be32(blocks);
     298      211783 :         btreeblks += blocks - 1;
     299             : 
     300      211783 :         agf->agf_btreeblks = cpu_to_be32(btreeblks);
     301             : 
     302             :         /* Update the AGF counters from the refcountbt. */
     303      211783 :         if (xfs_has_reflink(mp)) {
     304      211770 :                 cur = xfs_refcountbt_init_cursor(mp, sc->tp, agf_bp,
     305             :                                 sc->sa.pag);
     306      211760 :                 error = xfs_btree_count_blocks(cur, &blocks);
     307      211748 :                 if (error)
     308           0 :                         goto err;
     309      211748 :                 xfs_btree_del_cursor(cur, error);
     310      211772 :                 agf->agf_refcount_blocks = cpu_to_be32(blocks);
     311             :         }
     312             : 
     313             :         return 0;
     314           0 : err:
     315           0 :         xfs_btree_del_cursor(cur, error);
     316           0 :         return error;
     317             : }
     318             : 
     319             : /* Commit the new AGF and reinitialize the incore state. */
     320             : STATIC int
     321      211745 : xrep_agf_commit_new(
     322             :         struct xfs_scrub        *sc,
     323             :         struct xfs_buf          *agf_bp)
     324             : {
     325      211745 :         struct xfs_perag        *pag;
     326      211745 :         struct xfs_agf          *agf = agf_bp->b_addr;
     327             : 
     328             :         /* Trigger fdblocks recalculation */
     329      211745 :         xfs_force_summary_recalc(sc->mp);
     330             : 
     331             :         /* Write this to disk. */
     332      211786 :         xfs_trans_buf_set_type(sc->tp, agf_bp, XFS_BLFT_AGF_BUF);
     333      211767 :         xfs_trans_log_buf(sc->tp, agf_bp, 0, BBTOB(agf_bp->b_length) - 1);
     334             : 
     335             :         /* Now reinitialize the in-core counters we changed. */
     336      211714 :         pag = sc->sa.pag;
     337      211714 :         pag->pagf_btreeblks = be32_to_cpu(agf->agf_btreeblks);
     338      211714 :         pag->pagf_freeblks = be32_to_cpu(agf->agf_freeblks);
     339      211714 :         pag->pagf_longest = be32_to_cpu(agf->agf_longest);
     340      211714 :         pag->pagf_levels[XFS_BTNUM_BNOi] =
     341      211714 :                         be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNOi]);
     342      211714 :         pag->pagf_levels[XFS_BTNUM_CNTi] =
     343      211714 :                         be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi]);
     344      211714 :         pag->pagf_levels[XFS_BTNUM_RMAPi] =
     345      211714 :                         be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAPi]);
     346      211714 :         pag->pagf_refcount_level = be32_to_cpu(agf->agf_refcount_level);
     347      211714 :         set_bit(XFS_AGSTATE_AGF_INIT, &pag->pag_opstate);
     348             : 
     349      211759 :         return 0;
     350             : }
     351             : 
     352             : /* Repair the AGF. v5 filesystems only. */
     353             : int
     354      212200 : xrep_agf(
     355             :         struct xfs_scrub                *sc)
     356             : {
     357      212200 :         struct xrep_find_ag_btree       fab[XREP_AGF_MAX] = {
     358             :                 [XREP_AGF_BNOBT] = {
     359             :                         .rmap_owner = XFS_RMAP_OWN_AG,
     360             :                         .buf_ops = &xfs_bnobt_buf_ops,
     361      212200 :                         .maxlevels = sc->mp->m_alloc_maxlevels,
     362             :                 },
     363             :                 [XREP_AGF_CNTBT] = {
     364             :                         .rmap_owner = XFS_RMAP_OWN_AG,
     365             :                         .buf_ops = &xfs_cntbt_buf_ops,
     366             :                         .maxlevels = sc->mp->m_alloc_maxlevels,
     367             :                 },
     368             :                 [XREP_AGF_RMAPBT] = {
     369             :                         .rmap_owner = XFS_RMAP_OWN_AG,
     370             :                         .buf_ops = &xfs_rmapbt_buf_ops,
     371      212200 :                         .maxlevels = sc->mp->m_rmap_maxlevels,
     372             :                 },
     373             :                 [XREP_AGF_REFCOUNTBT] = {
     374             :                         .rmap_owner = XFS_RMAP_OWN_REFC,
     375             :                         .buf_ops = &xfs_refcountbt_buf_ops,
     376      212200 :                         .maxlevels = sc->mp->m_refc_maxlevels,
     377             :                 },
     378             :                 [XREP_AGF_END] = {
     379             :                         .buf_ops = NULL,
     380             :                 },
     381             :         };
     382      212200 :         struct xfs_agf                  old_agf;
     383      212200 :         struct xfs_mount                *mp = sc->mp;
     384      212200 :         struct xfs_buf                  *agf_bp;
     385      212200 :         struct xfs_buf                  *agfl_bp;
     386      212200 :         struct xfs_agf                  *agf;
     387      212200 :         int                             error;
     388             : 
     389             :         /* We require the rmapbt to rebuild anything. */
     390      212200 :         if (!xfs_has_rmapbt(mp))
     391             :                 return -EOPNOTSUPP;
     392             : 
     393             :         /*
     394             :          * Make sure we have the AGF buffer, as scrub might have decided it
     395             :          * was corrupt after xfs_alloc_read_agf failed with -EFSCORRUPTED.
     396             :          */
     397     1058513 :         error = xfs_trans_read_buf(mp, sc->tp, mp->m_ddev_targp,
     398      211730 :                         XFS_AG_DADDR(mp, sc->sa.pag->pag_agno,
     399             :                                                 XFS_AGF_DADDR(mp)),
     400      211730 :                         XFS_FSS_TO_BB(mp, 1), 0, &agf_bp, NULL);
     401      211593 :         if (error)
     402             :                 return error;
     403      211595 :         agf_bp->b_ops = &xfs_agf_buf_ops;
     404      211595 :         agf = agf_bp->b_addr;
     405             : 
     406             :         /*
     407             :          * Load the AGFL so that we can screen out OWN_AG blocks that are on
     408             :          * the AGFL now; these blocks might have once been part of the
     409             :          * bno/cnt/rmap btrees but are not now.  This is a chicken and egg
     410             :          * problem: the AGF is corrupt, so we have to trust the AGFL contents
     411             :          * because we can't do any serious cross-referencing with any of the
     412             :          * btrees rooted in the AGF.  If the AGFL contents are obviously bad
     413             :          * then we'll bail out.
     414             :          */
     415      211595 :         error = xfs_alloc_read_agfl(sc->sa.pag, sc->tp, &agfl_bp);
     416      211688 :         if (error)
     417             :                 return error;
     418             : 
     419             :         /*
     420             :          * Spot-check the AGFL blocks; if they're obviously corrupt then
     421             :          * there's nothing we can do but bail out.
     422             :          */
     423      211690 :         error = xfs_agfl_walk(sc->mp, agf_bp->b_addr, agfl_bp,
     424             :                         xrep_agf_check_agfl_block, sc);
     425      211738 :         if (error)
     426             :                 return error;
     427             : 
     428             :         /*
     429             :          * Find the AGF btree roots.  This is also a chicken-and-egg situation;
     430             :          * see the function for more details.
     431             :          */
     432      211740 :         error = xrep_agf_find_btrees(sc, agf_bp, fab, agfl_bp);
     433      211692 :         if (error)
     434             :                 return error;
     435             : 
     436             :         /* Last chance to abort before we start committing fixes. */
     437      211686 :         if (xchk_should_terminate(sc, &error))
     438           0 :                 return error;
     439             : 
     440             :         /* Start rewriting the header and implant the btrees we found. */
     441      211684 :         xrep_agf_init_header(sc, agf_bp, &old_agf);
     442      211738 :         xrep_agf_set_roots(sc, agf, fab);
     443      211706 :         error = xrep_agf_calc_from_btrees(sc, agf_bp);
     444      211771 :         if (error)
     445           0 :                 goto out_revert;
     446             : 
     447             :         /* Commit the changes and reinitialize incore state. */
     448      211771 :         return xrep_agf_commit_new(sc, agf_bp);
     449             : 
     450             : out_revert:
     451             :         /* Mark the incore AGF state stale and revert the AGF. */
     452           0 :         clear_bit(XFS_AGSTATE_AGF_INIT, &sc->sa.pag->pag_opstate);
     453           0 :         memcpy(agf, &old_agf, sizeof(old_agf));
     454           0 :         return error;
     455             : }
     456             : 
     457             : /* AGFL */
     458             : 
     459             : struct xrep_agfl {
     460             :         /* Bitmap of alleged AGFL blocks that we're not going to add. */
     461             :         struct xagb_bitmap      crossed;
     462             : 
     463             :         /* Bitmap of other OWN_AG metadata blocks. */
     464             :         struct xagb_bitmap      agmetablocks;
     465             : 
     466             :         /* Bitmap of free space. */
     467             :         struct xagb_bitmap      *freesp;
     468             : 
     469             :         /* rmapbt cursor for finding crosslinked blocks */
     470             :         struct xfs_btree_cur    *rmap_cur;
     471             : 
     472             :         struct xfs_scrub        *sc;
     473             : };
     474             : 
     475             : /* Record all OWN_AG (free space btree) information from the rmap data. */
     476             : STATIC int
     477  3984156141 : xrep_agfl_walk_rmap(
     478             :         struct xfs_btree_cur    *cur,
     479             :         const struct xfs_rmap_irec *rec,
     480             :         void                    *priv)
     481             : {
     482  3984156141 :         struct xrep_agfl        *ra = priv;
     483  3984156141 :         int                     error = 0;
     484             : 
     485  3984156141 :         if (xchk_should_terminate(ra->sc, &error))
     486           0 :                 return error;
     487             : 
     488             :         /* Record all the OWN_AG blocks. */
     489  3984168099 :         if (rec->rm_owner == XFS_RMAP_OWN_AG) {
     490    59327591 :                 error = xagb_bitmap_set(ra->freesp, rec->rm_startblock,
     491    29663925 :                                 rec->rm_blockcount);
     492    29663666 :                 if (error)
     493             :                         return error;
     494             :         }
     495             : 
     496  3984167840 :         return xagb_bitmap_set_btcur_path(&ra->agmetablocks, cur);
     497             : }
     498             : 
     499             : /* Strike out the blocks that are cross-linked according to the rmapbt. */
     500             : STATIC int
     501     1377052 : xrep_agfl_check_extent(
     502             :         uint64_t                start,
     503             :         uint64_t                len,
     504             :         void                    *priv)
     505             : {
     506     1377052 :         struct xrep_agfl        *ra = priv;
     507     1377052 :         xfs_agblock_t           agbno = start;
     508     1377052 :         xfs_agblock_t           last_agbno = agbno + len - 1;
     509     1377052 :         int                     error;
     510             : 
     511     3103556 :         while (agbno <= last_agbno) {
     512     1726420 :                 bool            other_owners;
     513             : 
     514     1726420 :                 error = xfs_rmap_has_other_keys(ra->rmap_cur, agbno, 1,
     515             :                                 &XFS_RMAP_OINFO_AG, &other_owners);
     516     1726508 :                 if (error)
     517           0 :                         return error;
     518             : 
     519     1726508 :                 if (other_owners) {
     520           0 :                         error = xagb_bitmap_set(&ra->crossed, agbno, 1);
     521           0 :                         if (error)
     522           0 :                                 return error;
     523             :                 }
     524             : 
     525     1726508 :                 if (xchk_should_terminate(ra->sc, &error))
     526           0 :                         return error;
     527     1726504 :                 agbno++;
     528             :         }
     529             : 
     530             :         return 0;
     531             : }
     532             : 
     533             : /*
     534             :  * Map out all the non-AGFL OWN_AG space in this AG so that we can deduce
     535             :  * which blocks belong to the AGFL.
     536             :  *
     537             :  * Compute the set of old AGFL blocks by subtracting from the list of OWN_AG
     538             :  * blocks the list of blocks owned by all other OWN_AG metadata (bnobt, cntbt,
     539             :  * rmapbt).  These are the old AGFL blocks, so return that list and the number
     540             :  * of blocks we're actually going to put back on the AGFL.
     541             :  */
     542             : STATIC int
     543      223833 : xrep_agfl_collect_blocks(
     544             :         struct xfs_scrub        *sc,
     545             :         struct xfs_buf          *agf_bp,
     546             :         struct xagb_bitmap      *agfl_extents,
     547             :         xfs_agblock_t           *flcount)
     548             : {
     549      223833 :         struct xrep_agfl        ra;
     550      223833 :         struct xfs_mount        *mp = sc->mp;
     551      223833 :         struct xfs_btree_cur    *cur;
     552      223833 :         int                     error;
     553             : 
     554      223833 :         ra.sc = sc;
     555      223833 :         ra.freesp = agfl_extents;
     556      223833 :         xagb_bitmap_init(&ra.agmetablocks);
     557      223767 :         xagb_bitmap_init(&ra.crossed);
     558             : 
     559             :         /* Find all space used by the free space btrees & rmapbt. */
     560      223757 :         cur = xfs_rmapbt_init_cursor(mp, sc->tp, agf_bp, sc->sa.pag);
     561      223900 :         error = xfs_rmap_query_all(cur, xrep_agfl_walk_rmap, &ra);
     562      223897 :         xfs_btree_del_cursor(cur, error);
     563      223937 :         if (error)
     564           0 :                 goto out_bmp;
     565             : 
     566             :         /* Find all blocks currently being used by the bnobt. */
     567      223937 :         cur = xfs_allocbt_init_cursor(mp, sc->tp, agf_bp,
     568             :                         sc->sa.pag, XFS_BTNUM_BNO);
     569      223921 :         error = xagb_bitmap_set_btblocks(&ra.agmetablocks, cur);
     570      223902 :         xfs_btree_del_cursor(cur, error);
     571      223948 :         if (error)
     572           0 :                 goto out_bmp;
     573             : 
     574             :         /* Find all blocks currently being used by the cntbt. */
     575      223948 :         cur = xfs_allocbt_init_cursor(mp, sc->tp, agf_bp,
     576             :                         sc->sa.pag, XFS_BTNUM_CNT);
     577      223932 :         error = xagb_bitmap_set_btblocks(&ra.agmetablocks, cur);
     578      223823 :         xfs_btree_del_cursor(cur, error);
     579      223946 :         if (error)
     580           0 :                 goto out_bmp;
     581             : 
     582             :         /*
     583             :          * Drop the freesp meta blocks that are in use by btrees.
     584             :          * The remaining blocks /should/ be AGFL blocks.
     585             :          */
     586      223946 :         error = xagb_bitmap_disunion(agfl_extents, &ra.agmetablocks);
     587      223776 :         if (error)
     588           0 :                 goto out_bmp;
     589             : 
     590             :         /* Strike out the blocks that are cross-linked. */
     591      223776 :         ra.rmap_cur = xfs_rmapbt_init_cursor(mp, sc->tp, agf_bp, sc->sa.pag);
     592      223893 :         error = xagb_bitmap_walk(agfl_extents, xrep_agfl_check_extent, &ra);
     593      223914 :         xfs_btree_del_cursor(ra.rmap_cur, error);
     594      223940 :         if (error)
     595           0 :                 goto out_bmp;
     596      223940 :         error = xagb_bitmap_disunion(agfl_extents, &ra.crossed);
     597      223869 :         if (error)
     598           0 :                 goto out_bmp;
     599             : 
     600             :         /*
     601             :          * Calculate the new AGFL size.  If we found more blocks than fit in
     602             :          * the AGFL we'll free them later.
     603             :          */
     604      223869 :         *flcount = min_t(uint64_t, xagb_bitmap_hweight(agfl_extents),
     605             :                          xfs_agfl_size(mp));
     606             : 
     607      223757 : out_bmp:
     608      223757 :         xagb_bitmap_destroy(&ra.crossed);
     609      223789 :         xagb_bitmap_destroy(&ra.agmetablocks);
     610      223854 :         return error;
     611             : }
     612             : 
     613             : /* Update the AGF and reset the in-core state. */
     614             : STATIC void
     615      223730 : xrep_agfl_update_agf(
     616             :         struct xfs_scrub        *sc,
     617             :         struct xfs_buf          *agf_bp,
     618             :         xfs_agblock_t           flcount)
     619             : {
     620      223730 :         struct xfs_agf          *agf = agf_bp->b_addr;
     621             : 
     622      223730 :         ASSERT(flcount <= xfs_agfl_size(sc->mp));
     623             : 
     624             :         /* Trigger fdblocks recalculation */
     625      223734 :         xfs_force_summary_recalc(sc->mp);
     626             : 
     627             :         /* Update the AGF counters. */
     628      447892 :         if (xfs_perag_initialised_agf(sc->sa.pag)) {
     629      223948 :                 sc->sa.pag->pagf_flcount = flcount;
     630      223948 :                 clear_bit(XFS_AGSTATE_AGFL_NEEDS_RESET,
     631      223948 :                                 &sc->sa.pag->pag_opstate);
     632             :         }
     633      223950 :         agf->agf_flfirst = cpu_to_be32(0);
     634      223950 :         agf->agf_flcount = cpu_to_be32(flcount);
     635      223950 :         if (flcount)
     636      223950 :                 agf->agf_fllast = cpu_to_be32(flcount - 1);
     637             :         else
     638           0 :                 agf->agf_fllast = cpu_to_be32(xfs_agfl_size(sc->mp) - 1);
     639             : 
     640      223950 :         xfs_alloc_log_agf(sc->tp, agf_bp,
     641             :                         XFS_AGF_FLFIRST | XFS_AGF_FLLAST | XFS_AGF_FLCOUNT);
     642      223851 : }
     643             : 
     644             : struct xrep_agfl_fill {
     645             :         struct xagb_bitmap      used_extents;
     646             :         struct xfs_scrub        *sc;
     647             :         __be32                  *agfl_bno;
     648             :         xfs_agblock_t           flcount;
     649             :         unsigned int            fl_off;
     650             : };
     651             : 
     652             : /* Fill the AGFL with whatever blocks are in this extent. */
     653             : static int
     654     1376935 : xrep_agfl_fill(
     655             :         uint64_t                start,
     656             :         uint64_t                len,
     657             :         void                    *priv)
     658             : {
     659     1376935 :         struct xrep_agfl_fill   *af = priv;
     660     1376935 :         struct xfs_scrub        *sc = af->sc;
     661     1376935 :         xfs_agblock_t           agbno = start;
     662     1376935 :         int                     error;
     663             : 
     664     1376935 :         trace_xrep_agfl_insert(sc->sa.pag, agbno, len);
     665             : 
     666     3101945 :         while (agbno < start + len && af->fl_off < af->flcount)
     667     1725010 :                 af->agfl_bno[af->fl_off++] = cpu_to_be32(agbno++);
     668             : 
     669     1376880 :         error = xagb_bitmap_set(&af->used_extents, start, agbno - 1);
     670     1377007 :         if (error)
     671             :                 return error;
     672             : 
     673     1377007 :         if (af->fl_off == af->flcount)
     674      223830 :                 return -ECANCELED;
     675             : 
     676             :         return 0;
     677             : }
     678             : 
     679             : /* Write out a totally new AGFL. */
     680             : STATIC int
     681      223803 : xrep_agfl_init_header(
     682             :         struct xfs_scrub        *sc,
     683             :         struct xfs_buf          *agfl_bp,
     684             :         struct xagb_bitmap      *agfl_extents,
     685             :         xfs_agblock_t           flcount)
     686             : {
     687      223803 :         struct xrep_agfl_fill   af = {
     688             :                 .sc             = sc,
     689             :                 .flcount        = flcount,
     690             :         };
     691      223803 :         struct xfs_mount        *mp = sc->mp;
     692      223803 :         struct xfs_agfl         *agfl;
     693      223803 :         int                     error;
     694             : 
     695      223803 :         ASSERT(flcount <= xfs_agfl_size(mp));
     696             : 
     697             :         /*
     698             :          * Start rewriting the header by setting the bno[] array to
     699             :          * NULLAGBLOCK, then setting AGFL header fields.
     700             :          */
     701      223743 :         agfl = XFS_BUF_TO_AGFL(agfl_bp);
     702      223743 :         memset(agfl, 0xFF, BBTOB(agfl_bp->b_length));
     703      223743 :         agfl->agfl_magicnum = cpu_to_be32(XFS_AGFL_MAGIC);
     704      223743 :         agfl->agfl_seqno = cpu_to_be32(sc->sa.pag->pag_agno);
     705      223743 :         uuid_copy(&agfl->agfl_uuid, &mp->m_sb.sb_meta_uuid);
     706             : 
     707             :         /*
     708             :          * Fill the AGFL with the remaining blocks.  If agfl_extents has more
     709             :          * blocks than fit in the AGFL, they will be freed in a subsequent
     710             :          * step.
     711             :          */
     712      223658 :         xagb_bitmap_init(&af.used_extents);
     713      447422 :         af.agfl_bno = xfs_buf_to_agfl_bno(agfl_bp),
     714             :         xagb_bitmap_walk(agfl_extents, xrep_agfl_fill, &af);
     715      223779 :         error = xagb_bitmap_disunion(agfl_extents, &af.used_extents);
     716      223878 :         if (error)
     717             :                 return error;
     718             : 
     719             :         /* Write new AGFL to disk. */
     720      223886 :         xfs_trans_buf_set_type(sc->tp, agfl_bp, XFS_BLFT_AGFL_BUF);
     721      223868 :         xfs_trans_log_buf(sc->tp, agfl_bp, 0, BBTOB(agfl_bp->b_length) - 1);
     722      223738 :         xagb_bitmap_destroy(&af.used_extents);
     723      223738 :         return 0;
     724             : }
     725             : 
     726             : /* Repair the AGFL. */
     727             : int
     728      224386 : xrep_agfl(
     729             :         struct xfs_scrub        *sc)
     730             : {
     731      224386 :         struct xagb_bitmap      agfl_extents;
     732      224386 :         struct xfs_mount        *mp = sc->mp;
     733      224386 :         struct xfs_buf          *agf_bp;
     734      224386 :         struct xfs_buf          *agfl_bp;
     735      224386 :         xfs_agblock_t           flcount;
     736      224386 :         int                     error;
     737             : 
     738             :         /* We require the rmapbt to rebuild anything. */
     739      224386 :         if (!xfs_has_rmapbt(mp))
     740             :                 return -EOPNOTSUPP;
     741             : 
     742      223915 :         xagb_bitmap_init(&agfl_extents);
     743             : 
     744             :         /*
     745             :          * Read the AGF so that we can query the rmapbt.  We hope that there's
     746             :          * nothing wrong with the AGF, but all the AG header repair functions
     747             :          * have this chicken-and-egg problem.
     748             :          */
     749      223811 :         error = xfs_alloc_read_agf(sc->sa.pag, sc->tp, 0, &agf_bp);
     750      223909 :         if (error)
     751             :                 return error;
     752             : 
     753             :         /*
     754             :          * Make sure we have the AGFL buffer, as scrub might have decided it
     755             :          * was corrupt after xfs_alloc_read_agfl failed with -EFSCORRUPTED.
     756             :          */
     757     1119543 :         error = xfs_trans_read_buf(mp, sc->tp, mp->m_ddev_targp,
     758      223909 :                         XFS_AG_DADDR(mp, sc->sa.pag->pag_agno,
     759             :                                                 XFS_AGFL_DADDR(mp)),
     760      223909 :                         XFS_FSS_TO_BB(mp, 1), 0, &agfl_bp, NULL);
     761      223907 :         if (error)
     762             :                 return error;
     763      223916 :         agfl_bp->b_ops = &xfs_agfl_buf_ops;
     764             : 
     765             :         /* Gather all the extents we're going to put on the new AGFL. */
     766      223916 :         error = xrep_agfl_collect_blocks(sc, agf_bp, &agfl_extents, &flcount);
     767      223798 :         if (error)
     768           0 :                 goto err;
     769             : 
     770             :         /* Last chance to abort before we start committing fixes. */
     771      223798 :         if (xchk_should_terminate(sc, &error))
     772           0 :                 goto err;
     773             : 
     774             :         /*
     775             :          * Update AGF and AGFL.  We reset the global free block counter when
     776             :          * we adjust the AGF flcount (which can fail) so avoid updating any
     777             :          * buffers until we know that part works.
     778             :          */
     779      223807 :         xrep_agfl_update_agf(sc, agf_bp, flcount);
     780      223822 :         error = xrep_agfl_init_header(sc, agfl_bp, &agfl_extents, flcount);
     781      223822 :         if (error)
     782           0 :                 goto err;
     783             : 
     784             :         /*
     785             :          * Ok, the AGFL should be ready to go now.  Roll the transaction to
     786             :          * make the new AGFL permanent before we start using it to return
     787             :          * freespace overflow to the freespace btrees.
     788             :          */
     789      223822 :         sc->sa.agf_bp = agf_bp;
     790      223822 :         error = xrep_roll_ag_trans(sc);
     791      223933 :         if (error)
     792           0 :                 goto err;
     793             : 
     794             :         /* Dump any AGFL overflow. */
     795      223933 :         error = xrep_reap_agblocks(sc, &agfl_extents, &XFS_RMAP_OINFO_AG,
     796             :                         XFS_AG_RESV_AGFL);
     797      223685 : err:
     798      223685 :         xagb_bitmap_destroy(&agfl_extents);
     799      223720 :         return error;
     800             : }
     801             : 
     802             : /* AGI */
     803             : 
     804             : /*
     805             :  * Offset within the xrep_find_ag_btree array for each btree type.  Avoid the
     806             :  * XFS_BTNUM_ names here to avoid creating a sparse array.
     807             :  */
     808             : enum {
     809             :         XREP_AGI_INOBT = 0,
     810             :         XREP_AGI_FINOBT,
     811             :         XREP_AGI_END,
     812             :         XREP_AGI_MAX
     813             : };
     814             : 
     815             : #define XREP_AGI_LOOKUP_BATCH           32
     816             : 
     817             : struct xrep_agi {
     818             :         struct xfs_scrub                *sc;
     819             : 
     820             :         /* AGI buffer, tracked separately */
     821             :         struct xfs_buf                  *agi_bp;
     822             : 
     823             :         /* context for finding btree roots */
     824             :         struct xrep_find_ag_btree       fab[XREP_AGI_MAX];
     825             : 
     826             :         /* old AGI contents in case we have to revert */
     827             :         struct xfs_agi                  old_agi;
     828             : 
     829             :         /* bitmap of which inodes are unlinked */
     830             :         struct xbitmap                  iunlink_bmp;
     831             : 
     832             :         /* heads of the unlinked inode bucket lists */
     833             :         xfs_agino_t                     iunlink_heads[XFS_AGI_UNLINKED_BUCKETS];
     834             : 
     835             :         /* scratchpad for batched lookups of the radix tree */
     836             :         struct xfs_inode                *lookup_batch[XREP_AGI_LOOKUP_BATCH];
     837             : 
     838             :         /* Map of ino -> next_ino for unlinked inode processing. */
     839             :         struct xfarray                  *iunlink_next;
     840             : 
     841             :         /* Map of ino -> prev_ino for unlinked inode processing. */
     842             :         struct xfarray                  *iunlink_prev;
     843             : };
     844             : 
     845             : static void
     846      233471 : xrep_agi_buf_cleanup(
     847             :         void            *buf)
     848             : {
     849      233471 :         struct xrep_agi *ragi = buf;
     850             : 
     851      233471 :         xfarray_destroy(ragi->iunlink_prev);
     852      233357 :         xfarray_destroy(ragi->iunlink_next);
     853      233496 :         xbitmap_destroy(&ragi->iunlink_bmp);
     854      233392 : }
     855             : 
     856             : /*
     857             :  * Given the inode btree roots described by *fab, find the roots, check them
     858             :  * for sanity, and pass the root data back out via *fab.
     859             :  */
     860             : STATIC int
     861      233469 : xrep_agi_find_btrees(
     862             :         struct xrep_agi                 *ragi)
     863             : {
     864      233469 :         struct xfs_scrub                *sc = ragi->sc;
     865      233469 :         struct xrep_find_ag_btree       *fab = ragi->fab;
     866      233469 :         struct xfs_buf                  *agf_bp;
     867      233469 :         struct xfs_mount                *mp = sc->mp;
     868      233469 :         int                             error;
     869             : 
     870             :         /* Read the AGF. */
     871      233469 :         error = xfs_alloc_read_agf(sc->sa.pag, sc->tp, 0, &agf_bp);
     872      233513 :         if (error)
     873             :                 return error;
     874             : 
     875             :         /* Find the btree roots. */
     876      233519 :         error = xrep_find_ag_btree_roots(sc, agf_bp, fab, NULL);
     877      233535 :         if (error)
     878             :                 return error;
     879             : 
     880             :         /* We must find the inobt root. */
     881      467070 :         if (!xrep_check_btree_root(sc, &fab[XREP_AGI_INOBT]))
     882             :                 return -EFSCORRUPTED;
     883             : 
     884             :         /* We must find the finobt root if that feature is enabled. */
     885      467063 :         if (xfs_has_finobt(mp) &&
     886             :             !xrep_check_btree_root(sc, &fab[XREP_AGI_FINOBT]))
     887           0 :                 return -EFSCORRUPTED;
     888             : 
     889             :         return 0;
     890             : }
     891             : 
     892             : /*
     893             :  * Reinitialize the AGI header, making an in-core copy of the old contents so
     894             :  * that we know which in-core state needs to be reinitialized.
     895             :  */
     896             : STATIC void
     897      233492 : xrep_agi_init_header(
     898             :         struct xrep_agi         *ragi)
     899             : {
     900      233492 :         struct xfs_scrub        *sc = ragi->sc;
     901      233492 :         struct xfs_buf          *agi_bp = ragi->agi_bp;
     902      233492 :         struct xfs_agi          *old_agi = &ragi->old_agi;
     903      233492 :         struct xfs_agi          *agi = agi_bp->b_addr;
     904      233492 :         struct xfs_perag        *pag = sc->sa.pag;
     905      233492 :         struct xfs_mount        *mp = sc->mp;
     906             : 
     907      466984 :         memcpy(old_agi, agi, sizeof(*old_agi));
     908      233492 :         memset(agi, 0, BBTOB(agi_bp->b_length));
     909      233492 :         agi->agi_magicnum = cpu_to_be32(XFS_AGI_MAGIC);
     910      233492 :         agi->agi_versionnum = cpu_to_be32(XFS_AGI_VERSION);
     911      233492 :         agi->agi_seqno = cpu_to_be32(pag->pag_agno);
     912      233492 :         agi->agi_length = cpu_to_be32(pag->block_count);
     913      233492 :         agi->agi_newino = cpu_to_be32(NULLAGINO);
     914      233492 :         agi->agi_dirino = cpu_to_be32(NULLAGINO);
     915      233492 :         if (xfs_has_crc(mp))
     916      233485 :                 uuid_copy(&agi->agi_uuid, &mp->m_sb.sb_meta_uuid);
     917             : 
     918             :         /* Mark the incore AGF data stale until we're done fixing things. */
     919      466812 :         ASSERT(xfs_perag_initialised_agi(pag));
     920      233406 :         clear_bit(XFS_AGSTATE_AGI_INIT, &pag->pag_opstate);
     921      233517 : }
     922             : 
     923             : /* Set btree root information in an AGI. */
     924             : STATIC void
     925      233452 : xrep_agi_set_roots(
     926             :         struct xrep_agi                 *ragi)
     927             : {
     928      233452 :         struct xfs_scrub                *sc = ragi->sc;
     929      233452 :         struct xfs_agi                  *agi = ragi->agi_bp->b_addr;
     930      233452 :         struct xrep_find_ag_btree       *fab = ragi->fab;
     931             : 
     932      233452 :         agi->agi_root = cpu_to_be32(fab[XREP_AGI_INOBT].root);
     933      233452 :         agi->agi_level = cpu_to_be32(fab[XREP_AGI_INOBT].height);
     934             : 
     935      233452 :         if (xfs_has_finobt(sc->mp)) {
     936      233433 :                 agi->agi_free_root = cpu_to_be32(fab[XREP_AGI_FINOBT].root);
     937      233433 :                 agi->agi_free_level = cpu_to_be32(fab[XREP_AGI_FINOBT].height);
     938             :         }
     939      233452 : }
     940             : 
     941             : /* Update the AGI counters. */
     942             : STATIC int
     943      233369 : xrep_agi_calc_from_btrees(
     944             :         struct xrep_agi         *ragi)
     945             : {
     946      233369 :         struct xfs_scrub        *sc = ragi->sc;
     947      233369 :         struct xfs_buf          *agi_bp = ragi->agi_bp;
     948      233369 :         struct xfs_btree_cur    *cur;
     949      233369 :         struct xfs_agi          *agi = agi_bp->b_addr;
     950      233369 :         struct xfs_mount        *mp = sc->mp;
     951      233369 :         xfs_agino_t             count;
     952      233369 :         xfs_agino_t             freecount;
     953      233369 :         int                     error;
     954             : 
     955      233369 :         cur = xfs_inobt_init_cursor(sc->sa.pag, sc->tp, agi_bp, XFS_BTNUM_INO);
     956      233512 :         error = xfs_ialloc_count_inodes(cur, &count, &freecount);
     957      233483 :         if (error)
     958           0 :                 goto err;
     959      233483 :         if (xfs_has_inobtcounts(mp)) {
     960      233442 :                 xfs_agblock_t   blocks;
     961             : 
     962      233442 :                 error = xfs_btree_count_blocks(cur, &blocks);
     963      233395 :                 if (error)
     964           0 :                         goto err;
     965      233395 :                 agi->agi_iblocks = cpu_to_be32(blocks);
     966             :         }
     967      233436 :         xfs_btree_del_cursor(cur, error);
     968             : 
     969      233541 :         agi->agi_count = cpu_to_be32(count);
     970      233541 :         agi->agi_freecount = cpu_to_be32(freecount);
     971             : 
     972      233541 :         if (xfs_has_finobt(mp) && xfs_has_inobtcounts(mp)) {
     973      233508 :                 xfs_agblock_t   blocks;
     974             : 
     975      233508 :                 cur = xfs_inobt_init_cursor(sc->sa.pag, sc->tp, agi_bp,
     976             :                                 XFS_BTNUM_FINO);
     977      233496 :                 error = xfs_btree_count_blocks(cur, &blocks);
     978      233499 :                 if (error)
     979           0 :                         goto err;
     980      233499 :                 xfs_btree_del_cursor(cur, error);
     981      233512 :                 agi->agi_fblocks = cpu_to_be32(blocks);
     982             :         }
     983             : 
     984             :         return 0;
     985           0 : err:
     986           0 :         xfs_btree_del_cursor(cur, error);
     987           0 :         return error;
     988             : }
     989             : 
     990             : /*
     991             :  * Record a forwards unlinked chain pointer from agino -> next_agino in our
     992             :  * staging information.
     993             :  */
     994             : static inline int
     995        3211 : xrep_iunlink_store_next(
     996             :         struct xrep_agi         *ragi,
     997             :         xfs_agino_t             agino,
     998             :         xfs_agino_t             next_agino)
     999             : {
    1000        3211 :         ASSERT(next_agino != 0);
    1001             : 
    1002        3211 :         return xfarray_store(ragi->iunlink_next, agino, &next_agino);
    1003             : }
    1004             : 
    1005             : /*
    1006             :  * Record a backwards unlinked chain pointer from prev_ino <- agino in our
    1007             :  * staging information.
    1008             :  */
    1009             : static inline int
    1010        3211 : xrep_iunlink_store_prev(
    1011             :         struct xrep_agi         *ragi,
    1012             :         xfs_agino_t             agino,
    1013             :         xfs_agino_t             prev_agino)
    1014             : {
    1015        3211 :         ASSERT(prev_agino != 0);
    1016             : 
    1017        3211 :         return xfarray_store(ragi->iunlink_prev, agino, &prev_agino);
    1018             : }
    1019             : 
    1020             : /* Load this inode into memory and add it to the incore unlinked list. */
    1021             : STATIC int
    1022           0 : xrep_iunlink_reload_inode(
    1023             :         struct xrep_agi         *ragi,
    1024             :         xfs_agino_t             prev_agino,
    1025             :         xfs_agino_t             agino,
    1026             :         struct xfs_inode        **ipp)
    1027             : {
    1028           0 :         struct xfs_scrub        *sc = ragi->sc;
    1029           0 :         xfs_ino_t               ino;
    1030           0 :         int                     error;
    1031             : 
    1032           0 :         ino = XFS_AGINO_TO_INO(sc->mp, sc->sa.pag->pag_agno, agino);
    1033           0 :         error = xchk_iget(ragi->sc, ino, ipp);
    1034           0 :         if (error)
    1035             :                 return error;
    1036             : 
    1037           0 :         trace_xrep_iunlink_reload(*ipp, prev_agino);
    1038             : 
    1039             :         /* If this is a linked inode, stop processing the chain. */
    1040           0 :         if (VFS_I(*ipp)->i_nlink != 0) {
    1041           0 :                 error = -EFSCORRUPTED;
    1042           0 :                 goto rele;
    1043             :         }
    1044             : 
    1045           0 :         xfs_emerg(ragi->sc->mp, "IUNLINK relink_prev agno 0x%x agino 0x%x prev ???? -> 0x%x", ragi->sc->sa.pag->pag_agno, agino, prev_agino);
    1046           0 :         (*ipp)->i_prev_unlinked = prev_agino;
    1047             : 
    1048             :         /*
    1049             :          * Drop the inode reference that we just took.  We hold the AGI, so
    1050             :          * this inode cannot move off the unlinked list and hence cannot be
    1051             :          * reclaimed.
    1052             :          */
    1053           0 : rele:
    1054           0 :         xchk_irele(sc, *ipp);
    1055           0 :         return 0;
    1056             : }
    1057             : 
    1058             : /*
    1059             :  * Walk an AGI unlinked bucket's list to load incore any unlinked inodes that
    1060             :  * still existed at mount time.  This can happen if iunlink processing fails
    1061             :  * during log recovery.
    1062             :  */
    1063             : STATIC int
    1064    14925852 : xrep_iunlink_walk_ondisk_bucket(
    1065             :         struct xrep_agi         *ragi,
    1066             :         unsigned int            bucket)
    1067             : {
    1068    14925852 :         struct xfs_scrub        *sc = ragi->sc;
    1069    14925852 :         struct xfs_inode        *ip;
    1070    14925852 :         struct xfs_agi          *agi = sc->sa.agi_bp->b_addr;
    1071    14925852 :         xfs_agino_t             prev_agino = NULLAGINO;
    1072    14925852 :         xfs_agino_t             next_agino;
    1073    14925852 :         int                     error = 0;
    1074             : 
    1075    14925852 :         next_agino = be32_to_cpu(agi->agi_unlinked[bucket]);
    1076    14929429 :         while (next_agino != NULLAGINO) {
    1077        3344 :                 if (xchk_should_terminate(ragi->sc, &error))
    1078           0 :                         return error;
    1079             : 
    1080        3211 :                 trace_xrep_iunlink_walk_ondisk_bucket(sc->sa.pag, bucket,
    1081             :                                 prev_agino, next_agino);
    1082             : 
    1083        3211 :                 ip = xfs_iunlink_lookup(sc->sa.pag, next_agino);
    1084        3211 :                 if (!ip) {
    1085             :                         /*
    1086             :                          * This unlinked inode wasn't incore.  Try to load it
    1087             :                          * and link it into the incore list.
    1088             :                          */
    1089           0 :                         error = xrep_iunlink_reload_inode(ragi, prev_agino,
    1090             :                                         next_agino, &ip);
    1091           0 :                         if (error) {
    1092             :                                 /*
    1093             :                                  * Inode cannot be resuscitated?  Terminate the
    1094             :                                  * chain.  We have other ways to find the rest
    1095             :                                  * of the inode(s) that might have been in this
    1096             :                                  * chain.
    1097             :                                  */
    1098             :                                 break;
    1099             :                         }
    1100             :                 }
    1101             : 
    1102        3211 :                 next_agino = ip->i_next_unlinked;
    1103             :         }
    1104             : 
    1105             :         return 0;
    1106             : }
    1107             : 
    1108             : /* Decide if this is an unlinked inode in this AG. */
    1109             : STATIC bool
    1110  2620771537 : xrep_iunlink_igrab(
    1111             :         struct xfs_perag        *pag,
    1112             :         struct xfs_inode        *ip)
    1113             : {
    1114  2620771537 :         struct xfs_mount        *mp = pag->pag_mount;
    1115             : 
    1116  2620771537 :         if (XFS_INO_TO_AGNO(mp, ip->i_ino) != pag->pag_agno)
    1117             :                 return false;
    1118             : 
    1119  2620779563 :         if (!xfs_inode_on_unlinked_list(ip))
    1120  2620776419 :                 return false;
    1121             : 
    1122             :         return true;
    1123             : }
    1124             : 
    1125             : /*
    1126             :  * Mark the given inode in the lookup batch in our unlinked inode bitmap, and
    1127             :  * remember if this inode is the start of the unlinked chain.
    1128             :  */
    1129             : STATIC int
    1130        3211 : xrep_iunlink_visit(
    1131             :         struct xrep_agi         *ragi,
    1132             :         unsigned int            batch_idx)
    1133             : {
    1134        3211 :         struct xfs_mount        *mp = ragi->sc->mp;
    1135        3211 :         struct xfs_inode        *ip = ragi->lookup_batch[batch_idx];
    1136        3211 :         xfs_agino_t             agino;
    1137        3211 :         unsigned int            bucket;
    1138        3211 :         int                     error;
    1139             : 
    1140        3211 :         ASSERT(XFS_INO_TO_AGNO(mp, ip->i_ino) == ragi->sc->sa.pag->pag_agno);
    1141        3211 :         ASSERT(xfs_inode_on_unlinked_list(ip));
    1142             : 
    1143        3211 :         agino = XFS_INO_TO_AGINO(mp, ip->i_ino);
    1144        3211 :         bucket = agino % XFS_AGI_UNLINKED_BUCKETS;
    1145             : 
    1146        3211 :         trace_xrep_iunlink_visit(ragi->sc->sa.pag, ragi->iunlink_heads[bucket],
    1147             :                         ip);
    1148             : 
    1149        3211 :         error = xbitmap_set(&ragi->iunlink_bmp, agino, 1);
    1150        3211 :         if (error)
    1151             :                 return error;
    1152             : 
    1153        3211 :         if (ip->i_prev_unlinked == NULLAGINO) {
    1154        3209 :                 if (ragi->iunlink_heads[bucket] == NULLAGINO)
    1155        3209 :                         ragi->iunlink_heads[bucket] = agino;
    1156             :         }
    1157             : 
    1158             :         return 0;
    1159             : }
    1160             : 
    1161             : /*
    1162             :  * Find all incore unlinked inodes so that we can rebuild the unlinked buckets.
    1163             :  * We hold the AGI so there should not be any modifications to the unlinked
    1164             :  * list.
    1165             :  */
    1166             : STATIC int
    1167      233470 : xrep_iunlink_mark_inodes(
    1168             :         struct xrep_agi         *ragi)
    1169             : {
    1170      233470 :         struct xfs_perag        *pag = ragi->sc->sa.pag;
    1171      233470 :         struct xfs_mount        *mp = pag->pag_mount;
    1172      233470 :         uint32_t                first_index = 0;
    1173      233470 :         bool                    done = false;
    1174      233470 :         unsigned int            nr_found = 0;
    1175             : 
    1176    82236675 :         do {
    1177    82236675 :                 unsigned int    i;
    1178    82236675 :                 int             error = 0;
    1179             : 
    1180    82236675 :                 if (xchk_should_terminate(ragi->sc, &error))
    1181      233304 :                         return error;
    1182             : 
    1183    82236633 :                 rcu_read_lock();
    1184             : 
    1185    82236650 :                 nr_found = radix_tree_gang_lookup(&pag->pag_ici_root,
    1186    82236650 :                                 (void **)&ragi->lookup_batch, first_index,
    1187             :                                 XREP_AGI_LOOKUP_BATCH);
    1188    82236579 :                 if (!nr_found) {
    1189      233296 :                         rcu_read_unlock();
    1190      233296 :                         return 0;
    1191             :                 }
    1192             : 
    1193  2702780955 :                 for (i = 0; i < nr_found; i++) {
    1194  2620777769 :                         struct xfs_inode *ip = ragi->lookup_batch[i];
    1195             : 
    1196  2620777163 :                         if (done || !xrep_iunlink_igrab(pag, ip))
    1197  2620775290 :                                 ragi->lookup_batch[i] = NULL;
    1198             : 
    1199             :                         /*
    1200             :                          * Update the index for the next lookup. Catch
    1201             :                          * overflows into the next AG range which can occur if
    1202             :                          * we have inodes in the last block of the AG and we
    1203             :                          * are currently pointing to the last inode.
    1204             :                          *
    1205             :                          * Because we may see inodes that are from the wrong AG
    1206             :                          * due to RCU freeing and reallocation, only update the
    1207             :                          * index if it lies in this AG. It was a race that lead
    1208             :                          * us to see this inode, so another lookup from the
    1209             :                          * same index will not find it again.
    1210             :                          */
    1211  2620777672 :                         if (XFS_INO_TO_AGNO(mp, ip->i_ino) != pag->pag_agno)
    1212           9 :                                 continue;
    1213  2620777663 :                         first_index = XFS_INO_TO_AGINO(mp, ip->i_ino + 1);
    1214  2620777663 :                         if (first_index < XFS_INO_TO_AGINO(mp, ip->i_ino))
    1215           0 :                                 done = true;
    1216             :                 }
    1217             : 
    1218             :                 /* unlock now we've grabbed the inodes. */
    1219    82003186 :                 rcu_read_unlock();
    1220             : 
    1221  2784800393 :                 for (i = 0; i < nr_found; i++) {
    1222  2620794002 :                         if (!ragi->lookup_batch[i])
    1223  2620790810 :                                 continue;
    1224        3211 :                         error = xrep_iunlink_visit(ragi, i);
    1225        3211 :                         if (error)
    1226           0 :                                 return error;
    1227             :                 }
    1228    82003205 :         } while (!done);
    1229             : 
    1230             :         return 0;
    1231             : }
    1232             : 
    1233             : /*
    1234             :  * Walk an iunlink bucket's inode list.  For each inode that should be on this
    1235             :  * chain, clear its entry in in iunlink_bmp because it's ok and we don't need
    1236             :  * to touch it further.
    1237             :  */
    1238             : STATIC int
    1239    14924302 : xrep_iunlink_clear_bucket_chain(
    1240             :         struct xrep_agi         *ragi,
    1241             :         unsigned int            bucket)
    1242             : {
    1243    14924302 :         struct xfs_scrub        *sc = ragi->sc;
    1244    14924302 :         struct xfs_inode        *ip;
    1245    14924302 :         xfs_agino_t             prev_agino = NULLAGINO;
    1246    14924302 :         xfs_agino_t             next_agino = ragi->iunlink_heads[bucket];
    1247    14924430 :         int                     error = 0;
    1248             : 
    1249    14927641 :         while (next_agino != NULLAGINO) {
    1250        3264 :                 if (xchk_should_terminate(ragi->sc, &error))
    1251           0 :                         return error;
    1252             : 
    1253        3211 :                 trace_xrep_iunlink_clear_bucket_chain(sc->sa.pag, bucket,
    1254             :                                 prev_agino, next_agino);
    1255             : 
    1256             :                 /* Find the next inode in the chain. */
    1257        3211 :                 ip = xfs_iunlink_lookup(sc->sa.pag, next_agino);
    1258        3211 :                 if (!ip) {
    1259             :                         /* Inode not incore?  Terminate the chain. */
    1260             :                         next_agino = NULLAGINO;
    1261             :                         break;
    1262             :                 }
    1263             : 
    1264        3211 :                 if (next_agino % XFS_AGI_UNLINKED_BUCKETS != bucket ||
    1265             :                     !xfs_inode_on_unlinked_list(ip)) {
    1266             :                         /*
    1267             :                          * Inode is in the wrong bucket or isn't unlinked.
    1268             :                          * Advance the list, but pretend we didn't see this
    1269             :                          * inode.
    1270             :                          */
    1271           0 :                         next_agino = ip->i_next_unlinked;
    1272           0 :                         continue;
    1273             :                 }
    1274             : 
    1275             :                 /*
    1276             :                  * Otherwise, this inode's unlinked pointers are ok.  Clear it
    1277             :                  * from the unlinked bitmap since we're done with it, and make
    1278             :                  * sure the chain is still correct.
    1279             :                  */
    1280        3211 :                 error = xbitmap_clear(&ragi->iunlink_bmp, next_agino, 1);
    1281        3211 :                 if (error)
    1282           0 :                         return error;
    1283             : 
    1284             :                 /* Remember the previous inode's next pointer. */
    1285        3211 :                 if (prev_agino != NULLAGINO) {
    1286           2 :                         error = xrep_iunlink_store_next(ragi, prev_agino,
    1287             :                                         next_agino);
    1288           2 :                         if (error)
    1289           0 :                                 return error;
    1290             :                 }
    1291             : 
    1292             :                 /* Remember this inode's previous pointer. */
    1293        3211 :                 error = xrep_iunlink_store_prev(ragi, next_agino, prev_agino);
    1294        3211 :                 if (error)
    1295           0 :                         return error;
    1296             : 
    1297             :                 /* Advance the list and remember this inode. */
    1298        3211 :                 prev_agino = next_agino;
    1299        3211 :                 next_agino = ip->i_next_unlinked;
    1300             :         }
    1301             : 
    1302             :         /* Update the previous inode's next pointer. */
    1303    14924377 :         if (prev_agino != NULLAGINO) {
    1304        3209 :                 error = xrep_iunlink_store_next(ragi, prev_agino, next_agino);
    1305        3209 :                 if (error)
    1306           0 :                         return error;
    1307             :         }
    1308             : 
    1309             :         return 0;
    1310             : }
    1311             : 
    1312             : /* Reinsert this unlinked inode into the head of the staged bucket list. */
    1313             : STATIC int
    1314           0 : xrep_iunlink_add_to_bucket(
    1315             :         struct xrep_agi         *ragi,
    1316             :         xfs_agino_t             agino)
    1317             : {
    1318           0 :         xfs_agino_t             current_head;
    1319           0 :         unsigned int            bucket;
    1320           0 :         int                     error;
    1321             : 
    1322           0 :         bucket = agino % XFS_AGI_UNLINKED_BUCKETS;
    1323             : 
    1324             :         /* Point this inode at the current head of the bucket list. */
    1325           0 :         current_head = ragi->iunlink_heads[bucket];
    1326           0 :         error = xrep_iunlink_store_next(ragi, agino, current_head);
    1327           0 :         if (error)
    1328             :                 return error;
    1329             : 
    1330             :         /* Remember the head inode's previous pointer. */
    1331           0 :         if (current_head != NULLAGINO) {
    1332           0 :                 error = xrep_iunlink_store_prev(ragi, current_head, agino);
    1333           0 :                 if (error)
    1334             :                         return error;
    1335             :         }
    1336             : 
    1337           0 :         ragi->iunlink_heads[bucket] = agino;
    1338           0 :         return 0;
    1339             : }
    1340             : 
    1341             : /* Reinsert unlinked inodes into the staged iunlink buckets. */
    1342             : STATIC int
    1343           0 : xrep_iunlink_add_lost_inodes(
    1344             :         uint64_t                start,
    1345             :         uint64_t                len,
    1346             :         void                    *priv)
    1347             : {
    1348           0 :         struct xrep_agi         *ragi = priv;
    1349           0 :         int                     error;
    1350             : 
    1351           0 :         while (len > 0) {
    1352           0 :                 error = xrep_iunlink_add_to_bucket(ragi, start);
    1353           0 :                 if (error)
    1354           0 :                         return error;
    1355             : 
    1356           0 :                 start++;
    1357           0 :                 len--;
    1358             :         }
    1359             : 
    1360             :         return 0;
    1361             : }
    1362             : 
    1363             : /*
    1364             :  * Figure out the iunlink bucket values and find inodes that need to be
    1365             :  * reinserted into the list.
    1366             :  */
    1367             : STATIC int
    1368      233477 : xrep_iunlink_rebuild_buckets(
    1369             :         struct xrep_agi         *ragi)
    1370             : {
    1371      233477 :         unsigned int            i;
    1372      233477 :         int                     error;
    1373             : 
    1374             :         /*
    1375             :          * Walk the ondisk AGI unlinked list to find inodes that are on the
    1376             :          * list but aren't in memory.  This can happen if a past log recovery
    1377             :          * tried to clear the iunlinked list but failed.  Our scan rebuilds the
    1378             :          * unlinked list using incore inodes, so we must load and link them
    1379             :          * properly.
    1380             :          */
    1381    15159349 :         for (i = 0; i < XFS_AGI_UNLINKED_BUCKETS; i++) {
    1382    14925861 :                 error = xrep_iunlink_walk_ondisk_bucket(ragi, i);
    1383    14925872 :                 if (error)
    1384           0 :                         return error;
    1385             :         }
    1386             : 
    1387             :         /* Record all the incore unlinked inodes in iunlink_bmp. */
    1388      233488 :         error = xrep_iunlink_mark_inodes(ragi);
    1389      233335 :         if (error)
    1390             :                 return error;
    1391             : 
    1392             :         /*
    1393             :          * Clear from iunlink_bmp all the unlinked inodes that are correctly
    1394             :          * linked into their incore inode bucket lists.  After this call,
    1395             :          * iunlink_bmp will contain unlinked inodes that are not in the correct
    1396             :          * list.
    1397             :          */
    1398    15157664 :         for (i = 0; i < XFS_AGI_UNLINKED_BUCKETS; i++) {
    1399    14924193 :                 error = xrep_iunlink_clear_bucket_chain(ragi, i);
    1400    14924329 :                 if (error)
    1401           0 :                         return error;
    1402             :         }
    1403             : 
    1404             :         /*
    1405             :          * Any unlinked inodes that we didn't find through the bucket list
    1406             :          * walk (or was ignored by the walk) must be inserted into the bucket
    1407             :          * list.  Stage this in memory for now.
    1408             :          */
    1409      233471 :         return xbitmap_walk(&ragi->iunlink_bmp,
    1410             :                         xrep_iunlink_add_lost_inodes, ragi);
    1411             : }
    1412             : 
    1413             : /* Update i_next_iunlinked for the inode @agino. */
    1414             : STATIC int
    1415        3211 : xrep_iunlink_relink_next(
    1416             :         struct xrep_agi         *ragi,
    1417             :         xfarray_idx_t           idx,
    1418             :         xfs_agino_t             next_agino)
    1419             : {
    1420        3211 :         struct xfs_scrub        *sc = ragi->sc;
    1421        3211 :         struct xfs_perag        *pag = sc->sa.pag;
    1422        3211 :         struct xfs_inode        *ip;
    1423        3211 :         xfarray_idx_t           agino = idx - 1;
    1424        3211 :         bool                    want_rele = false;
    1425        3211 :         int                     error = 0;
    1426             : 
    1427        3211 :         ip = xfs_iunlink_lookup(pag, agino);
    1428        3211 :         if (!ip) {
    1429           0 :                 xfs_ino_t       ino;
    1430           0 :                 xfs_agino_t     prev_agino;
    1431             : 
    1432             :                 /*
    1433             :                  * No inode exists in cache.  Load it off the disk so that we
    1434             :                  * can reinsert it into the incore unlinked list.
    1435             :                  */
    1436           0 :                 ino = XFS_AGINO_TO_INO(sc->mp, pag->pag_agno, agino);
    1437           0 :                 error = xchk_iget(sc, ino, &ip);
    1438           0 :                 if (error)
    1439           0 :                         return -EFSCORRUPTED;
    1440             : 
    1441           0 :                 want_rele = true;
    1442             : 
    1443             :                 /* Set the backward pointer since this just came off disk. */
    1444           0 :                 error = xfarray_load(ragi->iunlink_prev, agino, &prev_agino);
    1445           0 :                 if (error)
    1446           0 :                         goto out_rele;
    1447             : 
    1448           0 :                 trace_xrep_iunlink_relink_prev(ip, prev_agino);
    1449           0 :                 ip->i_prev_unlinked = prev_agino;
    1450           0 :                 xfs_emerg(ragi->sc->mp, "IUNLINK relink_prev agno 0x%x agino 0x%llx prev 0x%x -> 0x%x", ragi->sc->sa.pag->pag_agno, agino, ip->i_prev_unlinked, prev_agino);
    1451             :         }
    1452             : 
    1453             :         /* Update the forward pointer. */
    1454        3211 :         if (ip->i_next_unlinked != next_agino) {
    1455           0 :                 error = xfs_iunlink_log_inode(sc->tp, ip, pag, next_agino);
    1456           0 :                 if (error)
    1457           0 :                         goto out_rele;
    1458             : 
    1459           0 :                 trace_xrep_iunlink_relink_next(ip, next_agino);
    1460           0 :                 ip->i_next_unlinked = next_agino;
    1461           0 :                 xfs_emerg(ragi->sc->mp, "IUNLINK relink_next agno 0x%x agino 0x%llx next 0x%x -> 0x%x", ragi->sc->sa.pag->pag_agno, agino, ip->i_next_unlinked, next_agino);
    1462             :         }
    1463             : 
    1464        3211 : out_rele:
    1465             :         /*
    1466             :          * The iunlink lookup doesn't igrab because we hold the AGI buffer lock
    1467             :          * and the inode cannot be reclaimed.  However, if we used iget to load
    1468             :          * a missing inode, we must irele it here.
    1469             :          */
    1470        3211 :         if (want_rele)
    1471           0 :                 xchk_irele(sc, ip);
    1472             :         return error;
    1473             : }
    1474             : 
    1475             : /* Update i_prev_iunlinked for the inode @agino. */
    1476             : STATIC int
    1477        3211 : xrep_iunlink_relink_prev(
    1478             :         struct xrep_agi         *ragi,
    1479             :         xfarray_idx_t           idx,
    1480             :         xfs_agino_t             prev_agino)
    1481             : {
    1482        3211 :         struct xfs_scrub        *sc = ragi->sc;
    1483        3211 :         struct xfs_perag        *pag = sc->sa.pag;
    1484        3211 :         struct xfs_inode        *ip;
    1485        3211 :         xfarray_idx_t           agino = idx - 1;
    1486        3211 :         bool                    want_rele = false;
    1487        3211 :         int                     error = 0;
    1488             : 
    1489        3211 :         ASSERT(prev_agino != 0);
    1490             : 
    1491        3211 :         ip = xfs_iunlink_lookup(pag, agino);
    1492        3211 :         if (!ip) {
    1493           0 :                 xfs_ino_t       ino;
    1494           0 :                 xfs_agino_t     next_agino;
    1495             : 
    1496             :                 /*
    1497             :                  * No inode exists in cache.  Load it off the disk so that we
    1498             :                  * can reinsert it into the incore unlinked list.
    1499             :                  */
    1500           0 :                 ino = XFS_AGINO_TO_INO(sc->mp, pag->pag_agno, agino);
    1501           0 :                 error = xchk_iget(sc, ino, &ip);
    1502           0 :                 if (error)
    1503           0 :                         return -EFSCORRUPTED;
    1504             : 
    1505           0 :                 want_rele = true;
    1506             : 
    1507             :                 /* Set the forward pointer since this just came off disk. */
    1508           0 :                 error = xfarray_load(ragi->iunlink_prev, agino, &next_agino);
    1509           0 :                 if (error)
    1510           0 :                         goto out_rele;
    1511             : 
    1512           0 :                 error = xfs_iunlink_log_inode(sc->tp, ip, pag, next_agino);
    1513           0 :                 if (error)
    1514           0 :                         goto out_rele;
    1515             : 
    1516           0 :                 trace_xrep_iunlink_relink_next(ip, next_agino);
    1517           0 :                 ip->i_next_unlinked = next_agino;
    1518           0 :                 xfs_emerg(ragi->sc->mp, "IUNLINK relink_next agno 0x%x agino 0x%llx next 0x%x -> 0x%x", ragi->sc->sa.pag->pag_agno, agino, ip->i_next_unlinked, next_agino);
    1519             :         }
    1520             : 
    1521             :         /* Update the backward pointer. */
    1522        3211 :         if (ip->i_prev_unlinked != prev_agino) {
    1523           0 :                 trace_xrep_iunlink_relink_prev(ip, prev_agino);
    1524           0 :                 ip->i_prev_unlinked = prev_agino;
    1525           0 :                 xfs_emerg(ragi->sc->mp, "IUNLINK relink_prev agno 0x%x agino 0x%llx prev 0x%x -> 0x%x", ragi->sc->sa.pag->pag_agno, agino, ip->i_prev_unlinked, prev_agino);
    1526             :         }
    1527             : 
    1528        3211 : out_rele:
    1529             :         /*
    1530             :          * The iunlink lookup doesn't igrab because we hold the AGI buffer lock
    1531             :          * and the inode cannot be reclaimed.  However, if we used iget to load
    1532             :          * a missing inode, we must irele it here.
    1533             :          */
    1534        3211 :         if (want_rele)
    1535           0 :                 xchk_irele(sc, ip);
    1536             :         return error;
    1537             : }
    1538             : 
    1539             : /* Log all the iunlink updates we need to finish regenerating the AGI. */
    1540             : STATIC int
    1541      233404 : xrep_iunlink_commit(
    1542             :         struct xrep_agi         *ragi)
    1543             : {
    1544      233404 :         struct xfs_agi          *agi = ragi->agi_bp->b_addr;
    1545      233404 :         xfarray_idx_t           idx = XFARRAY_CURSOR_INIT;
    1546      233404 :         xfs_agino_t             agino;
    1547      233404 :         unsigned int            i;
    1548      233404 :         int                     error;
    1549             : 
    1550             :         /* Fix all the forward links */
    1551      236615 :         while ((error = xfarray_iter(ragi->iunlink_next, &idx, &agino)) == 1) {
    1552        3211 :                 error = xrep_iunlink_relink_next(ragi, idx, agino);
    1553        3211 :                 if (error) {
    1554           0 :                         xfs_emerg(ragi->sc->mp, "IUNLINK relink_forw failed agno 0x%x agino 0x%llx new_next 0x%x err %d", ragi->sc->sa.pag->pag_agno, idx - 1, agino, error);
    1555           0 :                         return error;
    1556             :                 }
    1557             :         }
    1558             : 
    1559             :         /* Fix all the back links */
    1560      233230 :         idx = XFARRAY_CURSOR_INIT;
    1561      236441 :         while ((error = xfarray_iter(ragi->iunlink_prev, &idx, &agino)) == 1) {
    1562        3211 :                 error = xrep_iunlink_relink_prev(ragi, idx, agino);
    1563        3211 :                 if (error) {
    1564           0 :                         xfs_emerg(ragi->sc->mp, "IUNLINK relink_back failed agno 0x%x agino 0x%llx new_prev 0x%x err %d", ragi->sc->sa.pag->pag_agno, idx - 1, agino, error);
    1565           0 :                         return error;
    1566             :                 }
    1567             :         }
    1568             : 
    1569             :         /* Copy the staged iunlink buckets to the new AGI. */
    1570    15159877 :         for (i = 0; i < XFS_AGI_UNLINKED_BUCKETS; i++) {
    1571    14926479 :                 trace_xrep_iunlink_commit_bucket(ragi->sc->sa.pag, i,
    1572    14926351 :                                 ragi->iunlink_heads[i]);
    1573             : 
    1574    14925837 :                 if (ragi->old_agi.agi_unlinked[i] != cpu_to_be32(ragi->iunlink_heads[i]))
    1575           0 :                         xfs_emerg(ragi->sc->mp, "IUNLINK relink_buct agno 0x%x bucket %u head 0x%x -> 0x%x", ragi->sc->sa.pag->pag_agno, i, be32_to_cpu(ragi->old_agi.agi_unlinked[i]), ragi->iunlink_heads[i]);
    1576    14926081 :                 agi->agi_unlinked[i] = cpu_to_be32(ragi->iunlink_heads[i]);
    1577             :         }
    1578             : 
    1579             :         return 0;
    1580             : }
    1581             : 
    1582             : /* Trigger reinitialization of the in-core data. */
    1583             : STATIC int
    1584      233488 : xrep_agi_commit_new(
    1585             :         struct xrep_agi         *ragi)
    1586             : {
    1587      233488 :         struct xfs_scrub        *sc = ragi->sc;
    1588      233488 :         struct xfs_buf          *agi_bp = ragi->agi_bp;
    1589      233488 :         struct xfs_perag        *pag;
    1590      233488 :         struct xfs_agi          *agi = agi_bp->b_addr;
    1591             : 
    1592             :         /* Trigger inode count recalculation */
    1593      233488 :         xfs_force_summary_recalc(sc->mp);
    1594             : 
    1595             :         /* Write this to disk. */
    1596      233546 :         xfs_trans_buf_set_type(sc->tp, agi_bp, XFS_BLFT_AGI_BUF);
    1597      233533 :         xfs_trans_log_buf(sc->tp, agi_bp, 0, BBTOB(agi_bp->b_length) - 1);
    1598             : 
    1599             :         /* Now reinitialize the in-core counters if necessary. */
    1600      233403 :         pag = sc->sa.pag;
    1601      233403 :         pag->pagi_count = be32_to_cpu(agi->agi_count);
    1602      233403 :         pag->pagi_freecount = be32_to_cpu(agi->agi_freecount);
    1603      233403 :         set_bit(XFS_AGSTATE_AGI_INIT, &pag->pag_opstate);
    1604             : 
    1605      233512 :         return 0;
    1606             : }
    1607             : 
    1608             : /* Repair the AGI. */
    1609             : int
    1610      234415 : xrep_agi(
    1611             :         struct xfs_scrub        *sc)
    1612             : {
    1613      234415 :         struct xrep_agi         *ragi;
    1614      234415 :         struct xfs_mount        *mp = sc->mp;
    1615      234415 :         char                    *descr;
    1616      234415 :         unsigned int            i;
    1617      234415 :         int                     error;
    1618             : 
    1619             :         /* We require the rmapbt to rebuild anything. */
    1620      234415 :         if (!xfs_has_rmapbt(mp))
    1621             :                 return -EOPNOTSUPP;
    1622             : 
    1623      233475 :         sc->buf = kzalloc(sizeof(struct xrep_agi), XCHK_GFP_FLAGS);
    1624      233511 :         if (!sc->buf)
    1625             :                 return -ENOMEM;
    1626      233511 :         ragi = sc->buf;
    1627      233511 :         ragi->sc = sc;
    1628             : 
    1629      233511 :         ragi->fab[XREP_AGI_INOBT] = (struct xrep_find_ag_btree){
    1630             :                 .rmap_owner     = XFS_RMAP_OWN_INOBT,
    1631             :                 .buf_ops        = &xfs_inobt_buf_ops,
    1632      233511 :                 .maxlevels      = M_IGEO(sc->mp)->inobt_maxlevels,
    1633             :         };
    1634      233511 :         ragi->fab[XREP_AGI_FINOBT] = (struct xrep_find_ag_btree){
    1635             :                 .rmap_owner     = XFS_RMAP_OWN_INOBT,
    1636             :                 .buf_ops        = &xfs_finobt_buf_ops,
    1637      233511 :                 .maxlevels      = M_IGEO(sc->mp)->inobt_maxlevels,
    1638             :         };
    1639      233511 :         ragi->fab[XREP_AGI_END] = (struct xrep_find_ag_btree){
    1640             :                 .buf_ops        = NULL,
    1641             :         };
    1642             : 
    1643    15168171 :         for (i = 0; i < XFS_AGI_UNLINKED_BUCKETS; i++)
    1644    14934728 :                 ragi->iunlink_heads[i] = NULLAGINO;
    1645             : 
    1646      233443 :         xbitmap_init(&ragi->iunlink_bmp);
    1647      233472 :         sc->buf_cleanup = xrep_agi_buf_cleanup;
    1648             : 
    1649      233472 :         descr = xchk_xfile_ag_descr(sc, "iunlinked next pointers");
    1650      233343 :         error = xfarray_create(descr, 0, sizeof(xfs_agino_t),
    1651             :                         &ragi->iunlink_next);
    1652      233339 :         kfree(descr);
    1653      233308 :         if (error)
    1654             :                 return error;
    1655             : 
    1656      233308 :         descr = xchk_xfile_ag_descr(sc, "iunlinked prev pointers");
    1657      233429 :         error = xfarray_create(descr, 0, sizeof(xfs_agino_t),
    1658             :                         &ragi->iunlink_prev);
    1659      233537 :         kfree(descr);
    1660      233508 :         if (error)
    1661             :                 return error;
    1662             : 
    1663             :         /*
    1664             :          * Make sure we have the AGI buffer, as scrub might have decided it
    1665             :          * was corrupt after xfs_ialloc_read_agi failed with -EFSCORRUPTED.
    1666             :          */
    1667     1167513 :         error = xfs_trans_read_buf(mp, sc->tp, mp->m_ddev_targp,
    1668      233508 :                         XFS_AG_DADDR(mp, sc->sa.pag->pag_agno,
    1669             :                                                 XFS_AGI_DADDR(mp)),
    1670      233508 :                         XFS_FSS_TO_BB(mp, 1), 0, &ragi->agi_bp, NULL);
    1671      233481 :         if (error)
    1672             :                 return error;
    1673      233482 :         ragi->agi_bp->b_ops = &xfs_agi_buf_ops;
    1674             : 
    1675             :         /* Find the AGI btree roots. */
    1676      233482 :         error = xrep_agi_find_btrees(ragi);
    1677      233506 :         if (error)
    1678             :                 return error;
    1679             : 
    1680      233490 :         error = xrep_iunlink_rebuild_buckets(ragi);
    1681      233421 :         if (error)
    1682             :                 return error;
    1683             : 
    1684             :         /* Last chance to abort before we start committing fixes. */
    1685      233417 :         if (xchk_should_terminate(sc, &error))
    1686           0 :                 return error;
    1687             : 
    1688             :         /* Start rewriting the header and implant the btrees we found. */
    1689      233380 :         xrep_agi_init_header(ragi);
    1690      233504 :         xrep_agi_set_roots(ragi);
    1691      233401 :         error = xrep_agi_calc_from_btrees(ragi);
    1692      233534 :         if (error)
    1693           0 :                 goto out_revert;
    1694      233534 :         error = xrep_iunlink_commit(ragi);
    1695      233518 :         if (error)
    1696           0 :                 goto out_revert;
    1697             : 
    1698             :         /* Reinitialize in-core state. */
    1699      233518 :         return xrep_agi_commit_new(ragi);
    1700             : 
    1701           0 : out_revert:
    1702             :         /* Mark the incore AGI state stale and revert the AGI. */
    1703           0 :         clear_bit(XFS_AGSTATE_AGI_INIT, &sc->sa.pag->pag_opstate);
    1704           0 :         memcpy(ragi->agi_bp->b_addr, &ragi->old_agi, sizeof(struct xfs_agi));
    1705           0 :         return error;
    1706             : }

Generated by: LCOV version 1.14