^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2018 Oracle. All Rights Reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Author: Darrick J. Wong <darrick.wong@oracle.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include "xfs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include "xfs_fs.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include "xfs_shared.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include "xfs_format.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include "xfs_trans_resv.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "xfs_mount.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include "xfs_btree.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include "xfs_log_format.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "xfs_trans.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "xfs_sb.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "xfs_alloc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include "xfs_alloc_btree.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include "xfs_ialloc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include "xfs_ialloc_btree.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include "xfs_rmap.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include "xfs_rmap_btree.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "xfs_refcount_btree.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include "scrub/scrub.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include "scrub/common.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include "scrub/trace.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include "scrub/repair.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include "scrub/bitmap.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) /* Superblock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) /* Repair the superblock. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) xrep_superblock(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) struct xfs_scrub *sc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) struct xfs_mount *mp = sc->mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) struct xfs_buf *bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) xfs_agnumber_t agno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) /* Don't try to repair AG 0's sb; let xfs_repair deal with it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) agno = sc->sm->sm_agno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) if (agno == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) error = xfs_sb_get_secondary(mp, sc->tp, agno, &bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) /* Copy AG 0's superblock to this one. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) xfs_buf_zero(bp, 0, BBTOB(bp->b_length));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) xfs_sb_to_disk(bp->b_addr, &mp->m_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) /* Write this to disk. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) xfs_trans_buf_set_type(sc->tp, bp, XFS_BLFT_SB_BUF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) xfs_trans_log_buf(sc->tp, bp, 0, BBTOB(bp->b_length) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) /* AGF */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) struct xrep_agf_allocbt {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) struct xfs_scrub *sc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) xfs_agblock_t freeblks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) xfs_agblock_t longest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) /* Record free space shape information. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) xrep_agf_walk_allocbt(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) struct xfs_btree_cur *cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) struct xfs_alloc_rec_incore *rec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) void *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) struct xrep_agf_allocbt *raa = priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) int error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) if (xchk_should_terminate(raa->sc, &error))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) raa->freeblks += rec->ar_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) if (rec->ar_blockcount > raa->longest)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) raa->longest = rec->ar_blockcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) /* Does this AGFL block look sane? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) xrep_agf_check_agfl_block(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) struct xfs_mount *mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) xfs_agblock_t agbno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) void *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) struct xfs_scrub *sc = priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) if (!xfs_verify_agbno(mp, sc->sa.agno, agbno))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) return -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) * Offset within the xrep_find_ag_btree array for each btree type. Avoid the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * XFS_BTNUM_ names here to avoid creating a sparse array.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) XREP_AGF_BNOBT = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) XREP_AGF_CNTBT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) XREP_AGF_RMAPBT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) XREP_AGF_REFCOUNTBT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) XREP_AGF_END,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) XREP_AGF_MAX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /* Check a btree root candidate. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) static inline bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) xrep_check_btree_root(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) struct xfs_scrub *sc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) struct xrep_find_ag_btree *fab)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) struct xfs_mount *mp = sc->mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) xfs_agnumber_t agno = sc->sm->sm_agno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) return xfs_verify_agbno(mp, agno, fab->root) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) fab->height <= XFS_BTREE_MAXLEVELS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * Given the btree roots described by *fab, find the roots, check them for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * sanity, and pass the root data back out via *fab.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) * This is /also/ a chicken and egg problem because we have to use the rmapbt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) * (rooted in the AGF) to find the btrees rooted in the AGF. We also have no
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) * idea if the btrees make any sense. If we hit obvious corruptions in those
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) * btrees we'll bail out.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) xrep_agf_find_btrees(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) struct xfs_scrub *sc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) struct xfs_buf *agf_bp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) struct xrep_find_ag_btree *fab,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) struct xfs_buf *agfl_bp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) struct xfs_agf *old_agf = agf_bp->b_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) /* Go find the root data. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) error = xrep_find_ag_btree_roots(sc, agf_bp, fab, agfl_bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) /* We must find the bnobt, cntbt, and rmapbt roots. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) if (!xrep_check_btree_root(sc, &fab[XREP_AGF_BNOBT]) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) !xrep_check_btree_root(sc, &fab[XREP_AGF_CNTBT]) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) !xrep_check_btree_root(sc, &fab[XREP_AGF_RMAPBT]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) return -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) * We relied on the rmapbt to reconstruct the AGF. If we get a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) * different root then something's seriously wrong.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) if (fab[XREP_AGF_RMAPBT].root !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) be32_to_cpu(old_agf->agf_roots[XFS_BTNUM_RMAPi]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) return -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) /* We must find the refcountbt root if that feature is enabled. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) if (xfs_sb_version_hasreflink(&sc->mp->m_sb) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) !xrep_check_btree_root(sc, &fab[XREP_AGF_REFCOUNTBT]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) return -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) * Reinitialize the AGF header, making an in-core copy of the old contents so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) * that we know which in-core state needs to be reinitialized.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) STATIC void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) xrep_agf_init_header(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) struct xfs_scrub *sc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) struct xfs_buf *agf_bp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) struct xfs_agf *old_agf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) struct xfs_mount *mp = sc->mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) struct xfs_agf *agf = agf_bp->b_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) memcpy(old_agf, agf, sizeof(*old_agf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) memset(agf, 0, BBTOB(agf_bp->b_length));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) agf->agf_magicnum = cpu_to_be32(XFS_AGF_MAGIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) agf->agf_versionnum = cpu_to_be32(XFS_AGF_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) agf->agf_seqno = cpu_to_be32(sc->sa.agno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) agf->agf_length = cpu_to_be32(xfs_ag_block_count(mp, sc->sa.agno));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) agf->agf_flfirst = old_agf->agf_flfirst;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) agf->agf_fllast = old_agf->agf_fllast;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) agf->agf_flcount = old_agf->agf_flcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) if (xfs_sb_version_hascrc(&mp->m_sb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) uuid_copy(&agf->agf_uuid, &mp->m_sb.sb_meta_uuid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) /* Mark the incore AGF data stale until we're done fixing things. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) ASSERT(sc->sa.pag->pagf_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) sc->sa.pag->pagf_init = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) /* Set btree root information in an AGF. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) STATIC void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) xrep_agf_set_roots(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) struct xfs_scrub *sc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) struct xfs_agf *agf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) struct xrep_find_ag_btree *fab)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) agf->agf_roots[XFS_BTNUM_BNOi] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) cpu_to_be32(fab[XREP_AGF_BNOBT].root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) agf->agf_levels[XFS_BTNUM_BNOi] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) cpu_to_be32(fab[XREP_AGF_BNOBT].height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) agf->agf_roots[XFS_BTNUM_CNTi] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) cpu_to_be32(fab[XREP_AGF_CNTBT].root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) agf->agf_levels[XFS_BTNUM_CNTi] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) cpu_to_be32(fab[XREP_AGF_CNTBT].height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) agf->agf_roots[XFS_BTNUM_RMAPi] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) cpu_to_be32(fab[XREP_AGF_RMAPBT].root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) agf->agf_levels[XFS_BTNUM_RMAPi] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) cpu_to_be32(fab[XREP_AGF_RMAPBT].height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) if (xfs_sb_version_hasreflink(&sc->mp->m_sb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) agf->agf_refcount_root =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) cpu_to_be32(fab[XREP_AGF_REFCOUNTBT].root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) agf->agf_refcount_level =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) cpu_to_be32(fab[XREP_AGF_REFCOUNTBT].height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) /* Update all AGF fields which derive from btree contents. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) xrep_agf_calc_from_btrees(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) struct xfs_scrub *sc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) struct xfs_buf *agf_bp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) struct xrep_agf_allocbt raa = { .sc = sc };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) struct xfs_btree_cur *cur = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) struct xfs_agf *agf = agf_bp->b_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) struct xfs_mount *mp = sc->mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) xfs_agblock_t btreeblks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) xfs_agblock_t blocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) /* Update the AGF counters from the bnobt. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) cur = xfs_allocbt_init_cursor(mp, sc->tp, agf_bp, sc->sa.agno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) XFS_BTNUM_BNO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) error = xfs_alloc_query_all(cur, xrep_agf_walk_allocbt, &raa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) error = xfs_btree_count_blocks(cur, &blocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) xfs_btree_del_cursor(cur, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) btreeblks = blocks - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) agf->agf_freeblks = cpu_to_be32(raa.freeblks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) agf->agf_longest = cpu_to_be32(raa.longest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) /* Update the AGF counters from the cntbt. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) cur = xfs_allocbt_init_cursor(mp, sc->tp, agf_bp, sc->sa.agno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) XFS_BTNUM_CNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) error = xfs_btree_count_blocks(cur, &blocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) xfs_btree_del_cursor(cur, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) btreeblks += blocks - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) /* Update the AGF counters from the rmapbt. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) cur = xfs_rmapbt_init_cursor(mp, sc->tp, agf_bp, sc->sa.agno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) error = xfs_btree_count_blocks(cur, &blocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) xfs_btree_del_cursor(cur, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) agf->agf_rmap_blocks = cpu_to_be32(blocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) btreeblks += blocks - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) agf->agf_btreeblks = cpu_to_be32(btreeblks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) /* Update the AGF counters from the refcountbt. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) if (xfs_sb_version_hasreflink(&mp->m_sb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) cur = xfs_refcountbt_init_cursor(mp, sc->tp, agf_bp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) sc->sa.agno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) error = xfs_btree_count_blocks(cur, &blocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) xfs_btree_del_cursor(cur, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) agf->agf_refcount_blocks = cpu_to_be32(blocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) xfs_btree_del_cursor(cur, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) /* Commit the new AGF and reinitialize the incore state. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) xrep_agf_commit_new(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) struct xfs_scrub *sc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) struct xfs_buf *agf_bp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) struct xfs_perag *pag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) struct xfs_agf *agf = agf_bp->b_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) /* Trigger fdblocks recalculation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) xfs_force_summary_recalc(sc->mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) /* Write this to disk. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) xfs_trans_buf_set_type(sc->tp, agf_bp, XFS_BLFT_AGF_BUF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) xfs_trans_log_buf(sc->tp, agf_bp, 0, BBTOB(agf_bp->b_length) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) /* Now reinitialize the in-core counters we changed. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) pag = sc->sa.pag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) pag->pagf_btreeblks = be32_to_cpu(agf->agf_btreeblks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) pag->pagf_freeblks = be32_to_cpu(agf->agf_freeblks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) pag->pagf_longest = be32_to_cpu(agf->agf_longest);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) pag->pagf_levels[XFS_BTNUM_BNOi] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNOi]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) pag->pagf_levels[XFS_BTNUM_CNTi] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) pag->pagf_levels[XFS_BTNUM_RMAPi] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAPi]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) pag->pagf_refcount_level = be32_to_cpu(agf->agf_refcount_level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) pag->pagf_init = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) /* Repair the AGF. v5 filesystems only. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) xrep_agf(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) struct xfs_scrub *sc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) struct xrep_find_ag_btree fab[XREP_AGF_MAX] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) [XREP_AGF_BNOBT] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) .rmap_owner = XFS_RMAP_OWN_AG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) .buf_ops = &xfs_bnobt_buf_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) [XREP_AGF_CNTBT] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) .rmap_owner = XFS_RMAP_OWN_AG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) .buf_ops = &xfs_cntbt_buf_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) [XREP_AGF_RMAPBT] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) .rmap_owner = XFS_RMAP_OWN_AG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) .buf_ops = &xfs_rmapbt_buf_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) [XREP_AGF_REFCOUNTBT] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) .rmap_owner = XFS_RMAP_OWN_REFC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) .buf_ops = &xfs_refcountbt_buf_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) [XREP_AGF_END] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) .buf_ops = NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) struct xfs_agf old_agf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) struct xfs_mount *mp = sc->mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) struct xfs_buf *agf_bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) struct xfs_buf *agfl_bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) struct xfs_agf *agf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) /* We require the rmapbt to rebuild anything. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) if (!xfs_sb_version_hasrmapbt(&mp->m_sb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) xchk_perag_get(sc->mp, &sc->sa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) * Make sure we have the AGF buffer, as scrub might have decided it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) * was corrupt after xfs_alloc_read_agf failed with -EFSCORRUPTED.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) error = xfs_trans_read_buf(mp, sc->tp, mp->m_ddev_targp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) XFS_AG_DADDR(mp, sc->sa.agno, XFS_AGF_DADDR(mp)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) XFS_FSS_TO_BB(mp, 1), 0, &agf_bp, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) agf_bp->b_ops = &xfs_agf_buf_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) agf = agf_bp->b_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) * Load the AGFL so that we can screen out OWN_AG blocks that are on
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) * the AGFL now; these blocks might have once been part of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) * bno/cnt/rmap btrees but are not now. This is a chicken and egg
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) * problem: the AGF is corrupt, so we have to trust the AGFL contents
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) * because we can't do any serious cross-referencing with any of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) * btrees rooted in the AGF. If the AGFL contents are obviously bad
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) * then we'll bail out.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) error = xfs_alloc_read_agfl(mp, sc->tp, sc->sa.agno, &agfl_bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) * Spot-check the AGFL blocks; if they're obviously corrupt then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) * there's nothing we can do but bail out.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) error = xfs_agfl_walk(sc->mp, agf_bp->b_addr, agfl_bp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) xrep_agf_check_agfl_block, sc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) * Find the AGF btree roots. This is also a chicken-and-egg situation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) * see the function for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) error = xrep_agf_find_btrees(sc, agf_bp, fab, agfl_bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) /* Start rewriting the header and implant the btrees we found. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) xrep_agf_init_header(sc, agf_bp, &old_agf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) xrep_agf_set_roots(sc, agf, fab);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) error = xrep_agf_calc_from_btrees(sc, agf_bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) goto out_revert;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) /* Commit the changes and reinitialize incore state. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) return xrep_agf_commit_new(sc, agf_bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) out_revert:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) /* Mark the incore AGF state stale and revert the AGF. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) sc->sa.pag->pagf_init = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) memcpy(agf, &old_agf, sizeof(old_agf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) /* AGFL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) struct xrep_agfl {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) /* Bitmap of other OWN_AG metadata blocks. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) struct xbitmap agmetablocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) /* Bitmap of free space. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) struct xbitmap *freesp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) struct xfs_scrub *sc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) /* Record all OWN_AG (free space btree) information from the rmap data. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) xrep_agfl_walk_rmap(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) struct xfs_btree_cur *cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) struct xfs_rmap_irec *rec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) void *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) struct xrep_agfl *ra = priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) xfs_fsblock_t fsb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) int error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) if (xchk_should_terminate(ra->sc, &error))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) /* Record all the OWN_AG blocks. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) if (rec->rm_owner == XFS_RMAP_OWN_AG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) fsb = XFS_AGB_TO_FSB(cur->bc_mp, cur->bc_ag.agno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) rec->rm_startblock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) error = xbitmap_set(ra->freesp, fsb, rec->rm_blockcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) return xbitmap_set_btcur_path(&ra->agmetablocks, cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) * Map out all the non-AGFL OWN_AG space in this AG so that we can deduce
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) * which blocks belong to the AGFL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) * Compute the set of old AGFL blocks by subtracting from the list of OWN_AG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) * blocks the list of blocks owned by all other OWN_AG metadata (bnobt, cntbt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) * rmapbt). These are the old AGFL blocks, so return that list and the number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) * of blocks we're actually going to put back on the AGFL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) xrep_agfl_collect_blocks(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) struct xfs_scrub *sc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) struct xfs_buf *agf_bp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) struct xbitmap *agfl_extents,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) xfs_agblock_t *flcount)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) struct xrep_agfl ra;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) struct xfs_mount *mp = sc->mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) struct xfs_btree_cur *cur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) ra.sc = sc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) ra.freesp = agfl_extents;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) xbitmap_init(&ra.agmetablocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) /* Find all space used by the free space btrees & rmapbt. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) cur = xfs_rmapbt_init_cursor(mp, sc->tp, agf_bp, sc->sa.agno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) error = xfs_rmap_query_all(cur, xrep_agfl_walk_rmap, &ra);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) xfs_btree_del_cursor(cur, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) /* Find all blocks currently being used by the bnobt. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) cur = xfs_allocbt_init_cursor(mp, sc->tp, agf_bp, sc->sa.agno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) XFS_BTNUM_BNO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) error = xbitmap_set_btblocks(&ra.agmetablocks, cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) xfs_btree_del_cursor(cur, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) /* Find all blocks currently being used by the cntbt. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) cur = xfs_allocbt_init_cursor(mp, sc->tp, agf_bp, sc->sa.agno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) XFS_BTNUM_CNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) error = xbitmap_set_btblocks(&ra.agmetablocks, cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) xfs_btree_del_cursor(cur, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) * Drop the freesp meta blocks that are in use by btrees.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) * The remaining blocks /should/ be AGFL blocks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) error = xbitmap_disunion(agfl_extents, &ra.agmetablocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) xbitmap_destroy(&ra.agmetablocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) * Calculate the new AGFL size. If we found more blocks than fit in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) * the AGFL we'll free them later.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) *flcount = min_t(uint64_t, xbitmap_hweight(agfl_extents),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) xfs_agfl_size(mp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) xbitmap_destroy(&ra.agmetablocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) xfs_btree_del_cursor(cur, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) /* Update the AGF and reset the in-core state. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) STATIC void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) xrep_agfl_update_agf(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) struct xfs_scrub *sc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) struct xfs_buf *agf_bp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) xfs_agblock_t flcount)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) struct xfs_agf *agf = agf_bp->b_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) ASSERT(flcount <= xfs_agfl_size(sc->mp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) /* Trigger fdblocks recalculation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) xfs_force_summary_recalc(sc->mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) /* Update the AGF counters. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) if (sc->sa.pag->pagf_init)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) sc->sa.pag->pagf_flcount = flcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) agf->agf_flfirst = cpu_to_be32(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) agf->agf_flcount = cpu_to_be32(flcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) agf->agf_fllast = cpu_to_be32(flcount - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) xfs_alloc_log_agf(sc->tp, agf_bp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) XFS_AGF_FLFIRST | XFS_AGF_FLLAST | XFS_AGF_FLCOUNT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) /* Write out a totally new AGFL. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) STATIC void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) xrep_agfl_init_header(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) struct xfs_scrub *sc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) struct xfs_buf *agfl_bp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) struct xbitmap *agfl_extents,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) xfs_agblock_t flcount)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) struct xfs_mount *mp = sc->mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) __be32 *agfl_bno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) struct xbitmap_range *br;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) struct xbitmap_range *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) struct xfs_agfl *agfl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) xfs_agblock_t agbno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) unsigned int fl_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) ASSERT(flcount <= xfs_agfl_size(mp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) * Start rewriting the header by setting the bno[] array to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) * NULLAGBLOCK, then setting AGFL header fields.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) agfl = XFS_BUF_TO_AGFL(agfl_bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) memset(agfl, 0xFF, BBTOB(agfl_bp->b_length));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) agfl->agfl_magicnum = cpu_to_be32(XFS_AGFL_MAGIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) agfl->agfl_seqno = cpu_to_be32(sc->sa.agno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) uuid_copy(&agfl->agfl_uuid, &mp->m_sb.sb_meta_uuid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) * Fill the AGFL with the remaining blocks. If agfl_extents has more
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) * blocks than fit in the AGFL, they will be freed in a subsequent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) * step.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) fl_off = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) agfl_bno = xfs_buf_to_agfl_bno(agfl_bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) for_each_xbitmap_extent(br, n, agfl_extents) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) agbno = XFS_FSB_TO_AGBNO(mp, br->start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) trace_xrep_agfl_insert(mp, sc->sa.agno, agbno, br->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) while (br->len > 0 && fl_off < flcount) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) agfl_bno[fl_off] = cpu_to_be32(agbno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) fl_off++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) agbno++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) * We've now used br->start by putting it in the AGFL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) * so bump br so that we don't reap the block later.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) br->start++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) br->len--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) if (br->len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) list_del(&br->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) kmem_free(br);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) /* Write new AGFL to disk. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) xfs_trans_buf_set_type(sc->tp, agfl_bp, XFS_BLFT_AGFL_BUF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) xfs_trans_log_buf(sc->tp, agfl_bp, 0, BBTOB(agfl_bp->b_length) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) /* Repair the AGFL. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) xrep_agfl(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) struct xfs_scrub *sc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) struct xbitmap agfl_extents;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) struct xfs_mount *mp = sc->mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) struct xfs_buf *agf_bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) struct xfs_buf *agfl_bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) xfs_agblock_t flcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) /* We require the rmapbt to rebuild anything. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) if (!xfs_sb_version_hasrmapbt(&mp->m_sb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) xchk_perag_get(sc->mp, &sc->sa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) xbitmap_init(&agfl_extents);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) * Read the AGF so that we can query the rmapbt. We hope that there's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) * nothing wrong with the AGF, but all the AG header repair functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) * have this chicken-and-egg problem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) error = xfs_alloc_read_agf(mp, sc->tp, sc->sa.agno, 0, &agf_bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) * Make sure we have the AGFL buffer, as scrub might have decided it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) * was corrupt after xfs_alloc_read_agfl failed with -EFSCORRUPTED.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) error = xfs_trans_read_buf(mp, sc->tp, mp->m_ddev_targp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) XFS_AG_DADDR(mp, sc->sa.agno, XFS_AGFL_DADDR(mp)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) XFS_FSS_TO_BB(mp, 1), 0, &agfl_bp, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) agfl_bp->b_ops = &xfs_agfl_buf_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) /* Gather all the extents we're going to put on the new AGFL. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) error = xrep_agfl_collect_blocks(sc, agf_bp, &agfl_extents, &flcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) * Update AGF and AGFL. We reset the global free block counter when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) * we adjust the AGF flcount (which can fail) so avoid updating any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) * buffers until we know that part works.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) xrep_agfl_update_agf(sc, agf_bp, flcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) xrep_agfl_init_header(sc, agfl_bp, &agfl_extents, flcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) * Ok, the AGFL should be ready to go now. Roll the transaction to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) * make the new AGFL permanent before we start using it to return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) * freespace overflow to the freespace btrees.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) sc->sa.agf_bp = agf_bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) sc->sa.agfl_bp = agfl_bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) error = xrep_roll_ag_trans(sc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) /* Dump any AGFL overflow. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) error = xrep_reap_extents(sc, &agfl_extents, &XFS_RMAP_OINFO_AG,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) XFS_AG_RESV_AGFL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) xbitmap_destroy(&agfl_extents);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) /* AGI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) * Offset within the xrep_find_ag_btree array for each btree type. Avoid the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) * XFS_BTNUM_ names here to avoid creating a sparse array.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) XREP_AGI_INOBT = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) XREP_AGI_FINOBT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) XREP_AGI_END,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) XREP_AGI_MAX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) * Given the inode btree roots described by *fab, find the roots, check them
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) * for sanity, and pass the root data back out via *fab.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) xrep_agi_find_btrees(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) struct xfs_scrub *sc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) struct xrep_find_ag_btree *fab)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) struct xfs_buf *agf_bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) struct xfs_mount *mp = sc->mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) /* Read the AGF. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) error = xfs_alloc_read_agf(mp, sc->tp, sc->sa.agno, 0, &agf_bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) /* Find the btree roots. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) error = xrep_find_ag_btree_roots(sc, agf_bp, fab, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) /* We must find the inobt root. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) if (!xrep_check_btree_root(sc, &fab[XREP_AGI_INOBT]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) return -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) /* We must find the finobt root if that feature is enabled. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) if (xfs_sb_version_hasfinobt(&mp->m_sb) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) !xrep_check_btree_root(sc, &fab[XREP_AGI_FINOBT]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) return -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) * Reinitialize the AGI header, making an in-core copy of the old contents so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) * that we know which in-core state needs to be reinitialized.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) STATIC void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) xrep_agi_init_header(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) struct xfs_scrub *sc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) struct xfs_buf *agi_bp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) struct xfs_agi *old_agi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) struct xfs_agi *agi = agi_bp->b_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) struct xfs_mount *mp = sc->mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) memcpy(old_agi, agi, sizeof(*old_agi));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) memset(agi, 0, BBTOB(agi_bp->b_length));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) agi->agi_magicnum = cpu_to_be32(XFS_AGI_MAGIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) agi->agi_versionnum = cpu_to_be32(XFS_AGI_VERSION);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) agi->agi_seqno = cpu_to_be32(sc->sa.agno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) agi->agi_length = cpu_to_be32(xfs_ag_block_count(mp, sc->sa.agno));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) agi->agi_newino = cpu_to_be32(NULLAGINO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) agi->agi_dirino = cpu_to_be32(NULLAGINO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) if (xfs_sb_version_hascrc(&mp->m_sb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) uuid_copy(&agi->agi_uuid, &mp->m_sb.sb_meta_uuid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) /* We don't know how to fix the unlinked list yet. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) memcpy(&agi->agi_unlinked, &old_agi->agi_unlinked,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) sizeof(agi->agi_unlinked));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) /* Mark the incore AGF data stale until we're done fixing things. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) ASSERT(sc->sa.pag->pagi_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) sc->sa.pag->pagi_init = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) /* Set btree root information in an AGI. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) STATIC void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) xrep_agi_set_roots(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) struct xfs_scrub *sc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) struct xfs_agi *agi,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) struct xrep_find_ag_btree *fab)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) agi->agi_root = cpu_to_be32(fab[XREP_AGI_INOBT].root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) agi->agi_level = cpu_to_be32(fab[XREP_AGI_INOBT].height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) if (xfs_sb_version_hasfinobt(&sc->mp->m_sb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) agi->agi_free_root = cpu_to_be32(fab[XREP_AGI_FINOBT].root);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) agi->agi_free_level = cpu_to_be32(fab[XREP_AGI_FINOBT].height);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) /* Update the AGI counters. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) xrep_agi_calc_from_btrees(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) struct xfs_scrub *sc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) struct xfs_buf *agi_bp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) struct xfs_btree_cur *cur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) struct xfs_agi *agi = agi_bp->b_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) struct xfs_mount *mp = sc->mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) xfs_agino_t count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) xfs_agino_t freecount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) cur = xfs_inobt_init_cursor(mp, sc->tp, agi_bp, sc->sa.agno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) XFS_BTNUM_INO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) error = xfs_ialloc_count_inodes(cur, &count, &freecount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) if (xfs_sb_version_hasinobtcounts(&mp->m_sb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) xfs_agblock_t blocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) error = xfs_btree_count_blocks(cur, &blocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) agi->agi_iblocks = cpu_to_be32(blocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) xfs_btree_del_cursor(cur, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) agi->agi_count = cpu_to_be32(count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) agi->agi_freecount = cpu_to_be32(freecount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) if (xfs_sb_version_hasfinobt(&mp->m_sb) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) xfs_sb_version_hasinobtcounts(&mp->m_sb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) xfs_agblock_t blocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) cur = xfs_inobt_init_cursor(mp, sc->tp, agi_bp, sc->sa.agno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) XFS_BTNUM_FINO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) error = xfs_btree_count_blocks(cur, &blocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) xfs_btree_del_cursor(cur, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) agi->agi_fblocks = cpu_to_be32(blocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) xfs_btree_del_cursor(cur, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) /* Trigger reinitialization of the in-core data. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) xrep_agi_commit_new(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) struct xfs_scrub *sc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) struct xfs_buf *agi_bp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) struct xfs_perag *pag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) struct xfs_agi *agi = agi_bp->b_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) /* Trigger inode count recalculation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) xfs_force_summary_recalc(sc->mp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) /* Write this to disk. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) xfs_trans_buf_set_type(sc->tp, agi_bp, XFS_BLFT_AGI_BUF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) xfs_trans_log_buf(sc->tp, agi_bp, 0, BBTOB(agi_bp->b_length) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) /* Now reinitialize the in-core counters if necessary. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) pag = sc->sa.pag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) pag->pagi_count = be32_to_cpu(agi->agi_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) pag->pagi_freecount = be32_to_cpu(agi->agi_freecount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) pag->pagi_init = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) /* Repair the AGI. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) xrep_agi(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) struct xfs_scrub *sc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) struct xrep_find_ag_btree fab[XREP_AGI_MAX] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) [XREP_AGI_INOBT] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) .rmap_owner = XFS_RMAP_OWN_INOBT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) .buf_ops = &xfs_inobt_buf_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) [XREP_AGI_FINOBT] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) .rmap_owner = XFS_RMAP_OWN_INOBT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) .buf_ops = &xfs_finobt_buf_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) [XREP_AGI_END] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) .buf_ops = NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) struct xfs_agi old_agi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) struct xfs_mount *mp = sc->mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) struct xfs_buf *agi_bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) struct xfs_agi *agi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) /* We require the rmapbt to rebuild anything. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) if (!xfs_sb_version_hasrmapbt(&mp->m_sb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) xchk_perag_get(sc->mp, &sc->sa);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) * Make sure we have the AGI buffer, as scrub might have decided it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) * was corrupt after xfs_ialloc_read_agi failed with -EFSCORRUPTED.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) error = xfs_trans_read_buf(mp, sc->tp, mp->m_ddev_targp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) XFS_AG_DADDR(mp, sc->sa.agno, XFS_AGI_DADDR(mp)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) XFS_FSS_TO_BB(mp, 1), 0, &agi_bp, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) agi_bp->b_ops = &xfs_agi_buf_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) agi = agi_bp->b_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) /* Find the AGI btree roots. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) error = xrep_agi_find_btrees(sc, fab);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) /* Start rewriting the header and implant the btrees we found. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) xrep_agi_init_header(sc, agi_bp, &old_agi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) xrep_agi_set_roots(sc, agi, fab);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) error = xrep_agi_calc_from_btrees(sc, agi_bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) goto out_revert;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) /* Reinitialize in-core state. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) return xrep_agi_commit_new(sc, agi_bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) out_revert:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) /* Mark the incore AGI state stale and revert the AGI. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) sc->sa.pag->pagi_init = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) memcpy(agi, &old_agi, sizeof(old_agi));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) }