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) 2017 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_log_format.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include "xfs_trans.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include "xfs_inode.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include "xfs_dir2.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include "xfs_dir2_priv.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include "xfs_attr_leaf.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include "scrub/scrub.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include "scrub/common.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include "scrub/trace.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include "scrub/dabtree.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) /* Directory/Attribute Btree */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)  * Check for da btree operation errors.  See the section about handling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)  * operational errors in common.c.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) xchk_da_process_error(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	struct xchk_da_btree	*ds,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	int			level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	int			*error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	struct xfs_scrub	*sc = ds->sc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	if (*error == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	switch (*error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	case -EDEADLOCK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 		/* Used to restart an op with deadlock avoidance. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 		trace_xchk_deadlock_retry(sc->ip, sc->sm, *error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	case -EFSBADCRC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	case -EFSCORRUPTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 		/* Note the badness but don't abort. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 		sc->sm->sm_flags |= XFS_SCRUB_OFLAG_CORRUPT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 		*error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 		/* fall through */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 		trace_xchk_file_op_error(sc, ds->dargs.whichfork,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 				xfs_dir2_da_to_db(ds->dargs.geo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 					ds->state->path.blk[level].blkno),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 				*error, __return_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62)  * Check for da btree corruption.  See the section about handling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63)  * operational errors in common.c.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) xchk_da_set_corrupt(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	struct xchk_da_btree	*ds,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	int			level)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	struct xfs_scrub	*sc = ds->sc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	sc->sm->sm_flags |= XFS_SCRUB_OFLAG_CORRUPT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	trace_xchk_fblock_error(sc, ds->dargs.whichfork,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 			xfs_dir2_da_to_db(ds->dargs.geo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 				ds->state->path.blk[level].blkno),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 			__return_address);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) static struct xfs_da_node_entry *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) xchk_da_btree_node_entry(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	struct xchk_da_btree		*ds,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	int				level)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	struct xfs_da_state_blk		*blk = &ds->state->path.blk[level];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	struct xfs_da3_icnode_hdr	hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	ASSERT(blk->magic == XFS_DA_NODE_MAGIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	xfs_da3_node_hdr_from_disk(ds->sc->mp, &hdr, blk->bp->b_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	return hdr.btree + blk->index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) /* Scrub a da btree hash (key). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) xchk_da_btree_hash(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	struct xchk_da_btree		*ds,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	int				level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	__be32				*hashp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	struct xfs_da_node_entry	*entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	xfs_dahash_t			hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	xfs_dahash_t			parent_hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	/* Is this hash in order? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	hash = be32_to_cpu(*hashp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	if (hash < ds->hashes[level])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 		xchk_da_set_corrupt(ds, level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	ds->hashes[level] = hash;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	if (level == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	/* Is this hash no larger than the parent hash? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	entry = xchk_da_btree_node_entry(ds, level - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 	parent_hash = be32_to_cpu(entry->hashval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	if (parent_hash < hash)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 		xchk_da_set_corrupt(ds, level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)  * Check a da btree pointer.  Returns true if it's ok to use this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)  * pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) STATIC bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) xchk_da_btree_ptr_ok(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	struct xchk_da_btree	*ds,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	int			level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	xfs_dablk_t		blkno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	if (blkno < ds->lowest || (ds->highest != 0 && blkno >= ds->highest)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 		xchk_da_set_corrupt(ds, level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142)  * The da btree scrubber can handle leaf1 blocks as a degenerate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)  * form of leafn blocks.  Since the regular da code doesn't handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)  * leaf1, we must multiplex the verifiers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) xchk_da_btree_read_verify(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	struct xfs_buf		*bp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 	struct xfs_da_blkinfo	*info = bp->b_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	switch (be16_to_cpu(info->magic)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 	case XFS_DIR2_LEAF1_MAGIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	case XFS_DIR3_LEAF1_MAGIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 		bp->b_ops = &xfs_dir3_leaf1_buf_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 		bp->b_ops->verify_read(bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 		 * xfs_da3_node_buf_ops already know how to handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 		 * DA*_NODE, ATTR*_LEAF, and DIR*_LEAFN blocks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 		bp->b_ops = &xfs_da3_node_buf_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 		bp->b_ops->verify_read(bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) xchk_da_btree_write_verify(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	struct xfs_buf		*bp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	struct xfs_da_blkinfo	*info = bp->b_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	switch (be16_to_cpu(info->magic)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	case XFS_DIR2_LEAF1_MAGIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	case XFS_DIR3_LEAF1_MAGIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 		bp->b_ops = &xfs_dir3_leaf1_buf_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 		bp->b_ops->verify_write(bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 		 * xfs_da3_node_buf_ops already know how to handle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 		 * DA*_NODE, ATTR*_LEAF, and DIR*_LEAFN blocks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 		bp->b_ops = &xfs_da3_node_buf_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 		bp->b_ops->verify_write(bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) static void *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) xchk_da_btree_verify(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	struct xfs_buf		*bp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	struct xfs_da_blkinfo	*info = bp->b_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	switch (be16_to_cpu(info->magic)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 	case XFS_DIR2_LEAF1_MAGIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	case XFS_DIR3_LEAF1_MAGIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 		bp->b_ops = &xfs_dir3_leaf1_buf_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 		return bp->b_ops->verify_struct(bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 		bp->b_ops = &xfs_da3_node_buf_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 		return bp->b_ops->verify_struct(bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) static const struct xfs_buf_ops xchk_da_btree_buf_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 	.name = "xchk_da_btree",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	.verify_read = xchk_da_btree_read_verify,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 	.verify_write = xchk_da_btree_write_verify,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	.verify_struct = xchk_da_btree_verify,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) /* Check a block's sibling. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) xchk_da_btree_block_check_sibling(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	struct xchk_da_btree	*ds,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	int			level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	int			direction,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	xfs_dablk_t		sibling)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	struct xfs_da_state_path *path = &ds->state->path;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 	struct xfs_da_state_path *altpath = &ds->state->altpath;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	int			retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	int			plevel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	int			error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	memcpy(altpath, path, sizeof(ds->state->altpath));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	 * If the pointer is null, we shouldn't be able to move the upper
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	 * level pointer anywhere.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	if (sibling == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 		error = xfs_da3_path_shift(ds->state, altpath, direction,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 				false, &retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 		if (error == 0 && retval == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 			xchk_da_set_corrupt(ds, level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 		error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	/* Move the alternate cursor one block in the direction given. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	error = xfs_da3_path_shift(ds->state, altpath, direction, false,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 			&retval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	if (!xchk_da_process_error(ds, level, &error))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 		xchk_da_set_corrupt(ds, level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	if (altpath->blk[level].bp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 		xchk_buffer_recheck(ds->sc, altpath->blk[level].bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	/* Compare upper level pointer to sibling pointer. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	if (altpath->blk[level].blkno != sibling)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 		xchk_da_set_corrupt(ds, level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	/* Free all buffers in the altpath that aren't referenced from path. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	for (plevel = 0; plevel < altpath->active; plevel++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 		if (altpath->blk[plevel].bp == NULL ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 		    (plevel < path->active &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 		     altpath->blk[plevel].bp == path->blk[plevel].bp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 		xfs_trans_brelse(ds->dargs.trans, altpath->blk[plevel].bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 		altpath->blk[plevel].bp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) /* Check a block's sibling pointers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) xchk_da_btree_block_check_siblings(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	struct xchk_da_btree	*ds,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	int			level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 	struct xfs_da_blkinfo	*hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	xfs_dablk_t		forw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	xfs_dablk_t		back;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	int			error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	forw = be32_to_cpu(hdr->forw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	back = be32_to_cpu(hdr->back);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 	/* Top level blocks should not have sibling pointers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	if (level == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 		if (forw != 0 || back != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 			xchk_da_set_corrupt(ds, level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	 * Check back (left) and forw (right) pointers.  These functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 	 * absorb error codes for us.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	error = xchk_da_btree_block_check_sibling(ds, level, 0, back);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	error = xchk_da_btree_block_check_sibling(ds, level, 1, forw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	memset(&ds->state->altpath, 0, sizeof(ds->state->altpath));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) /* Load a dir/attribute block from a btree. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) xchk_da_btree_block(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	struct xchk_da_btree		*ds,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	int				level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	xfs_dablk_t			blkno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 	struct xfs_da_state_blk		*blk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	struct xfs_da_intnode		*node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	struct xfs_da_node_entry	*btree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	struct xfs_da3_blkinfo		*hdr3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 	struct xfs_da_args		*dargs = &ds->dargs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	struct xfs_inode		*ip = ds->dargs.dp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	xfs_ino_t			owner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	int				*pmaxrecs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 	struct xfs_da3_icnode_hdr	nodehdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	int				error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	blk = &ds->state->path.blk[level];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	ds->state->path.active = level + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	/* Release old block. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	if (blk->bp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 		xfs_trans_brelse(dargs->trans, blk->bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 		blk->bp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 	/* Check the pointer. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 	blk->blkno = blkno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 	if (!xchk_da_btree_ptr_ok(ds, level, blkno))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 		goto out_nobuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	/* Read the buffer. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	error = xfs_da_read_buf(dargs->trans, dargs->dp, blk->blkno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 			XFS_DABUF_MAP_HOLE_OK, &blk->bp, dargs->whichfork,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 			&xchk_da_btree_buf_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	if (!xchk_da_process_error(ds, level, &error))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 		goto out_nobuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	if (blk->bp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 		xchk_buffer_recheck(ds->sc, blk->bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	 * We didn't find a dir btree root block, which means that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	 * there's no LEAF1/LEAFN tree (at least not where it's supposed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	 * to be), so jump out now.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	if (ds->dargs.whichfork == XFS_DATA_FORK && level == 0 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 			blk->bp == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 		goto out_nobuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 	/* It's /not/ ok for attr trees not to have a da btree. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	if (blk->bp == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 		xchk_da_set_corrupt(ds, level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 		goto out_nobuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	hdr3 = blk->bp->b_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 	blk->magic = be16_to_cpu(hdr3->hdr.magic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	pmaxrecs = &ds->maxrecs[level];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	/* We only started zeroing the header on v5 filesystems. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	if (xfs_sb_version_hascrc(&ds->sc->mp->m_sb) && hdr3->hdr.pad)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 		xchk_da_set_corrupt(ds, level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	/* Check the owner. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 	if (xfs_sb_version_hascrc(&ip->i_mount->m_sb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 		owner = be64_to_cpu(hdr3->owner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 		if (owner != ip->i_ino)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 			xchk_da_set_corrupt(ds, level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	/* Check the siblings. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 	error = xchk_da_btree_block_check_siblings(ds, level, &hdr3->hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 	/* Interpret the buffer. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	switch (blk->magic) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	case XFS_ATTR_LEAF_MAGIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	case XFS_ATTR3_LEAF_MAGIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 		xfs_trans_buf_set_type(dargs->trans, blk->bp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 				XFS_BLFT_ATTR_LEAF_BUF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 		blk->magic = XFS_ATTR_LEAF_MAGIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 		blk->hashval = xfs_attr_leaf_lasthash(blk->bp, pmaxrecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 		if (ds->tree_level != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 			xchk_da_set_corrupt(ds, level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 	case XFS_DIR2_LEAFN_MAGIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 	case XFS_DIR3_LEAFN_MAGIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 		xfs_trans_buf_set_type(dargs->trans, blk->bp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 				XFS_BLFT_DIR_LEAFN_BUF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 		blk->magic = XFS_DIR2_LEAFN_MAGIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 		blk->hashval = xfs_dir2_leaf_lasthash(ip, blk->bp, pmaxrecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 		if (ds->tree_level != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 			xchk_da_set_corrupt(ds, level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	case XFS_DIR2_LEAF1_MAGIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 	case XFS_DIR3_LEAF1_MAGIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 		xfs_trans_buf_set_type(dargs->trans, blk->bp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 				XFS_BLFT_DIR_LEAF1_BUF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 		blk->magic = XFS_DIR2_LEAF1_MAGIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 		blk->hashval = xfs_dir2_leaf_lasthash(ip, blk->bp, pmaxrecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 		if (ds->tree_level != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 			xchk_da_set_corrupt(ds, level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	case XFS_DA_NODE_MAGIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 	case XFS_DA3_NODE_MAGIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 		xfs_trans_buf_set_type(dargs->trans, blk->bp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 				XFS_BLFT_DA_NODE_BUF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 		blk->magic = XFS_DA_NODE_MAGIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 		node = blk->bp->b_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 		xfs_da3_node_hdr_from_disk(ip->i_mount, &nodehdr, node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 		btree = nodehdr.btree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 		*pmaxrecs = nodehdr.count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 		blk->hashval = be32_to_cpu(btree[*pmaxrecs - 1].hashval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 		if (level == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 			if (nodehdr.level >= XFS_DA_NODE_MAXDEPTH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 				xchk_da_set_corrupt(ds, level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 				goto out_freebp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 			ds->tree_level = nodehdr.level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 			if (ds->tree_level != nodehdr.level) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 				xchk_da_set_corrupt(ds, level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 				goto out_freebp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 		/* XXX: Check hdr3.pad32 once we know how to fix it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 		xchk_da_set_corrupt(ds, level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 		goto out_freebp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 	 * If we've been handed a block that is below the dabtree root, does
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 	 * its hashval match what the parent block expected to see?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 	if (level > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 		struct xfs_da_node_entry	*key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 		key = xchk_da_btree_node_entry(ds, level - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 		if (be32_to_cpu(key->hashval) != blk->hashval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 			xchk_da_set_corrupt(ds, level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 			goto out_freebp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) out_freebp:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 	xfs_trans_brelse(dargs->trans, blk->bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 	blk->bp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) out_nobuf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	blk->blkno = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) /* Visit all nodes and leaves of a da btree. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) xchk_da_btree(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 	struct xfs_scrub		*sc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 	int				whichfork,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 	xchk_da_btree_rec_fn		scrub_fn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 	void				*private)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 	struct xchk_da_btree		ds = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 	struct xfs_mount		*mp = sc->mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 	struct xfs_da_state_blk		*blks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 	struct xfs_da_node_entry	*key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 	xfs_dablk_t			blkno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 	int				level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 	int				error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 	/* Skip short format data structures; no btree to scan. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 	if (!xfs_ifork_has_extents(XFS_IFORK_PTR(sc->ip, whichfork)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 	/* Set up initial da state. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 	ds.dargs.dp = sc->ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 	ds.dargs.whichfork = whichfork;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 	ds.dargs.trans = sc->tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 	ds.dargs.op_flags = XFS_DA_OP_OKNOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 	ds.state = xfs_da_state_alloc(&ds.dargs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 	ds.sc = sc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 	ds.private = private;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 	if (whichfork == XFS_ATTR_FORK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 		ds.dargs.geo = mp->m_attr_geo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 		ds.lowest = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 		ds.highest = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 		ds.dargs.geo = mp->m_dir_geo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 		ds.lowest = ds.dargs.geo->leafblk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 		ds.highest = ds.dargs.geo->freeblk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 	blkno = ds.lowest;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 	level = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 	/* Find the root of the da tree, if present. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 	blks = ds.state->path.blk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 	error = xchk_da_btree_block(&ds, level, blkno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 		goto out_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 	 * We didn't find a block at ds.lowest, which means that there's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 	 * no LEAF1/LEAFN tree (at least not where it's supposed to be),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 	 * so jump out now.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 	if (blks[level].bp == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 		goto out_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 	blks[level].index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 	while (level >= 0 && level < XFS_DA_NODE_MAXDEPTH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 		/* Handle leaf block. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 		if (blks[level].magic != XFS_DA_NODE_MAGIC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 			/* End of leaf, pop back towards the root. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 			if (blks[level].index >= ds.maxrecs[level]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 				if (level > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 					blks[level - 1].index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 				ds.tree_level++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 				level--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 			/* Dispatch record scrubbing. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 			error = scrub_fn(&ds, level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 			if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 			if (xchk_should_terminate(sc, &error) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 			    (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 			blks[level].index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 		/* End of node, pop back towards the root. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 		if (blks[level].index >= ds.maxrecs[level]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 			if (level > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 				blks[level - 1].index++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 			ds.tree_level++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 			level--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 		/* Hashes in order for scrub? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 		key = xchk_da_btree_node_entry(&ds, level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 		error = xchk_da_btree_hash(&ds, level, &key->hashval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 		/* Drill another level deeper. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 		blkno = be32_to_cpu(key->before);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 		level++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 		if (level >= XFS_DA_NODE_MAXDEPTH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 			/* Too deep! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 			xchk_da_set_corrupt(&ds, level - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 		ds.tree_level--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 		error = xchk_da_btree_block(&ds, level, blkno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 		if (blks[level].bp == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 		blks[level].index = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 	/* Release all the buffers we're tracking. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 	for (level = 0; level < XFS_DA_NODE_MAXDEPTH; level++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 		if (blks[level].bp == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 		xfs_trans_brelse(sc->tp, blks[level].bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 		blks[level].bp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) out_state:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 	xfs_da_state_free(ds.state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) }