Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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) }