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) 2000-2002,2005 Silicon Graphics, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  * All Rights Reserved.
^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_log_format.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11) #include "xfs_trans_resv.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12) #include "xfs_bit.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13) #include "xfs_mount.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_trans.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) #include "xfs_buf_item.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) #include "xfs_btree.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) #include "xfs_errortag.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) #include "xfs_error.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #include "xfs_trace.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) #include "xfs_alloc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) #include "xfs_log.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) #include "xfs_btree_staging.h"
^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)  * Cursor allocation zone.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) kmem_zone_t	*xfs_btree_cur_zone;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31)  * Btree magic numbers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) static const uint32_t xfs_magics[2][XFS_BTNUM_MAX] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) 	{ XFS_ABTB_MAGIC, XFS_ABTC_MAGIC, 0, XFS_BMAP_MAGIC, XFS_IBT_MAGIC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) 	  XFS_FIBT_MAGIC, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) 	{ XFS_ABTB_CRC_MAGIC, XFS_ABTC_CRC_MAGIC, XFS_RMAP_CRC_MAGIC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) 	  XFS_BMAP_CRC_MAGIC, XFS_IBT_CRC_MAGIC, XFS_FIBT_CRC_MAGIC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) 	  XFS_REFC_CRC_MAGIC }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) uint32_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) xfs_btree_magic(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) 	int			crc,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) 	xfs_btnum_t		btnum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) 	uint32_t		magic = xfs_magics[crc][btnum];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) 	/* Ensure we asked for crc for crc-only magics. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) 	ASSERT(magic != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) 	return magic;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54)  * Check a long btree block header.  Return the address of the failing check,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55)  * or NULL if everything is ok.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) xfs_failaddr_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) __xfs_btree_check_lblock(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) 	struct xfs_btree_block	*block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) 	int			level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) 	struct xfs_buf		*bp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) 	struct xfs_mount	*mp = cur->bc_mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) 	xfs_btnum_t		btnum = cur->bc_btnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) 	int			crc = xfs_sb_version_hascrc(&mp->m_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) 	if (crc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) 		if (!uuid_equal(&block->bb_u.l.bb_uuid, &mp->m_sb.sb_meta_uuid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) 			return __this_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) 		if (block->bb_u.l.bb_blkno !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) 		    cpu_to_be64(bp ? bp->b_bn : XFS_BUF_DADDR_NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) 			return __this_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) 		if (block->bb_u.l.bb_pad != cpu_to_be32(0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) 			return __this_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) 	if (be32_to_cpu(block->bb_magic) != xfs_btree_magic(crc, btnum))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) 		return __this_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) 	if (be16_to_cpu(block->bb_level) != level)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) 		return __this_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) 	if (be16_to_cpu(block->bb_numrecs) >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) 	    cur->bc_ops->get_maxrecs(cur, level))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) 		return __this_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 	if (block->bb_u.l.bb_leftsib != cpu_to_be64(NULLFSBLOCK) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) 	    !xfs_btree_check_lptr(cur, be64_to_cpu(block->bb_u.l.bb_leftsib),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 			level + 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 		return __this_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 	if (block->bb_u.l.bb_rightsib != cpu_to_be64(NULLFSBLOCK) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 	    !xfs_btree_check_lptr(cur, be64_to_cpu(block->bb_u.l.bb_rightsib),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 			level + 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 		return __this_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) /* Check a long btree block header. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) xfs_btree_check_lblock(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 	struct xfs_btree_block	*block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) 	int			level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) 	struct xfs_buf		*bp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 	struct xfs_mount	*mp = cur->bc_mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 	xfs_failaddr_t		fa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 	fa = __xfs_btree_check_lblock(cur, block, level, bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 	if (XFS_IS_CORRUPT(mp, fa != NULL) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 	    XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BTREE_CHECK_LBLOCK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 		if (bp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 			trace_xfs_btree_corrupt(bp, _RET_IP_);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 		return -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119)  * Check a short btree block header.  Return the address of the failing check,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120)  * or NULL if everything is ok.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) xfs_failaddr_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) __xfs_btree_check_sblock(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 	struct xfs_btree_block	*block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 	int			level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 	struct xfs_buf		*bp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 	struct xfs_mount	*mp = cur->bc_mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 	xfs_btnum_t		btnum = cur->bc_btnum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 	int			crc = xfs_sb_version_hascrc(&mp->m_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 	if (crc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 		if (!uuid_equal(&block->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 			return __this_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 		if (block->bb_u.s.bb_blkno !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 		    cpu_to_be64(bp ? bp->b_bn : XFS_BUF_DADDR_NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 			return __this_address;
^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) 	if (be32_to_cpu(block->bb_magic) != xfs_btree_magic(crc, btnum))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 		return __this_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 	if (be16_to_cpu(block->bb_level) != level)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 		return __this_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 	if (be16_to_cpu(block->bb_numrecs) >
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 	    cur->bc_ops->get_maxrecs(cur, level))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 		return __this_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 	if (block->bb_u.s.bb_leftsib != cpu_to_be32(NULLAGBLOCK) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 	    !xfs_btree_check_sptr(cur, be32_to_cpu(block->bb_u.s.bb_leftsib),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 			level + 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 		return __this_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 	if (block->bb_u.s.bb_rightsib != cpu_to_be32(NULLAGBLOCK) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 	    !xfs_btree_check_sptr(cur, be32_to_cpu(block->bb_u.s.bb_rightsib),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 			level + 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 		return __this_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) /* Check a short btree block header. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) xfs_btree_check_sblock(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 	struct xfs_btree_block	*block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 	int			level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 	struct xfs_buf		*bp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 	struct xfs_mount	*mp = cur->bc_mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 	xfs_failaddr_t		fa;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 	fa = __xfs_btree_check_sblock(cur, block, level, bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 	if (XFS_IS_CORRUPT(mp, fa != NULL) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 	    XFS_TEST_ERROR(false, mp, XFS_ERRTAG_BTREE_CHECK_SBLOCK)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 		if (bp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 			trace_xfs_btree_corrupt(bp, _RET_IP_);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 		return -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182)  * Debug routine: check that block header is ok.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) xfs_btree_check_block(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 	struct xfs_btree_cur	*cur,	/* btree cursor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 	struct xfs_btree_block	*block,	/* generic btree block pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 	int			level,	/* level of the btree block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 	struct xfs_buf		*bp)	/* buffer containing block, if any */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 	if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 		return xfs_btree_check_lblock(cur, block, level, bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 		return xfs_btree_check_sblock(cur, block, level, bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) /* Check that this long pointer is valid and points within the fs. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) xfs_btree_check_lptr(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 	xfs_fsblock_t		fsbno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 	int			level)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) 	if (level <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 	return xfs_verify_fsbno(cur->bc_mp, fsbno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) /* Check that this short pointer is valid and points within the AG. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) xfs_btree_check_sptr(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 	xfs_agblock_t		agbno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 	int			level)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 	if (level <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 	return xfs_verify_agbno(cur->bc_mp, cur->bc_ag.agno, agbno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222)  * Check that a given (indexed) btree pointer at a certain level of a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223)  * btree is valid and doesn't point past where it should.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) xfs_btree_check_ptr(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 	union xfs_btree_ptr	*ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 	int			index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 	int			level)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) 	if (cur->bc_flags & XFS_BTREE_LONG_PTRS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 		if (xfs_btree_check_lptr(cur, be64_to_cpu((&ptr->l)[index]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) 				level))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 		xfs_err(cur->bc_mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) "Inode %llu fork %d: Corrupt btree %d pointer at level %d index %d.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 				cur->bc_ino.ip->i_ino,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 				cur->bc_ino.whichfork, cur->bc_btnum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 				level, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 		if (xfs_btree_check_sptr(cur, be32_to_cpu((&ptr->s)[index]),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 				level))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 		xfs_err(cur->bc_mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) "AG %u: Corrupt btree %d pointer at level %d index %d.",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 				cur->bc_ag.agno, cur->bc_btnum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 				level, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 	return -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) # define xfs_btree_debug_check_ptr	xfs_btree_check_ptr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) # define xfs_btree_debug_check_ptr(...)	(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261)  * Calculate CRC on the whole btree block and stuff it into the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262)  * long-form btree header.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264)  * Prior to calculting the CRC, pull the LSN out of the buffer log item and put
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265)  * it into the buffer so recovery knows what the last modification was that made
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266)  * it to disk.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) xfs_btree_lblock_calc_crc(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 	struct xfs_buf		*bp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 	struct xfs_btree_block	*block = XFS_BUF_TO_BLOCK(bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 	struct xfs_buf_log_item	*bip = bp->b_log_item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 	if (!xfs_sb_version_hascrc(&bp->b_mount->m_sb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 	if (bip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 		block->bb_u.l.bb_lsn = cpu_to_be64(bip->bli_item.li_lsn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 	xfs_buf_update_cksum(bp, XFS_BTREE_LBLOCK_CRC_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) xfs_btree_lblock_verify_crc(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 	struct xfs_buf		*bp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 	struct xfs_btree_block	*block = XFS_BUF_TO_BLOCK(bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 	struct xfs_mount	*mp = bp->b_mount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 	if (xfs_sb_version_hascrc(&mp->m_sb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 		if (!xfs_log_check_lsn(mp, be64_to_cpu(block->bb_u.l.bb_lsn)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 		return xfs_buf_verify_cksum(bp, XFS_BTREE_LBLOCK_CRC_OFF);
^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) 	return true;
^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299)  * Calculate CRC on the whole btree block and stuff it into the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300)  * short-form btree header.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302)  * Prior to calculting the CRC, pull the LSN out of the buffer log item and put
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303)  * it into the buffer so recovery knows what the last modification was that made
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304)  * it to disk.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) xfs_btree_sblock_calc_crc(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 	struct xfs_buf		*bp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 	struct xfs_btree_block	*block = XFS_BUF_TO_BLOCK(bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 	struct xfs_buf_log_item	*bip = bp->b_log_item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 	if (!xfs_sb_version_hascrc(&bp->b_mount->m_sb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 	if (bip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 		block->bb_u.s.bb_lsn = cpu_to_be64(bip->bli_item.li_lsn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 	xfs_buf_update_cksum(bp, XFS_BTREE_SBLOCK_CRC_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) xfs_btree_sblock_verify_crc(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 	struct xfs_buf		*bp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 	struct xfs_btree_block  *block = XFS_BUF_TO_BLOCK(bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 	struct xfs_mount	*mp = bp->b_mount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 	if (xfs_sb_version_hascrc(&mp->m_sb)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 		if (!xfs_log_check_lsn(mp, be64_to_cpu(block->bb_u.s.bb_lsn)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 			return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 		return xfs_buf_verify_cksum(bp, XFS_BTREE_SBLOCK_CRC_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 	return true;
^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) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) xfs_btree_free_block(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 	struct xfs_buf		*bp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 	int			error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 	error = cur->bc_ops->free_block(cur, bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 	if (!error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 		xfs_trans_binval(cur->bc_tp, bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 		XFS_BTREE_STATS_INC(cur, free);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 	return error;
^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352)  * Delete the btree cursor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) xfs_btree_del_cursor(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 	xfs_btree_cur_t	*cur,		/* btree cursor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 	int		error)		/* del because of error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 	int		i;		/* btree level */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 	 * Clear the buffer pointers, and release the buffers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 	 * If we're doing this in the face of an error, we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 	 * need to make sure to inspect all of the entries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 	 * in the bc_bufs array for buffers to be unlocked.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 	 * This is because some of the btree code works from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 	 * level n down to 0, and if we get an error along
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 	 * the way we won't have initialized all the entries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 	 * down to 0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 	for (i = 0; i < cur->bc_nlevels; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 		if (cur->bc_bufs[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 			xfs_trans_brelse(cur->bc_tp, cur->bc_bufs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 		else if (!error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 	 * Can't free a bmap cursor without having dealt with the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 	 * allocated indirect blocks' accounting.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 	ASSERT(cur->bc_btnum != XFS_BTNUM_BMAP ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 	       cur->bc_ino.allocated == 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 	 * Free the cursor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 	if (unlikely(cur->bc_flags & XFS_BTREE_STAGING))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 		kmem_free((void *)cur->bc_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 	kmem_cache_free(xfs_btree_cur_zone, cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392)  * Duplicate the btree cursor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393)  * Allocate a new one, copy the record, re-get the buffers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) int					/* error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) xfs_btree_dup_cursor(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 	xfs_btree_cur_t	*cur,		/* input cursor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 	xfs_btree_cur_t	**ncur)		/* output cursor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 	xfs_buf_t	*bp;		/* btree block's buffer pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 	int		error;		/* error return value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 	int		i;		/* level number of btree block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 	xfs_mount_t	*mp;		/* mount structure for filesystem */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 	xfs_btree_cur_t	*new;		/* new cursor value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 	xfs_trans_t	*tp;		/* transaction pointer, can be NULL */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 	tp = cur->bc_tp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 	mp = cur->bc_mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 	 * Allocate a new cursor like the old one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 	new = cur->bc_ops->dup_cursor(cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 	 * Copy the record currently in the cursor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 	new->bc_rec = cur->bc_rec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 	 * For each level current, re-get the buffer and copy the ptr value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 	for (i = 0; i < new->bc_nlevels; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 		new->bc_ptrs[i] = cur->bc_ptrs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 		new->bc_ra[i] = cur->bc_ra[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 		bp = cur->bc_bufs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 		if (bp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 			error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 						   XFS_BUF_ADDR(bp), mp->m_bsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 						   0, &bp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 						   cur->bc_ops->buf_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 			if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 				xfs_btree_del_cursor(new, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 				*ncur = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 				return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 		new->bc_bufs[i] = bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 	*ncur = new;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 	return 0;
^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)  * XFS btree block layout and addressing:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447)  * There are two types of blocks in the btree: leaf and non-leaf blocks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449)  * The leaf record start with a header then followed by records containing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450)  * the values.  A non-leaf block also starts with the same header, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451)  * then first contains lookup keys followed by an equal number of pointers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452)  * to the btree blocks at the previous level.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454)  *		+--------+-------+-------+-------+-------+-------+-------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455)  * Leaf:	| header | rec 1 | rec 2 | rec 3 | rec 4 | rec 5 | rec N |
^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)  *		+--------+-------+-------+-------+-------+-------+-------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459)  * Non-Leaf:	| header | key 1 | key 2 | key N | ptr 1 | ptr 2 | ptr N |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460)  *		+--------+-------+-------+-------+-------+-------+-------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462)  * The header is called struct xfs_btree_block for reasons better left unknown
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463)  * and comes in different versions for short (32bit) and long (64bit) block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464)  * pointers.  The record and key structures are defined by the btree instances
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465)  * and opaque to the btree core.  The block pointers are simple disk endian
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466)  * integers, available in a short (32bit) and long (64bit) variant.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468)  * The helpers below calculate the offset of a given record, key or pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469)  * into a btree block (xfs_btree_*_offset) or return a pointer to the given
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470)  * record, key or pointer (xfs_btree_*_addr).  Note that all addressing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471)  * inside the btree block is done using indices starting at one, not zero!
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473)  * If XFS_BTREE_OVERLAPPING is set, then this btree supports keys containing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474)  * overlapping intervals.  In such a tree, records are still sorted lowest to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475)  * highest and indexed by the smallest key value that refers to the record.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476)  * However, nodes are different: each pointer has two associated keys -- one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477)  * indexing the lowest key available in the block(s) below (the same behavior
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478)  * as the key in a regular btree) and another indexing the highest key
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479)  * available in the block(s) below.  Because records are /not/ sorted by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480)  * highest key, all leaf block updates require us to compute the highest key
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481)  * that matches any record in the leaf and to recursively update the high keys
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482)  * in the nodes going further up in the tree, if necessary.  Nodes look like
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483)  * this:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485)  *		+--------+-----+-----+-----+-----+-----+-------+-------+-----+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486)  * Non-Leaf:	| header | lo1 | hi1 | lo2 | hi2 | ... | ptr 1 | ptr 2 | ... |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487)  *		+--------+-----+-----+-----+-----+-----+-------+-------+-----+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489)  * To perform an interval query on an overlapped tree, perform the usual
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490)  * depth-first search and use the low and high keys to decide if we can skip
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491)  * that particular node.  If a leaf node is reached, return the records that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492)  * intersect the interval.  Note that an interval query may return numerous
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493)  * entries.  For a non-overlapped tree, simply search for the record associated
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494)  * with the lowest key and iterate forward until a non-matching record is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495)  * found.  Section 14.3 ("Interval Trees") of _Introduction to Algorithms_ by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496)  * Cormen, Leiserson, Rivest, and Stein (2nd or 3rd ed. only) discuss this in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497)  * more detail.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499)  * Why do we care about overlapping intervals?  Let's say you have a bunch of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500)  * reverse mapping records on a reflink filesystem:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502)  * 1: +- file A startblock B offset C length D -----------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503)  * 2:      +- file E startblock F offset G length H --------------+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504)  * 3:      +- file I startblock F offset J length K --+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505)  * 4:                                                        +- file L... --+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507)  * Now say we want to map block (B+D) into file A at offset (C+D).  Ideally,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508)  * we'd simply increment the length of record 1.  But how do we find the record
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509)  * that ends at (B+D-1) (i.e. record 1)?  A LE lookup of (B+D-1) would return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510)  * record 3 because the keys are ordered first by startblock.  An interval
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511)  * query would return records 1 and 2 because they both overlap (B+D-1), and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512)  * from that we can pick out record 1 as the appropriate left neighbor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514)  * In the non-overlapped case you can do a LE lookup and decrement the cursor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515)  * because a record's interval must end before the next record.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519)  * Return size of the btree block header for this btree instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) static inline size_t xfs_btree_block_len(struct xfs_btree_cur *cur)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 	if (cur->bc_flags & XFS_BTREE_LONG_PTRS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 		if (cur->bc_flags & XFS_BTREE_CRC_BLOCKS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 			return XFS_BTREE_LBLOCK_CRC_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 		return XFS_BTREE_LBLOCK_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 	if (cur->bc_flags & XFS_BTREE_CRC_BLOCKS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 		return XFS_BTREE_SBLOCK_CRC_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 	return XFS_BTREE_SBLOCK_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) }
^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)  * Return size of btree block pointers for this btree instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) static inline size_t xfs_btree_ptr_len(struct xfs_btree_cur *cur)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 	return (cur->bc_flags & XFS_BTREE_LONG_PTRS) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 		sizeof(__be64) : sizeof(__be32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543)  * Calculate offset of the n-th record in a btree block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) STATIC size_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) xfs_btree_rec_offset(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 	int			n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 	return xfs_btree_block_len(cur) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 		(n - 1) * cur->bc_ops->rec_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555)  * Calculate offset of the n-th key in a btree block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) STATIC size_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) xfs_btree_key_offset(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 	int			n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 	return xfs_btree_block_len(cur) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 		(n - 1) * cur->bc_ops->key_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567)  * Calculate offset of the n-th high key in a btree block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) STATIC size_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) xfs_btree_high_key_offset(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 	int			n)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 	return xfs_btree_block_len(cur) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 		(n - 1) * cur->bc_ops->key_len + (cur->bc_ops->key_len / 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579)  * Calculate offset of the n-th block pointer in a btree block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) STATIC size_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) xfs_btree_ptr_offset(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 	int			n,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 	int			level)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 	return xfs_btree_block_len(cur) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 		cur->bc_ops->get_maxrecs(cur, level) * cur->bc_ops->key_len +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 		(n - 1) * xfs_btree_ptr_len(cur);
^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) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593)  * Return a pointer to the n-th record in the btree block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) union xfs_btree_rec *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) xfs_btree_rec_addr(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 	int			n,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 	struct xfs_btree_block	*block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 	return (union xfs_btree_rec *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 		((char *)block + xfs_btree_rec_offset(cur, n));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606)  * Return a pointer to the n-th key in the btree block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) union xfs_btree_key *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) xfs_btree_key_addr(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 	int			n,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 	struct xfs_btree_block	*block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 	return (union xfs_btree_key *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 		((char *)block + xfs_btree_key_offset(cur, n));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619)  * Return a pointer to the n-th high key in the btree block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) union xfs_btree_key *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) xfs_btree_high_key_addr(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 	int			n,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 	struct xfs_btree_block	*block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 	return (union xfs_btree_key *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 		((char *)block + xfs_btree_high_key_offset(cur, n));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632)  * Return a pointer to the n-th block pointer in the btree block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) union xfs_btree_ptr *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) xfs_btree_ptr_addr(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 	int			n,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 	struct xfs_btree_block	*block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 	int			level = xfs_btree_get_level(block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 	ASSERT(block->bb_level != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 	return (union xfs_btree_ptr *)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 		((char *)block + xfs_btree_ptr_offset(cur, n, level));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) struct xfs_ifork *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) xfs_btree_ifork_ptr(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 	struct xfs_btree_cur	*cur)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 	ASSERT(cur->bc_flags & XFS_BTREE_ROOT_IN_INODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 	if (cur->bc_flags & XFS_BTREE_STAGING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 		return cur->bc_ino.ifake->if_fork;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 	return XFS_IFORK_PTR(cur->bc_ino.ip, cur->bc_ino.whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660)  * Get the root block which is stored in the inode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662)  * For now this btree implementation assumes the btree root is always
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663)  * stored in the if_broot field of an inode fork.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) STATIC struct xfs_btree_block *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) xfs_btree_get_iroot(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 	struct xfs_btree_cur	*cur)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 	struct xfs_ifork	*ifp = xfs_btree_ifork_ptr(cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 	return (struct xfs_btree_block *)ifp->if_broot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675)  * Retrieve the block pointer from the cursor at the given level.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676)  * This may be an inode btree root or from a buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) struct xfs_btree_block *		/* generic btree block pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) xfs_btree_get_block(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 	struct xfs_btree_cur	*cur,	/* btree cursor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 	int			level,	/* level in btree */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 	struct xfs_buf		**bpp)	/* buffer containing the block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 	if ((cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 	    (level == cur->bc_nlevels - 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 		*bpp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 		return xfs_btree_get_iroot(cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 	*bpp = cur->bc_bufs[level];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 	return XFS_BUF_TO_BLOCK(*bpp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695)  * Change the cursor to point to the first record at the given level.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696)  * Other levels are unaffected.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) STATIC int				/* success=1, failure=0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) xfs_btree_firstrec(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 	xfs_btree_cur_t		*cur,	/* btree cursor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 	int			level)	/* level to change */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 	struct xfs_btree_block	*block;	/* generic btree block pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 	xfs_buf_t		*bp;	/* buffer containing block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 	 * Get the block pointer for this level.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 	block = xfs_btree_get_block(cur, level, &bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 	if (xfs_btree_check_block(cur, block, level, bp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 	 * It's empty, there is no such record.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 	if (!block->bb_numrecs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 	 * Set the ptr value to 1, that's the first record/key.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 	cur->bc_ptrs[level] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725)  * Change the cursor to point to the last record in the current block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726)  * at the given level.  Other levels are unaffected.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) STATIC int				/* success=1, failure=0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) xfs_btree_lastrec(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 	xfs_btree_cur_t		*cur,	/* btree cursor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 	int			level)	/* level to change */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 	struct xfs_btree_block	*block;	/* generic btree block pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 	xfs_buf_t		*bp;	/* buffer containing block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 	 * Get the block pointer for this level.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 	block = xfs_btree_get_block(cur, level, &bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 	if (xfs_btree_check_block(cur, block, level, bp))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 	 * It's empty, there is no such record.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 	if (!block->bb_numrecs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 	 * Set the ptr value to numrecs, that's the last record/key.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 	cur->bc_ptrs[level] = be16_to_cpu(block->bb_numrecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755)  * Compute first and last byte offsets for the fields given.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756)  * Interprets the offsets table, which contains struct field offsets.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) xfs_btree_offsets(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 	int64_t		fields,		/* bitmask of fields */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 	const short	*offsets,	/* table of field offsets */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 	int		nbits,		/* number of bits to inspect */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 	int		*first,		/* output: first byte offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 	int		*last)		/* output: last byte offset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 	int		i;		/* current bit number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 	int64_t		imask;		/* mask for current bit number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 	ASSERT(fields != 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 	 * Find the lowest bit, so the first byte offset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 	for (i = 0, imask = 1LL; ; i++, imask <<= 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 		if (imask & fields) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 			*first = offsets[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 			break;
^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) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 	 * Find the highest bit, so the last byte offset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 	for (i = nbits - 1, imask = 1LL << i; ; i--, imask >>= 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 		if (imask & fields) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 			*last = offsets[i + 1] - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791)  * Get a buffer for the block, return it read in.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792)  * Long-form addressing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) xfs_btree_read_bufl(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 	struct xfs_mount	*mp,		/* file system mount point */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 	struct xfs_trans	*tp,		/* transaction pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 	xfs_fsblock_t		fsbno,		/* file system block number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 	struct xfs_buf		**bpp,		/* buffer for fsbno */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 	int			refval,		/* ref count value for buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 	const struct xfs_buf_ops *ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 	struct xfs_buf		*bp;		/* return value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 	xfs_daddr_t		d;		/* real disk block address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 	int			error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 	if (!xfs_verify_fsbno(mp, fsbno))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 		return -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 	d = XFS_FSB_TO_DADDR(mp, fsbno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) 	error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 				   mp->m_bsize, 0, &bp, ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 	if (bp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 		xfs_buf_set_ref(bp, refval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 	*bpp = bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821)  * Read-ahead the block, don't wait for it, don't return a buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822)  * Long-form addressing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) /* ARGSUSED */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) xfs_btree_reada_bufl(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 	struct xfs_mount	*mp,		/* file system mount point */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 	xfs_fsblock_t		fsbno,		/* file system block number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 	xfs_extlen_t		count,		/* count of filesystem blocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 	const struct xfs_buf_ops *ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 	xfs_daddr_t		d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 	ASSERT(fsbno != NULLFSBLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 	d = XFS_FSB_TO_DADDR(mp, fsbno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 	xfs_buf_readahead(mp->m_ddev_targp, d, mp->m_bsize * count, ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840)  * Read-ahead the block, don't wait for it, don't return a buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841)  * Short-form addressing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) /* ARGSUSED */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) xfs_btree_reada_bufs(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 	struct xfs_mount	*mp,		/* file system mount point */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 	xfs_agnumber_t		agno,		/* allocation group number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 	xfs_agblock_t		agbno,		/* allocation group block number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 	xfs_extlen_t		count,		/* count of filesystem blocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 	const struct xfs_buf_ops *ops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 	xfs_daddr_t		d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 	ASSERT(agno != NULLAGNUMBER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 	ASSERT(agbno != NULLAGBLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 	d = XFS_AGB_TO_DADDR(mp, agno, agbno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 	xfs_buf_readahead(mp->m_ddev_targp, d, mp->m_bsize * count, ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) xfs_btree_readahead_lblock(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 	int			lr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 	struct xfs_btree_block	*block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 	int			rval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 	xfs_fsblock_t		left = be64_to_cpu(block->bb_u.l.bb_leftsib);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 	xfs_fsblock_t		right = be64_to_cpu(block->bb_u.l.bb_rightsib);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 	if ((lr & XFS_BTCUR_LEFTRA) && left != NULLFSBLOCK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 		xfs_btree_reada_bufl(cur->bc_mp, left, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 				     cur->bc_ops->buf_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 		rval++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 	if ((lr & XFS_BTCUR_RIGHTRA) && right != NULLFSBLOCK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 		xfs_btree_reada_bufl(cur->bc_mp, right, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 				     cur->bc_ops->buf_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 		rval++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) xfs_btree_readahead_sblock(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 	int			lr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 	struct xfs_btree_block *block)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 	int			rval = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 	xfs_agblock_t		left = be32_to_cpu(block->bb_u.s.bb_leftsib);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 	xfs_agblock_t		right = be32_to_cpu(block->bb_u.s.bb_rightsib);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 	if ((lr & XFS_BTCUR_LEFTRA) && left != NULLAGBLOCK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 		xfs_btree_reada_bufs(cur->bc_mp, cur->bc_ag.agno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 				     left, 1, cur->bc_ops->buf_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 		rval++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 	if ((lr & XFS_BTCUR_RIGHTRA) && right != NULLAGBLOCK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 		xfs_btree_reada_bufs(cur->bc_mp, cur->bc_ag.agno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 				     right, 1, cur->bc_ops->buf_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 		rval++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912)  * Read-ahead btree blocks, at the given level.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913)  * Bits in lr are set from XFS_BTCUR_{LEFT,RIGHT}RA.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) xfs_btree_readahead(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 	struct xfs_btree_cur	*cur,		/* btree cursor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 	int			lev,		/* level in btree */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 	int			lr)		/* left/right bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 	struct xfs_btree_block	*block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 	 * No readahead needed if we are at the root level and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 	 * btree root is stored in the inode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 	if ((cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 	    (lev == cur->bc_nlevels - 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 	if ((cur->bc_ra[lev] | lr) == cur->bc_ra[lev])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 	cur->bc_ra[lev] |= lr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 	block = XFS_BUF_TO_BLOCK(cur->bc_bufs[lev]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 	if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 		return xfs_btree_readahead_lblock(cur, lr, block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 	return xfs_btree_readahead_sblock(cur, lr, block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) xfs_btree_ptr_to_daddr(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 	union xfs_btree_ptr	*ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 	xfs_daddr_t		*daddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 	xfs_fsblock_t		fsbno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 	xfs_agblock_t		agbno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 	int			error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 	error = xfs_btree_check_ptr(cur, ptr, 0, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 	if (cur->bc_flags & XFS_BTREE_LONG_PTRS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 		fsbno = be64_to_cpu(ptr->l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 		*daddr = XFS_FSB_TO_DADDR(cur->bc_mp, fsbno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 		agbno = be32_to_cpu(ptr->s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 		*daddr = XFS_AGB_TO_DADDR(cur->bc_mp, cur->bc_ag.agno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 				agbno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969)  * Readahead @count btree blocks at the given @ptr location.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971)  * We don't need to care about long or short form btrees here as we have a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972)  * method of converting the ptr directly to a daddr available to us.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) STATIC void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) xfs_btree_readahead_ptr(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 	union xfs_btree_ptr	*ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 	xfs_extlen_t		count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 	xfs_daddr_t		daddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 	if (xfs_btree_ptr_to_daddr(cur, ptr, &daddr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 	xfs_buf_readahead(cur->bc_mp->m_ddev_targp, daddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 			  cur->bc_mp->m_bsize * count, cur->bc_ops->buf_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989)  * Set the buffer for level "lev" in the cursor to bp, releasing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990)  * any previous buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) STATIC void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) xfs_btree_setbuf(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 	xfs_btree_cur_t		*cur,	/* btree cursor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 	int			lev,	/* level in btree */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 	xfs_buf_t		*bp)	/* new buffer to set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 	struct xfs_btree_block	*b;	/* btree block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 	if (cur->bc_bufs[lev])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 		xfs_trans_brelse(cur->bc_tp, cur->bc_bufs[lev]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 	cur->bc_bufs[lev] = bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 	cur->bc_ra[lev] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 	b = XFS_BUF_TO_BLOCK(bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 	if (cur->bc_flags & XFS_BTREE_LONG_PTRS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 		if (b->bb_u.l.bb_leftsib == cpu_to_be64(NULLFSBLOCK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 			cur->bc_ra[lev] |= XFS_BTCUR_LEFTRA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 		if (b->bb_u.l.bb_rightsib == cpu_to_be64(NULLFSBLOCK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 			cur->bc_ra[lev] |= XFS_BTCUR_RIGHTRA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 		if (b->bb_u.s.bb_leftsib == cpu_to_be32(NULLAGBLOCK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 			cur->bc_ra[lev] |= XFS_BTCUR_LEFTRA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 		if (b->bb_u.s.bb_rightsib == cpu_to_be32(NULLAGBLOCK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 			cur->bc_ra[lev] |= XFS_BTCUR_RIGHTRA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) xfs_btree_ptr_is_null(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 	union xfs_btree_ptr	*ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 	if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 		return ptr->l == cpu_to_be64(NULLFSBLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 		return ptr->s == cpu_to_be32(NULLAGBLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) xfs_btree_set_ptr_null(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 	union xfs_btree_ptr	*ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 	if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 		ptr->l = cpu_to_be64(NULLFSBLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 		ptr->s = cpu_to_be32(NULLAGBLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042)  * Get/set/init sibling pointers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) xfs_btree_get_sibling(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 	struct xfs_btree_block	*block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 	union xfs_btree_ptr	*ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 	int			lr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 	ASSERT(lr == XFS_BB_LEFTSIB || lr == XFS_BB_RIGHTSIB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 	if (cur->bc_flags & XFS_BTREE_LONG_PTRS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 		if (lr == XFS_BB_RIGHTSIB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 			ptr->l = block->bb_u.l.bb_rightsib;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 			ptr->l = block->bb_u.l.bb_leftsib;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 		if (lr == XFS_BB_RIGHTSIB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 			ptr->s = block->bb_u.s.bb_rightsib;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 			ptr->s = block->bb_u.s.bb_leftsib;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) xfs_btree_set_sibling(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 	struct xfs_btree_block	*block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 	union xfs_btree_ptr	*ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 	int			lr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 	ASSERT(lr == XFS_BB_LEFTSIB || lr == XFS_BB_RIGHTSIB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 	if (cur->bc_flags & XFS_BTREE_LONG_PTRS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 		if (lr == XFS_BB_RIGHTSIB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 			block->bb_u.l.bb_rightsib = ptr->l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 			block->bb_u.l.bb_leftsib = ptr->l;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 		if (lr == XFS_BB_RIGHTSIB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 			block->bb_u.s.bb_rightsib = ptr->s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 			block->bb_u.s.bb_leftsib = ptr->s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) xfs_btree_init_block_int(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 	struct xfs_mount	*mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 	struct xfs_btree_block	*buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 	xfs_daddr_t		blkno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 	xfs_btnum_t		btnum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 	__u16			level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 	__u16			numrecs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 	__u64			owner,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 	unsigned int		flags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 	int			crc = xfs_sb_version_hascrc(&mp->m_sb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 	__u32			magic = xfs_btree_magic(crc, btnum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 	buf->bb_magic = cpu_to_be32(magic);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 	buf->bb_level = cpu_to_be16(level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 	buf->bb_numrecs = cpu_to_be16(numrecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 	if (flags & XFS_BTREE_LONG_PTRS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 		buf->bb_u.l.bb_leftsib = cpu_to_be64(NULLFSBLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 		buf->bb_u.l.bb_rightsib = cpu_to_be64(NULLFSBLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 		if (crc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 			buf->bb_u.l.bb_blkno = cpu_to_be64(blkno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 			buf->bb_u.l.bb_owner = cpu_to_be64(owner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 			uuid_copy(&buf->bb_u.l.bb_uuid, &mp->m_sb.sb_meta_uuid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 			buf->bb_u.l.bb_pad = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 			buf->bb_u.l.bb_lsn = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 		/* owner is a 32 bit value on short blocks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 		__u32 __owner = (__u32)owner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 		buf->bb_u.s.bb_leftsib = cpu_to_be32(NULLAGBLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 		buf->bb_u.s.bb_rightsib = cpu_to_be32(NULLAGBLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 		if (crc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 			buf->bb_u.s.bb_blkno = cpu_to_be64(blkno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 			buf->bb_u.s.bb_owner = cpu_to_be32(__owner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 			uuid_copy(&buf->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 			buf->bb_u.s.bb_lsn = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) xfs_btree_init_block(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 	struct xfs_mount *mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 	struct xfs_buf	*bp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 	xfs_btnum_t	btnum,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 	__u16		level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 	__u16		numrecs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 	__u64		owner)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 	xfs_btree_init_block_int(mp, XFS_BUF_TO_BLOCK(bp), bp->b_bn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 				 btnum, level, numrecs, owner, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) xfs_btree_init_block_cur(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 	struct xfs_buf		*bp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 	int			level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 	int			numrecs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 	__u64			owner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 	 * we can pull the owner from the cursor right now as the different
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 	 * owners align directly with the pointer size of the btree. This may
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 	 * change in future, but is safe for current users of the generic btree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 	 * code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 	if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 		owner = cur->bc_ino.ip->i_ino;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 		owner = cur->bc_ag.agno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 	xfs_btree_init_block_int(cur->bc_mp, XFS_BUF_TO_BLOCK(bp), bp->b_bn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 				 cur->bc_btnum, level, numrecs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 				 owner, cur->bc_flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170)  * Return true if ptr is the last record in the btree and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171)  * we need to track updates to this record.  The decision
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172)  * will be further refined in the update_lastrec method.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) xfs_btree_is_lastrec(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 	struct xfs_btree_block	*block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 	int			level)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 	union xfs_btree_ptr	ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 	if (level > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 	if (!(cur->bc_flags & XFS_BTREE_LASTREC_UPDATE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 	xfs_btree_get_sibling(cur, block, &ptr, XFS_BB_RIGHTSIB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 	if (!xfs_btree_ptr_is_null(cur, &ptr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) STATIC void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) xfs_btree_buf_to_ptr(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 	struct xfs_buf		*bp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 	union xfs_btree_ptr	*ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 	if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 		ptr->l = cpu_to_be64(XFS_DADDR_TO_FSB(cur->bc_mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 					XFS_BUF_ADDR(bp)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 		ptr->s = cpu_to_be32(xfs_daddr_to_agbno(cur->bc_mp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 					XFS_BUF_ADDR(bp)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) STATIC void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) xfs_btree_set_refs(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 	struct xfs_buf		*bp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 	switch (cur->bc_btnum) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 	case XFS_BTNUM_BNO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 	case XFS_BTNUM_CNT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 		xfs_buf_set_ref(bp, XFS_ALLOC_BTREE_REF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 	case XFS_BTNUM_INO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 	case XFS_BTNUM_FINO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 		xfs_buf_set_ref(bp, XFS_INO_BTREE_REF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 	case XFS_BTNUM_BMAP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 		xfs_buf_set_ref(bp, XFS_BMAP_BTREE_REF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 	case XFS_BTNUM_RMAP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 		xfs_buf_set_ref(bp, XFS_RMAP_BTREE_REF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 	case XFS_BTNUM_REFC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 		xfs_buf_set_ref(bp, XFS_REFC_BTREE_REF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 		ASSERT(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) xfs_btree_get_buf_block(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 	union xfs_btree_ptr	*ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 	struct xfs_btree_block	**block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 	struct xfs_buf		**bpp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 	struct xfs_mount	*mp = cur->bc_mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 	xfs_daddr_t		d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 	int			error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 	error = xfs_btree_ptr_to_daddr(cur, ptr, &d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) 	error = xfs_trans_get_buf(cur->bc_tp, mp->m_ddev_targp, d, mp->m_bsize,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 			0, bpp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 	(*bpp)->b_ops = cur->bc_ops->buf_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 	*block = XFS_BUF_TO_BLOCK(*bpp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261)  * Read in the buffer at the given ptr and return the buffer and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262)  * the block pointer within the buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) xfs_btree_read_buf_block(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 	union xfs_btree_ptr	*ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 	int			flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 	struct xfs_btree_block	**block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 	struct xfs_buf		**bpp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 	struct xfs_mount	*mp = cur->bc_mp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 	xfs_daddr_t		d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 	int			error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 	/* need to sort out how callers deal with failures first */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 	ASSERT(!(flags & XBF_TRYLOCK));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 	error = xfs_btree_ptr_to_daddr(cur, ptr, &d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 	error = xfs_trans_read_buf(mp, cur->bc_tp, mp->m_ddev_targp, d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 				   mp->m_bsize, flags, bpp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 				   cur->bc_ops->buf_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) 	xfs_btree_set_refs(cur, *bpp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 	*block = XFS_BUF_TO_BLOCK(*bpp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294)  * Copy keys from one btree block to another.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) xfs_btree_copy_keys(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) 	union xfs_btree_key	*dst_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) 	union xfs_btree_key	*src_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) 	int			numkeys)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) 	ASSERT(numkeys >= 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) 	memcpy(dst_key, src_key, numkeys * cur->bc_ops->key_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308)  * Copy records from one btree block to another.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) STATIC void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) xfs_btree_copy_recs(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) 	union xfs_btree_rec	*dst_rec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) 	union xfs_btree_rec	*src_rec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) 	int			numrecs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) 	ASSERT(numrecs >= 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) 	memcpy(dst_rec, src_rec, numrecs * cur->bc_ops->rec_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322)  * Copy block pointers from one btree block to another.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) xfs_btree_copy_ptrs(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) 	union xfs_btree_ptr	*dst_ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) 	const union xfs_btree_ptr *src_ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) 	int			numptrs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) 	ASSERT(numptrs >= 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) 	memcpy(dst_ptr, src_ptr, numptrs * xfs_btree_ptr_len(cur));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336)  * Shift keys one index left/right inside a single btree block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) STATIC void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) xfs_btree_shift_keys(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) 	union xfs_btree_key	*key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) 	int			dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) 	int			numkeys)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) 	char			*dst_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) 	ASSERT(numkeys >= 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) 	ASSERT(dir == 1 || dir == -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) 	dst_key = (char *)key + (dir * cur->bc_ops->key_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) 	memmove(dst_key, key, numkeys * cur->bc_ops->key_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355)  * Shift records one index left/right inside a single btree block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) STATIC void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) xfs_btree_shift_recs(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) 	union xfs_btree_rec	*rec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) 	int			dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) 	int			numrecs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) 	char			*dst_rec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) 	ASSERT(numrecs >= 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) 	ASSERT(dir == 1 || dir == -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) 	dst_rec = (char *)rec + (dir * cur->bc_ops->rec_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) 	memmove(dst_rec, rec, numrecs * cur->bc_ops->rec_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374)  * Shift block pointers one index left/right inside a single btree block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) STATIC void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) xfs_btree_shift_ptrs(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) 	union xfs_btree_ptr	*ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) 	int			dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) 	int			numptrs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) 	char			*dst_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) 	ASSERT(numptrs >= 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) 	ASSERT(dir == 1 || dir == -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) 	dst_ptr = (char *)ptr + (dir * xfs_btree_ptr_len(cur));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) 	memmove(dst_ptr, ptr, numptrs * xfs_btree_ptr_len(cur));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393)  * Log key values from the btree block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) STATIC void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) xfs_btree_log_keys(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) 	struct xfs_buf		*bp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) 	int			first,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) 	int			last)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) 	if (bp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) 		xfs_trans_buf_set_type(cur->bc_tp, bp, XFS_BLFT_BTREE_BUF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) 		xfs_trans_log_buf(cur->bc_tp, bp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) 				  xfs_btree_key_offset(cur, first),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) 				  xfs_btree_key_offset(cur, last + 1) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) 		xfs_trans_log_inode(cur->bc_tp, cur->bc_ino.ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) 				xfs_ilog_fbroot(cur->bc_ino.whichfork));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415)  * Log record values from the btree block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) xfs_btree_log_recs(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) 	struct xfs_buf		*bp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) 	int			first,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) 	int			last)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) 	xfs_trans_buf_set_type(cur->bc_tp, bp, XFS_BLFT_BTREE_BUF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) 	xfs_trans_log_buf(cur->bc_tp, bp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) 			  xfs_btree_rec_offset(cur, first),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) 			  xfs_btree_rec_offset(cur, last + 1) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433)  * Log block pointer fields from a btree block (nonleaf).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) STATIC void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) xfs_btree_log_ptrs(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) 	struct xfs_btree_cur	*cur,	/* btree cursor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) 	struct xfs_buf		*bp,	/* buffer containing btree block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) 	int			first,	/* index of first pointer to log */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) 	int			last)	/* index of last pointer to log */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) 	if (bp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) 		struct xfs_btree_block	*block = XFS_BUF_TO_BLOCK(bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) 		int			level = xfs_btree_get_level(block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) 		xfs_trans_buf_set_type(cur->bc_tp, bp, XFS_BLFT_BTREE_BUF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) 		xfs_trans_log_buf(cur->bc_tp, bp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) 				xfs_btree_ptr_offset(cur, first, level),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) 				xfs_btree_ptr_offset(cur, last + 1, level) - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) 		xfs_trans_log_inode(cur->bc_tp, cur->bc_ino.ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) 			xfs_ilog_fbroot(cur->bc_ino.whichfork));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459)  * Log fields from a btree block header.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) xfs_btree_log_block(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) 	struct xfs_btree_cur	*cur,	/* btree cursor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) 	struct xfs_buf		*bp,	/* buffer containing btree block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) 	int			fields)	/* mask of fields: XFS_BB_... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) 	int			first;	/* first byte offset logged */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) 	int			last;	/* last byte offset logged */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) 	static const short	soffsets[] = {	/* table of offsets (short) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) 		offsetof(struct xfs_btree_block, bb_magic),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) 		offsetof(struct xfs_btree_block, bb_level),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) 		offsetof(struct xfs_btree_block, bb_numrecs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) 		offsetof(struct xfs_btree_block, bb_u.s.bb_leftsib),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) 		offsetof(struct xfs_btree_block, bb_u.s.bb_rightsib),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) 		offsetof(struct xfs_btree_block, bb_u.s.bb_blkno),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) 		offsetof(struct xfs_btree_block, bb_u.s.bb_lsn),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) 		offsetof(struct xfs_btree_block, bb_u.s.bb_uuid),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) 		offsetof(struct xfs_btree_block, bb_u.s.bb_owner),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) 		offsetof(struct xfs_btree_block, bb_u.s.bb_crc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) 		XFS_BTREE_SBLOCK_CRC_LEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) 	static const short	loffsets[] = {	/* table of offsets (long) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) 		offsetof(struct xfs_btree_block, bb_magic),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) 		offsetof(struct xfs_btree_block, bb_level),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) 		offsetof(struct xfs_btree_block, bb_numrecs),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) 		offsetof(struct xfs_btree_block, bb_u.l.bb_leftsib),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) 		offsetof(struct xfs_btree_block, bb_u.l.bb_rightsib),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) 		offsetof(struct xfs_btree_block, bb_u.l.bb_blkno),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) 		offsetof(struct xfs_btree_block, bb_u.l.bb_lsn),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) 		offsetof(struct xfs_btree_block, bb_u.l.bb_uuid),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) 		offsetof(struct xfs_btree_block, bb_u.l.bb_owner),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) 		offsetof(struct xfs_btree_block, bb_u.l.bb_crc),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) 		offsetof(struct xfs_btree_block, bb_u.l.bb_pad),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) 		XFS_BTREE_LBLOCK_CRC_LEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) 	if (bp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) 		int nbits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) 		if (cur->bc_flags & XFS_BTREE_CRC_BLOCKS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) 			 * We don't log the CRC when updating a btree
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) 			 * block but instead recreate it during log
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) 			 * recovery.  As the log buffers have checksums
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) 			 * of their own this is safe and avoids logging a crc
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) 			 * update in a lot of places.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) 			if (fields == XFS_BB_ALL_BITS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) 				fields = XFS_BB_ALL_BITS_CRC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) 			nbits = XFS_BB_NUM_BITS_CRC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) 			nbits = XFS_BB_NUM_BITS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) 		xfs_btree_offsets(fields,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) 				  (cur->bc_flags & XFS_BTREE_LONG_PTRS) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) 					loffsets : soffsets,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) 				  nbits, &first, &last);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) 		xfs_trans_buf_set_type(cur->bc_tp, bp, XFS_BLFT_BTREE_BUF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) 		xfs_trans_log_buf(cur->bc_tp, bp, first, last);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) 		xfs_trans_log_inode(cur->bc_tp, cur->bc_ino.ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) 			xfs_ilog_fbroot(cur->bc_ino.whichfork));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527)  * Increment cursor by one record at the level.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528)  * For nonzero levels the leaf-ward information is untouched.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) int						/* error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) xfs_btree_increment(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) 	int			level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) 	int			*stat)		/* success/failure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) 	struct xfs_btree_block	*block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) 	union xfs_btree_ptr	ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) 	struct xfs_buf		*bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) 	int			error;		/* error return value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) 	int			lev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) 	ASSERT(level < cur->bc_nlevels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) 	/* Read-ahead to the right at this level. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) 	xfs_btree_readahead(cur, level, XFS_BTCUR_RIGHTRA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) 	/* Get a pointer to the btree block. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) 	block = xfs_btree_get_block(cur, level, &bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) 	error = xfs_btree_check_block(cur, block, level, bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) 		goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) 	/* We're done if we remain in the block after the increment. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) 	if (++cur->bc_ptrs[level] <= xfs_btree_get_numrecs(block))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) 		goto out1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) 	/* Fail if we just went off the right edge of the tree. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) 	xfs_btree_get_sibling(cur, block, &ptr, XFS_BB_RIGHTSIB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) 	if (xfs_btree_ptr_is_null(cur, &ptr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) 		goto out0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) 	XFS_BTREE_STATS_INC(cur, increment);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) 	 * March up the tree incrementing pointers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) 	 * Stop when we don't go off the right edge of a block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) 	for (lev = level + 1; lev < cur->bc_nlevels; lev++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) 		block = xfs_btree_get_block(cur, lev, &bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) 		error = xfs_btree_check_block(cur, block, lev, bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) 			goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) 		if (++cur->bc_ptrs[lev] <= xfs_btree_get_numrecs(block))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) 		/* Read-ahead the right block for the next loop. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) 		xfs_btree_readahead(cur, lev, XFS_BTCUR_RIGHTRA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) 	 * If we went off the root then we are either seriously
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) 	 * confused or have the tree root in an inode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) 	if (lev == cur->bc_nlevels) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) 		if (cur->bc_flags & XFS_BTREE_ROOT_IN_INODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) 			goto out0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) 		ASSERT(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) 		error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) 		goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) 	ASSERT(lev < cur->bc_nlevels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) 	 * Now walk back down the tree, fixing up the cursor's buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) 	 * pointers and key numbers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) 	for (block = xfs_btree_get_block(cur, lev, &bp); lev > level; ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) 		union xfs_btree_ptr	*ptrp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) 		ptrp = xfs_btree_ptr_addr(cur, cur->bc_ptrs[lev], block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) 		--lev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) 		error = xfs_btree_read_buf_block(cur, ptrp, 0, &block, &bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) 			goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) 		xfs_btree_setbuf(cur, lev, bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) 		cur->bc_ptrs[lev] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) out1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) 	*stat = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) out0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) 	*stat = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) error0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629)  * Decrement cursor by one record at the level.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630)  * For nonzero levels the leaf-ward information is untouched.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) int						/* error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) xfs_btree_decrement(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) 	int			level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) 	int			*stat)		/* success/failure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) 	struct xfs_btree_block	*block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) 	xfs_buf_t		*bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) 	int			error;		/* error return value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) 	int			lev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) 	union xfs_btree_ptr	ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) 	ASSERT(level < cur->bc_nlevels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) 	/* Read-ahead to the left at this level. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) 	xfs_btree_readahead(cur, level, XFS_BTCUR_LEFTRA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) 	/* We're done if we remain in the block after the decrement. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) 	if (--cur->bc_ptrs[level] > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) 		goto out1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) 	/* Get a pointer to the btree block. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) 	block = xfs_btree_get_block(cur, level, &bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) 	error = xfs_btree_check_block(cur, block, level, bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) 		goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) 	/* Fail if we just went off the left edge of the tree. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) 	xfs_btree_get_sibling(cur, block, &ptr, XFS_BB_LEFTSIB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) 	if (xfs_btree_ptr_is_null(cur, &ptr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) 		goto out0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) 	XFS_BTREE_STATS_INC(cur, decrement);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) 	 * March up the tree decrementing pointers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) 	 * Stop when we don't go off the left edge of a block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) 	for (lev = level + 1; lev < cur->bc_nlevels; lev++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) 		if (--cur->bc_ptrs[lev] > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) 		/* Read-ahead the left block for the next loop. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) 		xfs_btree_readahead(cur, lev, XFS_BTCUR_LEFTRA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) 	 * If we went off the root then we are seriously confused.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) 	 * or the root of the tree is in an inode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) 	if (lev == cur->bc_nlevels) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) 		if (cur->bc_flags & XFS_BTREE_ROOT_IN_INODE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) 			goto out0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) 		ASSERT(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) 		error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) 		goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) 	ASSERT(lev < cur->bc_nlevels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) 	 * Now walk back down the tree, fixing up the cursor's buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) 	 * pointers and key numbers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) 	for (block = xfs_btree_get_block(cur, lev, &bp); lev > level; ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) 		union xfs_btree_ptr	*ptrp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700) 		ptrp = xfs_btree_ptr_addr(cur, cur->bc_ptrs[lev], block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701) 		--lev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) 		error = xfs_btree_read_buf_block(cur, ptrp, 0, &block, &bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) 			goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) 		xfs_btree_setbuf(cur, lev, bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) 		cur->bc_ptrs[lev] = xfs_btree_get_numrecs(block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) out1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) 	*stat = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) out0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) 	*stat = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) error0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) xfs_btree_lookup_get_block(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) 	struct xfs_btree_cur	*cur,	/* btree cursor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) 	int			level,	/* level in the btree */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) 	union xfs_btree_ptr	*pp,	/* ptr to btree block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) 	struct xfs_btree_block	**blkp) /* return btree block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) 	struct xfs_buf		*bp;	/* buffer pointer for btree block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) 	xfs_daddr_t		daddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) 	int			error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) 	/* special case the root block if in an inode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) 	if ((cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) 	    (level == cur->bc_nlevels - 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) 		*blkp = xfs_btree_get_iroot(cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) 	 * If the old buffer at this level for the disk address we are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) 	 * looking for re-use it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) 	 * Otherwise throw it away and get a new one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) 	bp = cur->bc_bufs[level];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) 	error = xfs_btree_ptr_to_daddr(cur, pp, &daddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) 	if (bp && XFS_BUF_ADDR(bp) == daddr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) 		*blkp = XFS_BUF_TO_BLOCK(bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) 	error = xfs_btree_read_buf_block(cur, pp, 0, blkp, &bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) 	/* Check the inode owner since the verifiers don't. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) 	if (xfs_sb_version_hascrc(&cur->bc_mp->m_sb) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) 	    !(cur->bc_ino.flags & XFS_BTCUR_BMBT_INVALID_OWNER) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) 	    (cur->bc_flags & XFS_BTREE_LONG_PTRS) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) 	    be64_to_cpu((*blkp)->bb_u.l.bb_owner) !=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) 			cur->bc_ino.ip->i_ino)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) 		goto out_bad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) 	/* Did we get the level we were looking for? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) 	if (be16_to_cpu((*blkp)->bb_level) != level)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) 		goto out_bad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) 	/* Check that internal nodes have at least one record. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770) 	if (level != 0 && be16_to_cpu((*blkp)->bb_numrecs) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) 		goto out_bad;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) 	xfs_btree_setbuf(cur, level, bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) out_bad:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) 	*blkp = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) 	xfs_buf_mark_corrupt(bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779) 	xfs_trans_brelse(cur->bc_tp, bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780) 	return -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784)  * Get current search key.  For level 0 we don't actually have a key
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785)  * structure so we make one up from the record.  For all other levels
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786)  * we just return the right key.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) STATIC union xfs_btree_key *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) xfs_lookup_get_search_key(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) 	int			level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) 	int			keyno,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793) 	struct xfs_btree_block	*block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794) 	union xfs_btree_key	*kp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796) 	if (level == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797) 		cur->bc_ops->init_key_from_rec(kp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798) 				xfs_btree_rec_addr(cur, keyno, block));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799) 		return kp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) 	return xfs_btree_key_addr(cur, keyno, block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806)  * Lookup the record.  The cursor is made to point to it, based on dir.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807)  * stat is set to 0 if can't find any such record, 1 for success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) int					/* error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) xfs_btree_lookup(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) 	struct xfs_btree_cur	*cur,	/* btree cursor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) 	xfs_lookup_t		dir,	/* <=, ==, or >= */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) 	int			*stat)	/* success/failure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) 	struct xfs_btree_block	*block;	/* current btree block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) 	int64_t			diff;	/* difference for the current key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) 	int			error;	/* error return value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) 	int			keyno;	/* current key number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) 	int			level;	/* level in the btree */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) 	union xfs_btree_ptr	*pp;	/* ptr to btree block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) 	union xfs_btree_ptr	ptr;	/* ptr to btree block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) 	XFS_BTREE_STATS_INC(cur, lookup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) 	/* No such thing as a zero-level tree. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) 	if (XFS_IS_CORRUPT(cur->bc_mp, cur->bc_nlevels == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) 		return -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) 	block = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) 	keyno = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) 	/* initialise start pointer from cursor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) 	cur->bc_ops->init_ptr_from_cur(cur, &ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) 	pp = &ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) 	 * Iterate over each level in the btree, starting at the root.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) 	 * For each level above the leaves, find the key we need, based
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) 	 * on the lookup record, then follow the corresponding block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) 	 * pointer down to the next level.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) 	for (level = cur->bc_nlevels - 1, diff = 1; level >= 0; level--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) 		/* Get the block we need to do the lookup on. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) 		error = xfs_btree_lookup_get_block(cur, level, pp, &block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) 			goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) 		if (diff == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) 			 * If we already had a key match at a higher level, we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) 			 * know we need to use the first entry in this block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) 			keyno = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) 			/* Otherwise search this block. Do a binary search. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) 			int	high;	/* high entry number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) 			int	low;	/* low entry number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) 			/* Set low and high entry numbers, 1-based. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) 			low = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) 			high = xfs_btree_get_numrecs(block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) 			if (!high) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) 				/* Block is empty, must be an empty leaf. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) 				if (level != 0 || cur->bc_nlevels != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) 					XFS_CORRUPTION_ERROR(__func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) 							XFS_ERRLEVEL_LOW,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) 							cur->bc_mp, block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) 							sizeof(*block));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) 					return -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) 				cur->bc_ptrs[0] = dir != XFS_LOOKUP_LE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) 				*stat = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) 				return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) 			/* Binary search the block. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) 			while (low <= high) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) 				union xfs_btree_key	key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) 				union xfs_btree_key	*kp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) 				XFS_BTREE_STATS_INC(cur, compare);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) 				/* keyno is average of low and high. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) 				keyno = (low + high) >> 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) 				/* Get current search key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) 				kp = xfs_lookup_get_search_key(cur, level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) 						keyno, block, &key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) 				/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) 				 * Compute difference to get next direction:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) 				 *  - less than, move right
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) 				 *  - greater than, move left
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) 				 *  - equal, we're done
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) 				 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) 				diff = cur->bc_ops->key_diff(cur, kp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) 				if (diff < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) 					low = keyno + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) 				else if (diff > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) 					high = keyno - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) 				else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) 		 * If there are more levels, set up for the next level
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) 		 * by getting the block number and filling in the cursor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) 		if (level > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) 			 * If we moved left, need the previous key number,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) 			 * unless there isn't one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) 			if (diff > 0 && --keyno < 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) 				keyno = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) 			pp = xfs_btree_ptr_addr(cur, keyno, block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) 			error = xfs_btree_debug_check_ptr(cur, pp, 0, level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) 			if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) 				goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) 			cur->bc_ptrs[level] = keyno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) 	/* Done with the search. See if we need to adjust the results. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) 	if (dir != XFS_LOOKUP_LE && diff < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) 		keyno++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) 		 * If ge search and we went off the end of the block, but it's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) 		 * not the last block, we're in the wrong block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) 		xfs_btree_get_sibling(cur, block, &ptr, XFS_BB_RIGHTSIB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) 		if (dir == XFS_LOOKUP_GE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938) 		    keyno > xfs_btree_get_numrecs(block) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939) 		    !xfs_btree_ptr_is_null(cur, &ptr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940) 			int	i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942) 			cur->bc_ptrs[0] = keyno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943) 			error = xfs_btree_increment(cur, 0, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944) 			if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945) 				goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946) 			if (XFS_IS_CORRUPT(cur->bc_mp, i != 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947) 				return -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948) 			*stat = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951) 	} else if (dir == XFS_LOOKUP_LE && diff > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952) 		keyno--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953) 	cur->bc_ptrs[0] = keyno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955) 	/* Return if we succeeded or not. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) 	if (keyno == 0 || keyno > xfs_btree_get_numrecs(block))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) 		*stat = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) 	else if (dir != XFS_LOOKUP_EQ || diff == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) 		*stat = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) 		*stat = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) error0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) /* Find the high key storage area from a regular key. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) union xfs_btree_key *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) xfs_btree_high_key_from_key(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) 	union xfs_btree_key	*key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) 	ASSERT(cur->bc_flags & XFS_BTREE_OVERLAPPING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) 	return (union xfs_btree_key *)((char *)key +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) 			(cur->bc_ops->key_len / 2));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) /* Determine the low (and high if overlapped) keys of a leaf block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) STATIC void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) xfs_btree_get_leaf_keys(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) 	struct xfs_btree_block	*block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) 	union xfs_btree_key	*key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) 	union xfs_btree_key	max_hkey;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) 	union xfs_btree_key	hkey;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) 	union xfs_btree_rec	*rec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) 	union xfs_btree_key	*high;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) 	int			n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) 	rec = xfs_btree_rec_addr(cur, 1, block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) 	cur->bc_ops->init_key_from_rec(key, rec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) 	if (cur->bc_flags & XFS_BTREE_OVERLAPPING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) 		cur->bc_ops->init_high_key_from_rec(&max_hkey, rec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) 		for (n = 2; n <= xfs_btree_get_numrecs(block); n++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) 			rec = xfs_btree_rec_addr(cur, n, block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) 			cur->bc_ops->init_high_key_from_rec(&hkey, rec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) 			if (cur->bc_ops->diff_two_keys(cur, &hkey, &max_hkey)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002) 					> 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003) 				max_hkey = hkey;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) 		high = xfs_btree_high_key_from_key(cur, key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) 		memcpy(high, &max_hkey, cur->bc_ops->key_len / 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) /* Determine the low (and high if overlapped) keys of a node block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) STATIC void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) xfs_btree_get_node_keys(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) 	struct xfs_btree_block	*block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) 	union xfs_btree_key	*key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) 	union xfs_btree_key	*hkey;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) 	union xfs_btree_key	*max_hkey;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) 	union xfs_btree_key	*high;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) 	int			n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) 	if (cur->bc_flags & XFS_BTREE_OVERLAPPING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) 		memcpy(key, xfs_btree_key_addr(cur, 1, block),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) 				cur->bc_ops->key_len / 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) 		max_hkey = xfs_btree_high_key_addr(cur, 1, block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) 		for (n = 2; n <= xfs_btree_get_numrecs(block); n++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) 			hkey = xfs_btree_high_key_addr(cur, n, block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) 			if (cur->bc_ops->diff_two_keys(cur, hkey, max_hkey) > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) 				max_hkey = hkey;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) 		high = xfs_btree_high_key_from_key(cur, key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) 		memcpy(high, max_hkey, cur->bc_ops->key_len / 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) 		memcpy(key, xfs_btree_key_addr(cur, 1, block),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) 				cur->bc_ops->key_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) /* Derive the keys for any btree block. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) xfs_btree_get_keys(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) 	struct xfs_btree_block	*block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) 	union xfs_btree_key	*key)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) 	if (be16_to_cpu(block->bb_level) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) 		xfs_btree_get_leaf_keys(cur, block, key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) 		xfs_btree_get_node_keys(cur, block, key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056)  * Decide if we need to update the parent keys of a btree block.  For
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057)  * a standard btree this is only necessary if we're updating the first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058)  * record/key.  For an overlapping btree, we must always update the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059)  * keys because the highest key can be in any of the records or keys
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060)  * in the block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062) static inline bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063) xfs_btree_needs_key_update(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) 	int			ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) 	return (cur->bc_flags & XFS_BTREE_OVERLAPPING) || ptr == 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071)  * Update the low and high parent keys of the given level, progressing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072)  * towards the root.  If force_all is false, stop if the keys for a given
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073)  * level do not need updating.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) __xfs_btree_updkeys(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) 	int			level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) 	struct xfs_btree_block	*block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) 	struct xfs_buf		*bp0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) 	bool			force_all)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) 	union xfs_btree_key	key;	/* keys from current level */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) 	union xfs_btree_key	*lkey;	/* keys from the next level up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) 	union xfs_btree_key	*hkey;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086) 	union xfs_btree_key	*nlkey;	/* keys from the next level up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087) 	union xfs_btree_key	*nhkey;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088) 	struct xfs_buf		*bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089) 	int			ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091) 	ASSERT(cur->bc_flags & XFS_BTREE_OVERLAPPING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) 	/* Exit if there aren't any parent levels to update. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) 	if (level + 1 >= cur->bc_nlevels)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) 	trace_xfs_btree_updkeys(cur, level, bp0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) 	lkey = &key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) 	hkey = xfs_btree_high_key_from_key(cur, lkey);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) 	xfs_btree_get_keys(cur, block, lkey);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) 	for (level++; level < cur->bc_nlevels; level++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) 		int		error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) 		block = xfs_btree_get_block(cur, level, &bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107) 		trace_xfs_btree_updkeys(cur, level, bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109) 		error = xfs_btree_check_block(cur, block, level, bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111) 			return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113) 		ptr = cur->bc_ptrs[level];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) 		nlkey = xfs_btree_key_addr(cur, ptr, block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) 		nhkey = xfs_btree_high_key_addr(cur, ptr, block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) 		if (!force_all &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) 		    !(cur->bc_ops->diff_two_keys(cur, nlkey, lkey) != 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) 		      cur->bc_ops->diff_two_keys(cur, nhkey, hkey) != 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) 		xfs_btree_copy_keys(cur, nlkey, lkey, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) 		xfs_btree_log_keys(cur, bp, ptr, ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) 		if (level + 1 >= cur->bc_nlevels)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) 		xfs_btree_get_node_keys(cur, block, lkey);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130) /* Update all the keys from some level in cursor back to the root. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132) xfs_btree_updkeys_force(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134) 	int			level)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) 	struct xfs_buf		*bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) 	struct xfs_btree_block	*block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) 	block = xfs_btree_get_block(cur, level, &bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) 	return __xfs_btree_updkeys(cur, level, block, bp, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144)  * Update the parent keys of the given level, progressing towards the root.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) xfs_btree_update_keys(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) 	int			level)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) 	struct xfs_btree_block	*block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) 	struct xfs_buf		*bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) 	union xfs_btree_key	*kp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) 	union xfs_btree_key	key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) 	int			ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157) 	ASSERT(level >= 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159) 	block = xfs_btree_get_block(cur, level, &bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160) 	if (cur->bc_flags & XFS_BTREE_OVERLAPPING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161) 		return __xfs_btree_updkeys(cur, level, block, bp, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) 	 * Go up the tree from this level toward the root.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) 	 * At each level, update the key value to the value input.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) 	 * Stop when we reach a level where the cursor isn't pointing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) 	 * at the first entry in the block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) 	xfs_btree_get_keys(cur, block, &key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) 	for (level++, ptr = 1; ptr == 1 && level < cur->bc_nlevels; level++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) 		int		error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) 		block = xfs_btree_get_block(cur, level, &bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) 		error = xfs_btree_check_block(cur, block, level, bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) 			return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) 		ptr = cur->bc_ptrs[level];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) 		kp = xfs_btree_key_addr(cur, ptr, block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) 		xfs_btree_copy_keys(cur, kp, &key, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) 		xfs_btree_log_keys(cur, bp, ptr, ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190)  * Update the record referred to by cur to the value in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191)  * given record. This either works (return 0) or gets an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192)  * EFSCORRUPTED error.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) xfs_btree_update(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) 	union xfs_btree_rec	*rec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) 	struct xfs_btree_block	*block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) 	struct xfs_buf		*bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) 	int			error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) 	int			ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) 	union xfs_btree_rec	*rp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) 	/* Pick up the current block. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) 	block = xfs_btree_get_block(cur, 0, &bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) 	error = xfs_btree_check_block(cur, block, 0, bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) 		goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) 	/* Get the address of the rec to be updated. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) 	ptr = cur->bc_ptrs[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) 	rp = xfs_btree_rec_addr(cur, ptr, block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) 	/* Fill in the new contents and log them. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) 	xfs_btree_copy_recs(cur, rp, rec, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) 	xfs_btree_log_recs(cur, bp, ptr, ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) 	 * If we are tracking the last record in the tree and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) 	 * we are at the far right edge of the tree, update it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) 	if (xfs_btree_is_lastrec(cur, block, 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) 		cur->bc_ops->update_lastrec(cur, block, rec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) 					    ptr, LASTREC_UPDATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) 	/* Pass new key value up to our parent. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) 	if (xfs_btree_needs_key_update(cur, ptr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) 		error = xfs_btree_update_keys(cur, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) 			goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) error0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244)  * Move 1 record left from cur/level if possible.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245)  * Update cur to reflect the new path.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) STATIC int					/* error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) xfs_btree_lshift(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) 	int			level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) 	int			*stat)		/* success/failure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) 	struct xfs_buf		*lbp;		/* left buffer pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) 	struct xfs_btree_block	*left;		/* left btree block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) 	int			lrecs;		/* left record count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) 	struct xfs_buf		*rbp;		/* right buffer pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) 	struct xfs_btree_block	*right;		/* right btree block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) 	struct xfs_btree_cur	*tcur;		/* temporary btree cursor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) 	int			rrecs;		/* right record count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) 	union xfs_btree_ptr	lptr;		/* left btree pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) 	union xfs_btree_key	*rkp = NULL;	/* right btree key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) 	union xfs_btree_ptr	*rpp = NULL;	/* right address pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) 	union xfs_btree_rec	*rrp = NULL;	/* right record pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) 	int			error;		/* error return value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) 	int			i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) 	if ((cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) 	    level == cur->bc_nlevels - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) 		goto out0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271) 	/* Set up variables for this block as "right". */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) 	right = xfs_btree_get_block(cur, level, &rbp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) 	error = xfs_btree_check_block(cur, right, level, rbp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) 		goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) 	/* If we've got no left sibling then we can't shift an entry left. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) 	xfs_btree_get_sibling(cur, right, &lptr, XFS_BB_LEFTSIB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) 	if (xfs_btree_ptr_is_null(cur, &lptr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) 		goto out0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) 	 * If the cursor entry is the one that would be moved, don't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) 	 * do it... it's too complicated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) 	if (cur->bc_ptrs[level] <= 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) 		goto out0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) 	/* Set up the left neighbor as "left". */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) 	error = xfs_btree_read_buf_block(cur, &lptr, 0, &left, &lbp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) 		goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) 	/* If it's full, it can't take another entry. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) 	lrecs = xfs_btree_get_numrecs(left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) 	if (lrecs == cur->bc_ops->get_maxrecs(cur, level))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) 		goto out0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) 	rrecs = xfs_btree_get_numrecs(right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) 	 * We add one entry to the left side and remove one for the right side.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) 	 * Account for it here, the changes will be updated on disk and logged
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) 	 * later.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) 	lrecs++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) 	rrecs--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) 	XFS_BTREE_STATS_INC(cur, lshift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) 	XFS_BTREE_STATS_ADD(cur, moves, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) 	 * If non-leaf, copy a key and a ptr to the left block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) 	 * Log the changes to the left block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) 	if (level > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) 		/* It's a non-leaf.  Move keys and pointers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) 		union xfs_btree_key	*lkp;	/* left btree key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) 		union xfs_btree_ptr	*lpp;	/* left address pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) 		lkp = xfs_btree_key_addr(cur, lrecs, left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) 		rkp = xfs_btree_key_addr(cur, 1, right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) 		lpp = xfs_btree_ptr_addr(cur, lrecs, left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) 		rpp = xfs_btree_ptr_addr(cur, 1, right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) 		error = xfs_btree_debug_check_ptr(cur, rpp, 0, level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) 			goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) 		xfs_btree_copy_keys(cur, lkp, rkp, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) 		xfs_btree_copy_ptrs(cur, lpp, rpp, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) 		xfs_btree_log_keys(cur, lbp, lrecs, lrecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) 		xfs_btree_log_ptrs(cur, lbp, lrecs, lrecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) 		ASSERT(cur->bc_ops->keys_inorder(cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) 			xfs_btree_key_addr(cur, lrecs - 1, left), lkp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) 		/* It's a leaf.  Move records.  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) 		union xfs_btree_rec	*lrp;	/* left record pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) 		lrp = xfs_btree_rec_addr(cur, lrecs, left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) 		rrp = xfs_btree_rec_addr(cur, 1, right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) 		xfs_btree_copy_recs(cur, lrp, rrp, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) 		xfs_btree_log_recs(cur, lbp, lrecs, lrecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) 		ASSERT(cur->bc_ops->recs_inorder(cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) 			xfs_btree_rec_addr(cur, lrecs - 1, left), lrp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) 	xfs_btree_set_numrecs(left, lrecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) 	xfs_btree_log_block(cur, lbp, XFS_BB_NUMRECS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) 	xfs_btree_set_numrecs(right, rrecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) 	xfs_btree_log_block(cur, rbp, XFS_BB_NUMRECS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) 	 * Slide the contents of right down one entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) 	XFS_BTREE_STATS_ADD(cur, moves, rrecs - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) 	if (level > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) 		/* It's a nonleaf. operate on keys and ptrs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) 		for (i = 0; i < rrecs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) 			error = xfs_btree_debug_check_ptr(cur, rpp, i + 1, level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) 			if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) 				goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) 		xfs_btree_shift_keys(cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) 				xfs_btree_key_addr(cur, 2, right),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) 				-1, rrecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) 		xfs_btree_shift_ptrs(cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) 				xfs_btree_ptr_addr(cur, 2, right),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) 				-1, rrecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) 		xfs_btree_log_keys(cur, rbp, 1, rrecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) 		xfs_btree_log_ptrs(cur, rbp, 1, rrecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) 		/* It's a leaf. operate on records */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) 		xfs_btree_shift_recs(cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) 			xfs_btree_rec_addr(cur, 2, right),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) 			-1, rrecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) 		xfs_btree_log_recs(cur, rbp, 1, rrecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) 	 * Using a temporary cursor, update the parent key values of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) 	 * block on the left.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) 	if (cur->bc_flags & XFS_BTREE_OVERLAPPING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) 		error = xfs_btree_dup_cursor(cur, &tcur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) 			goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) 		i = xfs_btree_firstrec(tcur, level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) 		if (XFS_IS_CORRUPT(tcur->bc_mp, i != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) 			error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) 			goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) 		error = xfs_btree_decrement(tcur, level, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) 			goto error1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) 		/* Update the parent high keys of the left block, if needed. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) 		error = xfs_btree_update_keys(tcur, level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) 			goto error1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) 		xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) 	/* Update the parent keys of the right block. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) 	error = xfs_btree_update_keys(cur, level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) 		goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) 	/* Slide the cursor value left one. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) 	cur->bc_ptrs[level]--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) 	*stat = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) out0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) 	*stat = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) error0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) error1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) 	xfs_btree_del_cursor(tcur, XFS_BTREE_ERROR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441)  * Move 1 record right from cur/level if possible.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442)  * Update cur to reflect the new path.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) STATIC int					/* error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445) xfs_btree_rshift(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447) 	int			level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448) 	int			*stat)		/* success/failure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450) 	struct xfs_buf		*lbp;		/* left buffer pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451) 	struct xfs_btree_block	*left;		/* left btree block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452) 	struct xfs_buf		*rbp;		/* right buffer pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453) 	struct xfs_btree_block	*right;		/* right btree block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454) 	struct xfs_btree_cur	*tcur;		/* temporary btree cursor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) 	union xfs_btree_ptr	rptr;		/* right block pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) 	union xfs_btree_key	*rkp;		/* right btree key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) 	int			rrecs;		/* right record count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) 	int			lrecs;		/* left record count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) 	int			error;		/* error return value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) 	int			i;		/* loop counter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) 	if ((cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) 	    (level == cur->bc_nlevels - 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) 		goto out0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) 	/* Set up variables for this block as "left". */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) 	left = xfs_btree_get_block(cur, level, &lbp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) 	error = xfs_btree_check_block(cur, left, level, lbp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) 		goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) 	/* If we've got no right sibling then we can't shift an entry right. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) 	xfs_btree_get_sibling(cur, left, &rptr, XFS_BB_RIGHTSIB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) 	if (xfs_btree_ptr_is_null(cur, &rptr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) 		goto out0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) 	 * If the cursor entry is the one that would be moved, don't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) 	 * do it... it's too complicated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) 	lrecs = xfs_btree_get_numrecs(left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) 	if (cur->bc_ptrs[level] >= lrecs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) 		goto out0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) 	/* Set up the right neighbor as "right". */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) 	error = xfs_btree_read_buf_block(cur, &rptr, 0, &right, &rbp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) 		goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) 	/* If it's full, it can't take another entry. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) 	rrecs = xfs_btree_get_numrecs(right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) 	if (rrecs == cur->bc_ops->get_maxrecs(cur, level))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) 		goto out0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) 	XFS_BTREE_STATS_INC(cur, rshift);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) 	XFS_BTREE_STATS_ADD(cur, moves, rrecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) 	 * Make a hole at the start of the right neighbor block, then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) 	 * copy the last left block entry to the hole.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) 	if (level > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) 		/* It's a nonleaf. make a hole in the keys and ptrs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) 		union xfs_btree_key	*lkp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) 		union xfs_btree_ptr	*lpp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) 		union xfs_btree_ptr	*rpp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) 		lkp = xfs_btree_key_addr(cur, lrecs, left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) 		lpp = xfs_btree_ptr_addr(cur, lrecs, left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) 		rkp = xfs_btree_key_addr(cur, 1, right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514) 		rpp = xfs_btree_ptr_addr(cur, 1, right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516) 		for (i = rrecs - 1; i >= 0; i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517) 			error = xfs_btree_debug_check_ptr(cur, rpp, i, level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518) 			if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519) 				goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) 		xfs_btree_shift_keys(cur, rkp, 1, rrecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) 		xfs_btree_shift_ptrs(cur, rpp, 1, rrecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) 		error = xfs_btree_debug_check_ptr(cur, lpp, 0, level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) 			goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) 		/* Now put the new data in, and log it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) 		xfs_btree_copy_keys(cur, rkp, lkp, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) 		xfs_btree_copy_ptrs(cur, rpp, lpp, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) 		xfs_btree_log_keys(cur, rbp, 1, rrecs + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) 		xfs_btree_log_ptrs(cur, rbp, 1, rrecs + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536) 		ASSERT(cur->bc_ops->keys_inorder(cur, rkp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537) 			xfs_btree_key_addr(cur, 2, right)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539) 		/* It's a leaf. make a hole in the records */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540) 		union xfs_btree_rec	*lrp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) 		union xfs_btree_rec	*rrp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) 		lrp = xfs_btree_rec_addr(cur, lrecs, left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) 		rrp = xfs_btree_rec_addr(cur, 1, right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) 		xfs_btree_shift_recs(cur, rrp, 1, rrecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) 		/* Now put the new data in, and log it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) 		xfs_btree_copy_recs(cur, rrp, lrp, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) 		xfs_btree_log_recs(cur, rbp, 1, rrecs + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) 	 * Decrement and log left's numrecs, bump and log right's numrecs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556) 	xfs_btree_set_numrecs(left, --lrecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557) 	xfs_btree_log_block(cur, lbp, XFS_BB_NUMRECS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559) 	xfs_btree_set_numrecs(right, ++rrecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560) 	xfs_btree_log_block(cur, rbp, XFS_BB_NUMRECS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) 	 * Using a temporary cursor, update the parent key values of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) 	 * block on the right.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) 	error = xfs_btree_dup_cursor(cur, &tcur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) 		goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) 	i = xfs_btree_lastrec(tcur, level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) 	if (XFS_IS_CORRUPT(tcur->bc_mp, i != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) 		error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) 		goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) 	error = xfs_btree_increment(tcur, level, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) 		goto error1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) 	/* Update the parent high keys of the left block, if needed. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) 	if (cur->bc_flags & XFS_BTREE_OVERLAPPING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581) 		error = xfs_btree_update_keys(cur, level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) 			goto error1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) 	/* Update the parent keys of the right block. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) 	error = xfs_btree_update_keys(tcur, level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) 		goto error1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) 	xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) 	*stat = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) out0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) 	*stat = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) error0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) error1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) 	xfs_btree_del_cursor(tcur, XFS_BTREE_ERROR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609)  * Split cur/level block in half.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610)  * Return new block number and the key to its first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611)  * record (to be inserted into parent).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) STATIC int					/* error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) __xfs_btree_split(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) 	int			level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) 	union xfs_btree_ptr	*ptrp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) 	union xfs_btree_key	*key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) 	struct xfs_btree_cur	**curp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) 	int			*stat)		/* success/failure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) 	union xfs_btree_ptr	lptr;		/* left sibling block ptr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) 	struct xfs_buf		*lbp;		/* left buffer pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) 	struct xfs_btree_block	*left;		/* left btree block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) 	union xfs_btree_ptr	rptr;		/* right sibling block ptr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) 	struct xfs_buf		*rbp;		/* right buffer pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) 	struct xfs_btree_block	*right;		/* right btree block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) 	union xfs_btree_ptr	rrptr;		/* right-right sibling ptr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629) 	struct xfs_buf		*rrbp;		/* right-right buffer pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630) 	struct xfs_btree_block	*rrblock;	/* right-right btree block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) 	int			lrecs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) 	int			rrecs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) 	int			src_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) 	int			error;		/* error return value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) 	int			i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) 	XFS_BTREE_STATS_INC(cur, split);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) 	/* Set up left block (current one). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) 	left = xfs_btree_get_block(cur, level, &lbp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) 	error = xfs_btree_check_block(cur, left, level, lbp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) 		goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) 	xfs_btree_buf_to_ptr(cur, lbp, &lptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) 	/* Allocate the new block. If we can't do it, we're toast. Give up. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) 	error = cur->bc_ops->alloc_block(cur, &lptr, &rptr, stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) 		goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) 	if (*stat == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) 		goto out0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) 	XFS_BTREE_STATS_INC(cur, alloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) 	/* Set up the new block as "right". */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) 	error = xfs_btree_get_buf_block(cur, &rptr, &right, &rbp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) 		goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) 	/* Fill in the btree header for the new right block. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) 	xfs_btree_init_block_cur(cur, rbp, xfs_btree_get_level(left), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) 	 * Split the entries between the old and the new block evenly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) 	 * Make sure that if there's an odd number of entries now, that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) 	 * each new block will have the same number of entries.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) 	lrecs = xfs_btree_get_numrecs(left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) 	rrecs = lrecs / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) 	if ((lrecs & 1) && cur->bc_ptrs[level] <= rrecs + 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) 		rrecs++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) 	src_index = (lrecs - rrecs + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) 	XFS_BTREE_STATS_ADD(cur, moves, rrecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) 	/* Adjust numrecs for the later get_*_keys() calls. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) 	lrecs -= rrecs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) 	xfs_btree_set_numrecs(left, lrecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) 	xfs_btree_set_numrecs(right, xfs_btree_get_numrecs(right) + rrecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) 	 * Copy btree block entries from the left block over to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) 	 * new block, the right. Update the right block and log the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) 	 * changes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) 	if (level > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) 		/* It's a non-leaf.  Move keys and pointers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) 		union xfs_btree_key	*lkp;	/* left btree key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) 		union xfs_btree_ptr	*lpp;	/* left address pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) 		union xfs_btree_key	*rkp;	/* right btree key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) 		union xfs_btree_ptr	*rpp;	/* right address pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) 		lkp = xfs_btree_key_addr(cur, src_index, left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) 		lpp = xfs_btree_ptr_addr(cur, src_index, left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) 		rkp = xfs_btree_key_addr(cur, 1, right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699) 		rpp = xfs_btree_ptr_addr(cur, 1, right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701) 		for (i = src_index; i < rrecs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702) 			error = xfs_btree_debug_check_ptr(cur, lpp, i, level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703) 			if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704) 				goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707) 		/* Copy the keys & pointers to the new block. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) 		xfs_btree_copy_keys(cur, rkp, lkp, rrecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) 		xfs_btree_copy_ptrs(cur, rpp, lpp, rrecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) 		xfs_btree_log_keys(cur, rbp, 1, rrecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) 		xfs_btree_log_ptrs(cur, rbp, 1, rrecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) 		/* Stash the keys of the new block for later insertion. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) 		xfs_btree_get_node_keys(cur, right, key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) 		/* It's a leaf.  Move records.  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) 		union xfs_btree_rec	*lrp;	/* left record pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) 		union xfs_btree_rec	*rrp;	/* right record pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) 		lrp = xfs_btree_rec_addr(cur, src_index, left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) 		rrp = xfs_btree_rec_addr(cur, 1, right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) 		/* Copy records to the new block. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) 		xfs_btree_copy_recs(cur, rrp, lrp, rrecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) 		xfs_btree_log_recs(cur, rbp, 1, rrecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) 		/* Stash the keys of the new block for later insertion. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) 		xfs_btree_get_leaf_keys(cur, right, key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) 	 * Find the left block number by looking in the buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) 	 * Adjust sibling pointers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) 	xfs_btree_get_sibling(cur, left, &rrptr, XFS_BB_RIGHTSIB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) 	xfs_btree_set_sibling(cur, right, &rrptr, XFS_BB_RIGHTSIB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738) 	xfs_btree_set_sibling(cur, right, &lptr, XFS_BB_LEFTSIB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739) 	xfs_btree_set_sibling(cur, left, &rptr, XFS_BB_RIGHTSIB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741) 	xfs_btree_log_block(cur, rbp, XFS_BB_ALL_BITS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742) 	xfs_btree_log_block(cur, lbp, XFS_BB_NUMRECS | XFS_BB_RIGHTSIB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745) 	 * If there's a block to the new block's right, make that block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746) 	 * point back to right instead of to left.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) 	if (!xfs_btree_ptr_is_null(cur, &rrptr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) 		error = xfs_btree_read_buf_block(cur, &rrptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) 							0, &rrblock, &rrbp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) 			goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) 		xfs_btree_set_sibling(cur, rrblock, &rptr, XFS_BB_LEFTSIB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) 		xfs_btree_log_block(cur, rrbp, XFS_BB_LEFTSIB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) 	/* Update the parent high keys of the left block, if needed. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) 	if (cur->bc_flags & XFS_BTREE_OVERLAPPING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) 		error = xfs_btree_update_keys(cur, level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) 			goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) 	 * If the cursor is really in the right block, move it there.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) 	 * If it's just pointing past the last entry in left, then we'll
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) 	 * insert there, so don't change anything in that case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769) 	if (cur->bc_ptrs[level] > lrecs + 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770) 		xfs_btree_setbuf(cur, level, rbp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771) 		cur->bc_ptrs[level] -= lrecs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774) 	 * If there are more levels, we'll need another cursor which refers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775) 	 * the right block, no matter where this cursor was.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) 	if (level + 1 < cur->bc_nlevels) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) 		error = xfs_btree_dup_cursor(cur, curp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) 			goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) 		(*curp)->bc_ptrs[level + 1]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) 	*ptrp = rptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) 	*stat = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) out0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) 	*stat = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) error0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) struct xfs_btree_split_args {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) 	struct xfs_btree_cur	*cur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796) 	int			level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797) 	union xfs_btree_ptr	*ptrp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) 	union xfs_btree_key	*key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) 	struct xfs_btree_cur	**curp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) 	int			*stat;		/* success/failure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) 	int			result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) 	bool			kswapd;	/* allocation in kswapd context */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) 	struct completion	*done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) 	struct work_struct	work;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808)  * Stack switching interfaces for allocation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) xfs_btree_split_worker(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) 	struct work_struct	*work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) 	struct xfs_btree_split_args	*args = container_of(work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) 						struct xfs_btree_split_args, work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) 	unsigned long		pflags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) 	unsigned long		new_pflags = PF_MEMALLOC_NOFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) 	 * we are in a transaction context here, but may also be doing work
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) 	 * in kswapd context, and hence we may need to inherit that state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) 	 * temporarily to ensure that we don't block waiting for memory reclaim
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) 	 * in any way.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) 	if (args->kswapd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) 		new_pflags |= PF_MEMALLOC | PF_SWAPWRITE | PF_KSWAPD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) 	current_set_flags_nested(&pflags, new_pflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) 	args->result = __xfs_btree_split(args->cur, args->level, args->ptrp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) 					 args->key, args->curp, args->stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) 	complete(args->done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) 	current_restore_flags_nested(&pflags, new_pflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838)  * BMBT split requests often come in with little stack to work on. Push
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839)  * them off to a worker thread so there is lots of stack to use. For the other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840)  * btree types, just call directly to avoid the context switch overhead here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) STATIC int					/* error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) xfs_btree_split(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) 	int			level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) 	union xfs_btree_ptr	*ptrp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) 	union xfs_btree_key	*key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) 	struct xfs_btree_cur	**curp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) 	int			*stat)		/* success/failure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) 	struct xfs_btree_split_args	args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) 	DECLARE_COMPLETION_ONSTACK(done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) 	if (cur->bc_btnum != XFS_BTNUM_BMAP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) 		return __xfs_btree_split(cur, level, ptrp, key, curp, stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) 	args.cur = cur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) 	args.level = level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) 	args.ptrp = ptrp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) 	args.key = key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) 	args.curp = curp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) 	args.stat = stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) 	args.done = &done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) 	args.kswapd = current_is_kswapd();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) 	INIT_WORK_ONSTACK(&args.work, xfs_btree_split_worker);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) 	queue_work(xfs_alloc_wq, &args.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) 	wait_for_completion(&done);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) 	destroy_work_on_stack(&args.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) 	return args.result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874)  * Copy the old inode root contents into a real block and make the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875)  * broot point to it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) int						/* error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) xfs_btree_new_iroot(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) 	struct xfs_btree_cur	*cur,		/* btree cursor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) 	int			*logflags,	/* logging flags for inode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) 	int			*stat)		/* return status - 0 fail */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) 	struct xfs_buf		*cbp;		/* buffer for cblock */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) 	struct xfs_btree_block	*block;		/* btree block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) 	struct xfs_btree_block	*cblock;	/* child btree block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) 	union xfs_btree_key	*ckp;		/* child key pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) 	union xfs_btree_ptr	*cpp;		/* child ptr pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) 	union xfs_btree_key	*kp;		/* pointer to btree key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) 	union xfs_btree_ptr	*pp;		/* pointer to block addr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) 	union xfs_btree_ptr	nptr;		/* new block addr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) 	int			level;		/* btree level */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) 	int			error;		/* error return code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893) 	int			i;		/* loop counter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895) 	XFS_BTREE_STATS_INC(cur, newroot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) 	ASSERT(cur->bc_flags & XFS_BTREE_ROOT_IN_INODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) 	level = cur->bc_nlevels - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) 	block = xfs_btree_get_iroot(cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) 	pp = xfs_btree_ptr_addr(cur, 1, block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) 	/* Allocate the new block. If we can't do it, we're toast. Give up. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) 	error = cur->bc_ops->alloc_block(cur, pp, &nptr, stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) 		goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) 	if (*stat == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911) 	XFS_BTREE_STATS_INC(cur, alloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) 	/* Copy the root into a real block. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) 	error = xfs_btree_get_buf_block(cur, &nptr, &cblock, &cbp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) 		goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) 	 * we can't just memcpy() the root in for CRC enabled btree blocks.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) 	 * In that case have to also ensure the blkno remains correct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) 	memcpy(cblock, block, xfs_btree_block_len(cur));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) 	if (cur->bc_flags & XFS_BTREE_CRC_BLOCKS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) 		if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) 			cblock->bb_u.l.bb_blkno = cpu_to_be64(cbp->b_bn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) 			cblock->bb_u.s.bb_blkno = cpu_to_be64(cbp->b_bn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) 	be16_add_cpu(&block->bb_level, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) 	xfs_btree_set_numrecs(block, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) 	cur->bc_nlevels++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) 	cur->bc_ptrs[level + 1] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) 	kp = xfs_btree_key_addr(cur, 1, block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) 	ckp = xfs_btree_key_addr(cur, 1, cblock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) 	xfs_btree_copy_keys(cur, ckp, kp, xfs_btree_get_numrecs(cblock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) 	cpp = xfs_btree_ptr_addr(cur, 1, cblock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) 	for (i = 0; i < be16_to_cpu(cblock->bb_numrecs); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) 		error = xfs_btree_debug_check_ptr(cur, pp, i, level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) 			goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) 	xfs_btree_copy_ptrs(cur, cpp, pp, xfs_btree_get_numrecs(cblock));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) 	error = xfs_btree_debug_check_ptr(cur, &nptr, 0, level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) 		goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) 	xfs_btree_copy_ptrs(cur, pp, &nptr, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) 	xfs_iroot_realloc(cur->bc_ino.ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) 			  1 - xfs_btree_get_numrecs(cblock),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) 			  cur->bc_ino.whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) 	xfs_btree_setbuf(cur, level, cbp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961) 	 * Do all this logging at the end so that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) 	 * the root is at the right level.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) 	xfs_btree_log_block(cur, cbp, XFS_BB_ALL_BITS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) 	xfs_btree_log_keys(cur, cbp, 1, be16_to_cpu(cblock->bb_numrecs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) 	xfs_btree_log_ptrs(cur, cbp, 1, be16_to_cpu(cblock->bb_numrecs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) 	*logflags |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) 		XFS_ILOG_CORE | xfs_ilog_fbroot(cur->bc_ino.whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) 	*stat = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) error0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977)  * Allocate a new root block, fill it in.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) STATIC int				/* error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) xfs_btree_new_root(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) 	struct xfs_btree_cur	*cur,	/* btree cursor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) 	int			*stat)	/* success/failure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) 	struct xfs_btree_block	*block;	/* one half of the old root block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) 	struct xfs_buf		*bp;	/* buffer containing block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) 	int			error;	/* error return value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) 	struct xfs_buf		*lbp;	/* left buffer pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) 	struct xfs_btree_block	*left;	/* left btree block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) 	struct xfs_buf		*nbp;	/* new (root) buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) 	struct xfs_btree_block	*new;	/* new (root) btree block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) 	int			nptr;	/* new value for key index, 1 or 2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992) 	struct xfs_buf		*rbp;	/* right buffer pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) 	struct xfs_btree_block	*right;	/* right btree block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) 	union xfs_btree_ptr	rptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) 	union xfs_btree_ptr	lptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) 	XFS_BTREE_STATS_INC(cur, newroot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999) 	/* initialise our start point from the cursor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) 	cur->bc_ops->init_ptr_from_cur(cur, &rptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002) 	/* Allocate the new block. If we can't do it, we're toast. Give up. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003) 	error = cur->bc_ops->alloc_block(cur, &rptr, &lptr, stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) 		goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) 	if (*stat == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) 		goto out0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008) 	XFS_BTREE_STATS_INC(cur, alloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) 	/* Set up the new block. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) 	error = xfs_btree_get_buf_block(cur, &lptr, &new, &nbp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) 		goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) 	/* Set the root in the holding structure  increasing the level by 1. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016) 	cur->bc_ops->set_root(cur, &lptr, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) 	 * At the previous root level there are now two blocks: the old root,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) 	 * and the new block generated when it was split.  We don't know which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021) 	 * one the cursor is pointing at, so we set up variables "left" and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022) 	 * "right" for each case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024) 	block = xfs_btree_get_block(cur, cur->bc_nlevels - 1, &bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) 	error = xfs_btree_check_block(cur, block, cur->bc_nlevels - 1, bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029) 		goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) 	xfs_btree_get_sibling(cur, block, &rptr, XFS_BB_RIGHTSIB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) 	if (!xfs_btree_ptr_is_null(cur, &rptr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034) 		/* Our block is left, pick up the right block. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) 		lbp = bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) 		xfs_btree_buf_to_ptr(cur, lbp, &lptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037) 		left = block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) 		error = xfs_btree_read_buf_block(cur, &rptr, 0, &right, &rbp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040) 			goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) 		bp = rbp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) 		nptr = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) 		/* Our block is right, pick up the left block. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045) 		rbp = bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046) 		xfs_btree_buf_to_ptr(cur, rbp, &rptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) 		right = block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048) 		xfs_btree_get_sibling(cur, right, &lptr, XFS_BB_LEFTSIB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) 		error = xfs_btree_read_buf_block(cur, &lptr, 0, &left, &lbp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051) 			goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052) 		bp = lbp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) 		nptr = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) 	/* Fill in the new block's btree header and log it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) 	xfs_btree_init_block_cur(cur, nbp, cur->bc_nlevels, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058) 	xfs_btree_log_block(cur, nbp, XFS_BB_ALL_BITS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) 	ASSERT(!xfs_btree_ptr_is_null(cur, &lptr) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) 			!xfs_btree_ptr_is_null(cur, &rptr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) 	/* Fill in the key data in the new root. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) 	if (xfs_btree_get_level(left) > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) 		 * Get the keys for the left block's keys and put them directly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) 		 * in the parent block.  Do the same for the right block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) 		xfs_btree_get_node_keys(cur, left,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) 				xfs_btree_key_addr(cur, 1, new));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070) 		xfs_btree_get_node_keys(cur, right,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) 				xfs_btree_key_addr(cur, 2, new));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074) 		 * Get the keys for the left block's records and put them
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) 		 * directly in the parent block.  Do the same for the right
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) 		 * block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078) 		xfs_btree_get_leaf_keys(cur, left,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) 			xfs_btree_key_addr(cur, 1, new));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080) 		xfs_btree_get_leaf_keys(cur, right,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) 			xfs_btree_key_addr(cur, 2, new));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) 	xfs_btree_log_keys(cur, nbp, 1, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) 	/* Fill in the pointer data in the new root. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086) 	xfs_btree_copy_ptrs(cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) 		xfs_btree_ptr_addr(cur, 1, new), &lptr, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) 	xfs_btree_copy_ptrs(cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) 		xfs_btree_ptr_addr(cur, 2, new), &rptr, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) 	xfs_btree_log_ptrs(cur, nbp, 1, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092) 	/* Fix up the cursor. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) 	xfs_btree_setbuf(cur, cur->bc_nlevels, nbp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) 	cur->bc_ptrs[cur->bc_nlevels] = nptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) 	cur->bc_nlevels++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096) 	*stat = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) error0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) out0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) 	*stat = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) xfs_btree_make_block_unfull(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107) 	struct xfs_btree_cur	*cur,	/* btree cursor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) 	int			level,	/* btree level */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) 	int			numrecs,/* # of recs in block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110) 	int			*oindex,/* old tree index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) 	int			*index,	/* new tree index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112) 	union xfs_btree_ptr	*nptr,	/* new btree ptr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113) 	struct xfs_btree_cur	**ncur,	/* new btree cursor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) 	union xfs_btree_key	*key,	/* key of new block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115) 	int			*stat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) 	int			error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119) 	if ((cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) 	    level == cur->bc_nlevels - 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) 		struct xfs_inode *ip = cur->bc_ino.ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123) 		if (numrecs < cur->bc_ops->get_dmaxrecs(cur, level)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124) 			/* A root block that can be made bigger. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125) 			xfs_iroot_realloc(ip, 1, cur->bc_ino.whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126) 			*stat = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128) 			/* A root block that needs replacing */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) 			int	logflags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) 			error = xfs_btree_new_iroot(cur, &logflags, stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) 			if (error || *stat == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133) 				return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) 			xfs_trans_log_inode(cur->bc_tp, ip, logflags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141) 	/* First, try shifting an entry to the right neighbor. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142) 	error = xfs_btree_rshift(cur, level, stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) 	if (error || *stat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146) 	/* Next, try shifting an entry to the left neighbor. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147) 	error = xfs_btree_lshift(cur, level, stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151) 	if (*stat) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152) 		*oindex = *index = cur->bc_ptrs[level];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157) 	 * Next, try splitting the current block in half.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) 	 * If this works we have to re-set our variables because we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160) 	 * could be in a different block now.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162) 	error = xfs_btree_split(cur, level, nptr, key, ncur, stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163) 	if (error || *stat == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) 	*index = cur->bc_ptrs[level];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172)  * Insert one record/level.  Return information to the caller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173)  * allowing the next level up to proceed if necessary.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176) xfs_btree_insrec(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177) 	struct xfs_btree_cur	*cur,	/* btree cursor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178) 	int			level,	/* level to insert record at */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179) 	union xfs_btree_ptr	*ptrp,	/* i/o: block number inserted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180) 	union xfs_btree_rec	*rec,	/* record to insert */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181) 	union xfs_btree_key	*key,	/* i/o: block key for ptrp */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182) 	struct xfs_btree_cur	**curp,	/* output: new cursor replacing cur */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183) 	int			*stat)	/* success/failure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185) 	struct xfs_btree_block	*block;	/* btree block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186) 	struct xfs_buf		*bp;	/* buffer for block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) 	union xfs_btree_ptr	nptr;	/* new block ptr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188) 	struct xfs_btree_cur	*ncur;	/* new btree cursor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189) 	union xfs_btree_key	nkey;	/* new block key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) 	union xfs_btree_key	*lkey;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191) 	int			optr;	/* old key/record index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192) 	int			ptr;	/* key/record index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193) 	int			numrecs;/* number of records */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194) 	int			error;	/* error return value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195) 	int			i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196) 	xfs_daddr_t		old_bn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198) 	ncur = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199) 	lkey = &nkey;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202) 	 * If we have an external root pointer, and we've made it to the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203) 	 * root level, allocate a new root block and we're done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205) 	if (!(cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206) 	    (level >= cur->bc_nlevels)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207) 		error = xfs_btree_new_root(cur, stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208) 		xfs_btree_set_ptr_null(cur, ptrp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213) 	/* If we're off the left edge, return failure. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214) 	ptr = cur->bc_ptrs[level];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215) 	if (ptr == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216) 		*stat = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220) 	optr = ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222) 	XFS_BTREE_STATS_INC(cur, insrec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224) 	/* Get pointers to the btree buffer and block. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225) 	block = xfs_btree_get_block(cur, level, &bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226) 	old_bn = bp ? bp->b_bn : XFS_BUF_DADDR_NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227) 	numrecs = xfs_btree_get_numrecs(block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230) 	error = xfs_btree_check_block(cur, block, level, bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232) 		goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234) 	/* Check that the new entry is being inserted in the right place. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235) 	if (ptr <= numrecs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236) 		if (level == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237) 			ASSERT(cur->bc_ops->recs_inorder(cur, rec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238) 				xfs_btree_rec_addr(cur, ptr, block)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240) 			ASSERT(cur->bc_ops->keys_inorder(cur, key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241) 				xfs_btree_key_addr(cur, ptr, block)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) 	 * If the block is full, we can't insert the new entry until we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248) 	 * make the block un-full.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250) 	xfs_btree_set_ptr_null(cur, &nptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251) 	if (numrecs == cur->bc_ops->get_maxrecs(cur, level)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252) 		error = xfs_btree_make_block_unfull(cur, level, numrecs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253) 					&optr, &ptr, &nptr, &ncur, lkey, stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254) 		if (error || *stat == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) 			goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259) 	 * The current block may have changed if the block was
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260) 	 * previously full and we have just made space in it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262) 	block = xfs_btree_get_block(cur, level, &bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263) 	numrecs = xfs_btree_get_numrecs(block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266) 	error = xfs_btree_check_block(cur, block, level, bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272) 	 * At this point we know there's room for our new entry in the block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273) 	 * we're pointing at.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275) 	XFS_BTREE_STATS_ADD(cur, moves, numrecs - ptr + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277) 	if (level > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278) 		/* It's a nonleaf. make a hole in the keys and ptrs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279) 		union xfs_btree_key	*kp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280) 		union xfs_btree_ptr	*pp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282) 		kp = xfs_btree_key_addr(cur, ptr, block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283) 		pp = xfs_btree_ptr_addr(cur, ptr, block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285) 		for (i = numrecs - ptr; i >= 0; i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286) 			error = xfs_btree_debug_check_ptr(cur, pp, i, level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287) 			if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288) 				return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291) 		xfs_btree_shift_keys(cur, kp, 1, numrecs - ptr + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292) 		xfs_btree_shift_ptrs(cur, pp, 1, numrecs - ptr + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294) 		error = xfs_btree_debug_check_ptr(cur, ptrp, 0, level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296) 			goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3298) 		/* Now put the new data in, bump numrecs and log it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3299) 		xfs_btree_copy_keys(cur, kp, key, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3300) 		xfs_btree_copy_ptrs(cur, pp, ptrp, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3301) 		numrecs++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3302) 		xfs_btree_set_numrecs(block, numrecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3303) 		xfs_btree_log_ptrs(cur, bp, ptr, numrecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3304) 		xfs_btree_log_keys(cur, bp, ptr, numrecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306) 		if (ptr < numrecs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307) 			ASSERT(cur->bc_ops->keys_inorder(cur, kp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308) 				xfs_btree_key_addr(cur, ptr + 1, block)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312) 		/* It's a leaf. make a hole in the records */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313) 		union xfs_btree_rec             *rp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315) 		rp = xfs_btree_rec_addr(cur, ptr, block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317) 		xfs_btree_shift_recs(cur, rp, 1, numrecs - ptr + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319) 		/* Now put the new data in, bump numrecs and log it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3320) 		xfs_btree_copy_recs(cur, rp, rec, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3321) 		xfs_btree_set_numrecs(block, ++numrecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3322) 		xfs_btree_log_recs(cur, bp, ptr, numrecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3323) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3324) 		if (ptr < numrecs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3325) 			ASSERT(cur->bc_ops->recs_inorder(cur, rp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3326) 				xfs_btree_rec_addr(cur, ptr + 1, block)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3327) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3328) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3329) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3330) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3331) 	/* Log the new number of records in the btree header. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3332) 	xfs_btree_log_block(cur, bp, XFS_BB_NUMRECS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3333) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3334) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3335) 	 * If we just inserted into a new tree block, we have to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3336) 	 * recalculate nkey here because nkey is out of date.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3337) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3338) 	 * Otherwise we're just updating an existing block (having shoved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3339) 	 * some records into the new tree block), so use the regular key
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3340) 	 * update mechanism.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3341) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3342) 	if (bp && bp->b_bn != old_bn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3343) 		xfs_btree_get_keys(cur, block, lkey);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3344) 	} else if (xfs_btree_needs_key_update(cur, optr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3345) 		error = xfs_btree_update_keys(cur, level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3346) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3347) 			goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3348) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3350) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3351) 	 * If we are tracking the last record in the tree and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3352) 	 * we are at the far right edge of the tree, update it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3353) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3354) 	if (xfs_btree_is_lastrec(cur, block, level)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3355) 		cur->bc_ops->update_lastrec(cur, block, rec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3356) 					    ptr, LASTREC_INSREC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3357) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3359) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3360) 	 * Return the new block number, if any.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3361) 	 * If there is one, give back a record value and a cursor too.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3362) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3363) 	*ptrp = nptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3364) 	if (!xfs_btree_ptr_is_null(cur, &nptr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3365) 		xfs_btree_copy_keys(cur, key, lkey, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3366) 		*curp = ncur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3367) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3368) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3369) 	*stat = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3370) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3372) error0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3373) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3376) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3377)  * Insert the record at the point referenced by cur.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3378)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3379)  * A multi-level split of the tree on insert will invalidate the original
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3380)  * cursor.  All callers of this function should assume that the cursor is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3381)  * no longer valid and revalidate it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3382)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3383) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3384) xfs_btree_insert(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3385) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3386) 	int			*stat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3387) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3388) 	int			error;	/* error return value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3389) 	int			i;	/* result value, 0 for failure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3390) 	int			level;	/* current level number in btree */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3391) 	union xfs_btree_ptr	nptr;	/* new block number (split result) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3392) 	struct xfs_btree_cur	*ncur;	/* new cursor (split result) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3393) 	struct xfs_btree_cur	*pcur;	/* previous level's cursor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3394) 	union xfs_btree_key	bkey;	/* key of block to insert */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3395) 	union xfs_btree_key	*key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3396) 	union xfs_btree_rec	rec;	/* record to insert */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3397) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3398) 	level = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3399) 	ncur = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3400) 	pcur = cur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3401) 	key = &bkey;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3403) 	xfs_btree_set_ptr_null(cur, &nptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3404) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3405) 	/* Make a key out of the record data to be inserted, and save it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3406) 	cur->bc_ops->init_rec_from_cur(cur, &rec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3407) 	cur->bc_ops->init_key_from_rec(key, &rec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3409) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3410) 	 * Loop going up the tree, starting at the leaf level.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3411) 	 * Stop when we don't get a split block, that must mean that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3412) 	 * the insert is finished with this level.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3413) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3414) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3415) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3416) 		 * Insert nrec/nptr into this level of the tree.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3417) 		 * Note if we fail, nptr will be null.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3418) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3419) 		error = xfs_btree_insrec(pcur, level, &nptr, &rec, key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3420) 				&ncur, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3421) 		if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3422) 			if (pcur != cur)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3423) 				xfs_btree_del_cursor(pcur, XFS_BTREE_ERROR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3424) 			goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3425) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3426) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3427) 		if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3428) 			error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3429) 			goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3430) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3431) 		level++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3433) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3434) 		 * See if the cursor we just used is trash.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3435) 		 * Can't trash the caller's cursor, but otherwise we should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3436) 		 * if ncur is a new cursor or we're about to be done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3437) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3438) 		if (pcur != cur &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3439) 		    (ncur || xfs_btree_ptr_is_null(cur, &nptr))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3440) 			/* Save the state from the cursor before we trash it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3441) 			if (cur->bc_ops->update_cursor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3442) 				cur->bc_ops->update_cursor(pcur, cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3443) 			cur->bc_nlevels = pcur->bc_nlevels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3444) 			xfs_btree_del_cursor(pcur, XFS_BTREE_NOERROR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3445) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3446) 		/* If we got a new cursor, switch to it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3447) 		if (ncur) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3448) 			pcur = ncur;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3449) 			ncur = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3450) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3451) 	} while (!xfs_btree_ptr_is_null(cur, &nptr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3453) 	*stat = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3454) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3455) error0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3456) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3459) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3460)  * Try to merge a non-leaf block back into the inode root.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3461)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3462)  * Note: the killroot names comes from the fact that we're effectively
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3463)  * killing the old root block.  But because we can't just delete the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3464)  * inode we have to copy the single block it was pointing to into the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3465)  * inode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3466)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3467) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3468) xfs_btree_kill_iroot(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3469) 	struct xfs_btree_cur	*cur)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3470) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3471) 	int			whichfork = cur->bc_ino.whichfork;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3472) 	struct xfs_inode	*ip = cur->bc_ino.ip;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3473) 	struct xfs_ifork	*ifp = XFS_IFORK_PTR(ip, whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3474) 	struct xfs_btree_block	*block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3475) 	struct xfs_btree_block	*cblock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3476) 	union xfs_btree_key	*kp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3477) 	union xfs_btree_key	*ckp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3478) 	union xfs_btree_ptr	*pp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3479) 	union xfs_btree_ptr	*cpp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3480) 	struct xfs_buf		*cbp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3481) 	int			level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3482) 	int			index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3483) 	int			numrecs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3484) 	int			error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3485) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3486) 	union xfs_btree_ptr	ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3487) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3488) 	int			i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3490) 	ASSERT(cur->bc_flags & XFS_BTREE_ROOT_IN_INODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3491) 	ASSERT(cur->bc_nlevels > 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3492) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3493) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3494) 	 * Don't deal with the root block needs to be a leaf case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3495) 	 * We're just going to turn the thing back into extents anyway.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3496) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3497) 	level = cur->bc_nlevels - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3498) 	if (level == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3499) 		goto out0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3501) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3502) 	 * Give up if the root has multiple children.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3503) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3504) 	block = xfs_btree_get_iroot(cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3505) 	if (xfs_btree_get_numrecs(block) != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3506) 		goto out0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3507) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3508) 	cblock = xfs_btree_get_block(cur, level - 1, &cbp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3509) 	numrecs = xfs_btree_get_numrecs(cblock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3511) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3512) 	 * Only do this if the next level will fit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3513) 	 * Then the data must be copied up to the inode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3514) 	 * instead of freeing the root you free the next level.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3515) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3516) 	if (numrecs > cur->bc_ops->get_dmaxrecs(cur, level))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3517) 		goto out0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3518) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3519) 	XFS_BTREE_STATS_INC(cur, killroot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3521) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3522) 	xfs_btree_get_sibling(cur, block, &ptr, XFS_BB_LEFTSIB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3523) 	ASSERT(xfs_btree_ptr_is_null(cur, &ptr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3524) 	xfs_btree_get_sibling(cur, block, &ptr, XFS_BB_RIGHTSIB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3525) 	ASSERT(xfs_btree_ptr_is_null(cur, &ptr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3526) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3528) 	index = numrecs - cur->bc_ops->get_maxrecs(cur, level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3529) 	if (index) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3530) 		xfs_iroot_realloc(cur->bc_ino.ip, index,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3531) 				  cur->bc_ino.whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3532) 		block = ifp->if_broot;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3533) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3534) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3535) 	be16_add_cpu(&block->bb_numrecs, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3536) 	ASSERT(block->bb_numrecs == cblock->bb_numrecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3537) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3538) 	kp = xfs_btree_key_addr(cur, 1, block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3539) 	ckp = xfs_btree_key_addr(cur, 1, cblock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3540) 	xfs_btree_copy_keys(cur, kp, ckp, numrecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3542) 	pp = xfs_btree_ptr_addr(cur, 1, block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3543) 	cpp = xfs_btree_ptr_addr(cur, 1, cblock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3544) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3545) 	for (i = 0; i < numrecs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3546) 		error = xfs_btree_debug_check_ptr(cur, cpp, i, level - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3547) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3548) 			return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3549) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3550) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3551) 	xfs_btree_copy_ptrs(cur, pp, cpp, numrecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3553) 	error = xfs_btree_free_block(cur, cbp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3554) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3555) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3557) 	cur->bc_bufs[level - 1] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3558) 	be16_add_cpu(&block->bb_level, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3559) 	xfs_trans_log_inode(cur->bc_tp, ip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3560) 		XFS_ILOG_CORE | xfs_ilog_fbroot(cur->bc_ino.whichfork));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3561) 	cur->bc_nlevels--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3562) out0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3563) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3564) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3566) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3567)  * Kill the current root node, and replace it with it's only child node.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3568)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3569) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3570) xfs_btree_kill_root(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3571) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3572) 	struct xfs_buf		*bp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3573) 	int			level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3574) 	union xfs_btree_ptr	*newroot)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3575) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3576) 	int			error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3577) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3578) 	XFS_BTREE_STATS_INC(cur, killroot);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3579) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3580) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3581) 	 * Update the root pointer, decreasing the level by 1 and then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3582) 	 * free the old root.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3583) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3584) 	cur->bc_ops->set_root(cur, newroot, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3586) 	error = xfs_btree_free_block(cur, bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3587) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3588) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3589) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3590) 	cur->bc_bufs[level] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3591) 	cur->bc_ra[level] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3592) 	cur->bc_nlevels--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3593) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3594) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3595) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3596) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3597) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3598) xfs_btree_dec_cursor(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3599) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3600) 	int			level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3601) 	int			*stat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3602) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3603) 	int			error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3604) 	int			i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3605) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3606) 	if (level > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3607) 		error = xfs_btree_decrement(cur, level, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3608) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3609) 			return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3610) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3612) 	*stat = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3613) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3615) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3616) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3617)  * Single level of the btree record deletion routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3618)  * Delete record pointed to by cur/level.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3619)  * Remove the record from its block then rebalance the tree.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3620)  * Return 0 for error, 1 for done, 2 to go on to the next level.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3621)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3622) STATIC int					/* error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3623) xfs_btree_delrec(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3624) 	struct xfs_btree_cur	*cur,		/* btree cursor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3625) 	int			level,		/* level removing record from */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3626) 	int			*stat)		/* fail/done/go-on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3627) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3628) 	struct xfs_btree_block	*block;		/* btree block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3629) 	union xfs_btree_ptr	cptr;		/* current block ptr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3630) 	struct xfs_buf		*bp;		/* buffer for block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3631) 	int			error;		/* error return value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3632) 	int			i;		/* loop counter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3633) 	union xfs_btree_ptr	lptr;		/* left sibling block ptr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3634) 	struct xfs_buf		*lbp;		/* left buffer pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3635) 	struct xfs_btree_block	*left;		/* left btree block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3636) 	int			lrecs = 0;	/* left record count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3637) 	int			ptr;		/* key/record index */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3638) 	union xfs_btree_ptr	rptr;		/* right sibling block ptr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3639) 	struct xfs_buf		*rbp;		/* right buffer pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3640) 	struct xfs_btree_block	*right;		/* right btree block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3641) 	struct xfs_btree_block	*rrblock;	/* right-right btree block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3642) 	struct xfs_buf		*rrbp;		/* right-right buffer pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3643) 	int			rrecs = 0;	/* right record count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3644) 	struct xfs_btree_cur	*tcur;		/* temporary btree cursor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3645) 	int			numrecs;	/* temporary numrec count */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3646) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3647) 	tcur = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3648) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3649) 	/* Get the index of the entry being deleted, check for nothing there. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3650) 	ptr = cur->bc_ptrs[level];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3651) 	if (ptr == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3652) 		*stat = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3653) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3654) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3655) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3656) 	/* Get the buffer & block containing the record or key/ptr. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3657) 	block = xfs_btree_get_block(cur, level, &bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3658) 	numrecs = xfs_btree_get_numrecs(block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3659) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3660) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3661) 	error = xfs_btree_check_block(cur, block, level, bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3662) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3663) 		goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3664) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3665) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3666) 	/* Fail if we're off the end of the block. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3667) 	if (ptr > numrecs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3668) 		*stat = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3669) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3670) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3671) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3672) 	XFS_BTREE_STATS_INC(cur, delrec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3673) 	XFS_BTREE_STATS_ADD(cur, moves, numrecs - ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3675) 	/* Excise the entries being deleted. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3676) 	if (level > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3677) 		/* It's a nonleaf. operate on keys and ptrs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3678) 		union xfs_btree_key	*lkp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3679) 		union xfs_btree_ptr	*lpp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3680) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3681) 		lkp = xfs_btree_key_addr(cur, ptr + 1, block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3682) 		lpp = xfs_btree_ptr_addr(cur, ptr + 1, block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3683) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3684) 		for (i = 0; i < numrecs - ptr; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3685) 			error = xfs_btree_debug_check_ptr(cur, lpp, i, level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3686) 			if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3687) 				goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3688) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3689) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3690) 		if (ptr < numrecs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3691) 			xfs_btree_shift_keys(cur, lkp, -1, numrecs - ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3692) 			xfs_btree_shift_ptrs(cur, lpp, -1, numrecs - ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3693) 			xfs_btree_log_keys(cur, bp, ptr, numrecs - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3694) 			xfs_btree_log_ptrs(cur, bp, ptr, numrecs - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3695) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3696) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3697) 		/* It's a leaf. operate on records */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3698) 		if (ptr < numrecs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3699) 			xfs_btree_shift_recs(cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3700) 				xfs_btree_rec_addr(cur, ptr + 1, block),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3701) 				-1, numrecs - ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3702) 			xfs_btree_log_recs(cur, bp, ptr, numrecs - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3703) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3704) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3705) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3706) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3707) 	 * Decrement and log the number of entries in the block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3708) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3709) 	xfs_btree_set_numrecs(block, --numrecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3710) 	xfs_btree_log_block(cur, bp, XFS_BB_NUMRECS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3711) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3712) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3713) 	 * If we are tracking the last record in the tree and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3714) 	 * we are at the far right edge of the tree, update it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3715) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3716) 	if (xfs_btree_is_lastrec(cur, block, level)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3717) 		cur->bc_ops->update_lastrec(cur, block, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3718) 					    ptr, LASTREC_DELREC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3719) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3720) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3721) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3722) 	 * We're at the root level.  First, shrink the root block in-memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3723) 	 * Try to get rid of the next level down.  If we can't then there's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3724) 	 * nothing left to do.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3725) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3726) 	if (level == cur->bc_nlevels - 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3727) 		if (cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3728) 			xfs_iroot_realloc(cur->bc_ino.ip, -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3729) 					  cur->bc_ino.whichfork);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3730) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3731) 			error = xfs_btree_kill_iroot(cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3732) 			if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3733) 				goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3734) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3735) 			error = xfs_btree_dec_cursor(cur, level, stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3736) 			if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3737) 				goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3738) 			*stat = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3739) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3740) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3741) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3742) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3743) 		 * If this is the root level, and there's only one entry left,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3744) 		 * and it's NOT the leaf level, then we can get rid of this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3745) 		 * level.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3746) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3747) 		if (numrecs == 1 && level > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3748) 			union xfs_btree_ptr	*pp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3749) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3750) 			 * pp is still set to the first pointer in the block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3751) 			 * Make it the new root of the btree.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3752) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3753) 			pp = xfs_btree_ptr_addr(cur, 1, block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3754) 			error = xfs_btree_kill_root(cur, bp, level, pp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3755) 			if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3756) 				goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3757) 		} else if (level > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3758) 			error = xfs_btree_dec_cursor(cur, level, stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3759) 			if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3760) 				goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3761) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3762) 		*stat = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3763) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3764) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3765) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3766) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3767) 	 * If we deleted the leftmost entry in the block, update the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3768) 	 * key values above us in the tree.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3769) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3770) 	if (xfs_btree_needs_key_update(cur, ptr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3771) 		error = xfs_btree_update_keys(cur, level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3772) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3773) 			goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3774) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3775) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3776) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3777) 	 * If the number of records remaining in the block is at least
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3778) 	 * the minimum, we're done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3779) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3780) 	if (numrecs >= cur->bc_ops->get_minrecs(cur, level)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3781) 		error = xfs_btree_dec_cursor(cur, level, stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3782) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3783) 			goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3784) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3785) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3786) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3787) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3788) 	 * Otherwise, we have to move some records around to keep the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3789) 	 * tree balanced.  Look at the left and right sibling blocks to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3790) 	 * see if we can re-balance by moving only one record.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3791) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3792) 	xfs_btree_get_sibling(cur, block, &rptr, XFS_BB_RIGHTSIB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3793) 	xfs_btree_get_sibling(cur, block, &lptr, XFS_BB_LEFTSIB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3794) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3795) 	if (cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3796) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3797) 		 * One child of root, need to get a chance to copy its contents
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3798) 		 * into the root and delete it. Can't go up to next level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3799) 		 * there's nothing to delete there.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3800) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3801) 		if (xfs_btree_ptr_is_null(cur, &rptr) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3802) 		    xfs_btree_ptr_is_null(cur, &lptr) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3803) 		    level == cur->bc_nlevels - 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3804) 			error = xfs_btree_kill_iroot(cur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3805) 			if (!error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3806) 				error = xfs_btree_dec_cursor(cur, level, stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3807) 			if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3808) 				goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3809) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3810) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3811) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3812) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3813) 	ASSERT(!xfs_btree_ptr_is_null(cur, &rptr) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3814) 	       !xfs_btree_ptr_is_null(cur, &lptr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3815) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3816) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3817) 	 * Duplicate the cursor so our btree manipulations here won't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3818) 	 * disrupt the next level up.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3819) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3820) 	error = xfs_btree_dup_cursor(cur, &tcur);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3821) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3822) 		goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3823) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3824) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3825) 	 * If there's a right sibling, see if it's ok to shift an entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3826) 	 * out of it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3827) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3828) 	if (!xfs_btree_ptr_is_null(cur, &rptr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3829) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3830) 		 * Move the temp cursor to the last entry in the next block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3831) 		 * Actually any entry but the first would suffice.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3832) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3833) 		i = xfs_btree_lastrec(tcur, level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3834) 		if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3835) 			error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3836) 			goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3837) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3838) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3839) 		error = xfs_btree_increment(tcur, level, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3840) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3841) 			goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3842) 		if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3843) 			error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3844) 			goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3845) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3846) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3847) 		i = xfs_btree_lastrec(tcur, level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3848) 		if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3849) 			error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3850) 			goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3851) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3852) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3853) 		/* Grab a pointer to the block. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3854) 		right = xfs_btree_get_block(tcur, level, &rbp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3855) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3856) 		error = xfs_btree_check_block(tcur, right, level, rbp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3857) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3858) 			goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3859) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3860) 		/* Grab the current block number, for future use. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3861) 		xfs_btree_get_sibling(tcur, right, &cptr, XFS_BB_LEFTSIB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3862) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3863) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3864) 		 * If right block is full enough so that removing one entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3865) 		 * won't make it too empty, and left-shifting an entry out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3866) 		 * of right to us works, we're done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3867) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3868) 		if (xfs_btree_get_numrecs(right) - 1 >=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3869) 		    cur->bc_ops->get_minrecs(tcur, level)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3870) 			error = xfs_btree_lshift(tcur, level, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3871) 			if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3872) 				goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3873) 			if (i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3874) 				ASSERT(xfs_btree_get_numrecs(block) >=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3875) 				       cur->bc_ops->get_minrecs(tcur, level));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3876) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3877) 				xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3878) 				tcur = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3879) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3880) 				error = xfs_btree_dec_cursor(cur, level, stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3881) 				if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3882) 					goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3883) 				return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3884) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3885) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3886) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3887) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3888) 		 * Otherwise, grab the number of records in right for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3889) 		 * future reference, and fix up the temp cursor to point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3890) 		 * to our block again (last record).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3891) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3892) 		rrecs = xfs_btree_get_numrecs(right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3893) 		if (!xfs_btree_ptr_is_null(cur, &lptr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3894) 			i = xfs_btree_firstrec(tcur, level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3895) 			if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3896) 				error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3897) 				goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3898) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3899) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3900) 			error = xfs_btree_decrement(tcur, level, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3901) 			if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3902) 				goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3903) 			if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3904) 				error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3905) 				goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3906) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3907) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3908) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3909) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3910) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3911) 	 * If there's a left sibling, see if it's ok to shift an entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3912) 	 * out of it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3913) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3914) 	if (!xfs_btree_ptr_is_null(cur, &lptr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3915) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3916) 		 * Move the temp cursor to the first entry in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3917) 		 * previous block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3918) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3919) 		i = xfs_btree_firstrec(tcur, level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3920) 		if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3921) 			error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3922) 			goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3923) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3924) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3925) 		error = xfs_btree_decrement(tcur, level, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3926) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3927) 			goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3928) 		i = xfs_btree_firstrec(tcur, level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3929) 		if (XFS_IS_CORRUPT(cur->bc_mp, i != 1)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3930) 			error = -EFSCORRUPTED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3931) 			goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3932) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3933) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3934) 		/* Grab a pointer to the block. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3935) 		left = xfs_btree_get_block(tcur, level, &lbp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3936) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3937) 		error = xfs_btree_check_block(cur, left, level, lbp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3938) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3939) 			goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3940) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3941) 		/* Grab the current block number, for future use. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3942) 		xfs_btree_get_sibling(tcur, left, &cptr, XFS_BB_RIGHTSIB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3943) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3944) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3945) 		 * If left block is full enough so that removing one entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3946) 		 * won't make it too empty, and right-shifting an entry out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3947) 		 * of left to us works, we're done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3948) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3949) 		if (xfs_btree_get_numrecs(left) - 1 >=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3950) 		    cur->bc_ops->get_minrecs(tcur, level)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3951) 			error = xfs_btree_rshift(tcur, level, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3952) 			if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3953) 				goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3954) 			if (i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3955) 				ASSERT(xfs_btree_get_numrecs(block) >=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3956) 				       cur->bc_ops->get_minrecs(tcur, level));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3957) 				xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3958) 				tcur = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3959) 				if (level == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3960) 					cur->bc_ptrs[0]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3961) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3962) 				*stat = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3963) 				return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3964) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3965) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3966) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3967) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3968) 		 * Otherwise, grab the number of records in right for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3969) 		 * future reference.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3970) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3971) 		lrecs = xfs_btree_get_numrecs(left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3972) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3973) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3974) 	/* Delete the temp cursor, we're done with it. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3975) 	xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3976) 	tcur = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3977) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3978) 	/* If here, we need to do a join to keep the tree balanced. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3979) 	ASSERT(!xfs_btree_ptr_is_null(cur, &cptr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3980) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3981) 	if (!xfs_btree_ptr_is_null(cur, &lptr) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3982) 	    lrecs + xfs_btree_get_numrecs(block) <=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3983) 			cur->bc_ops->get_maxrecs(cur, level)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3984) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3985) 		 * Set "right" to be the starting block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3986) 		 * "left" to be the left neighbor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3987) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3988) 		rptr = cptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3989) 		right = block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3990) 		rbp = bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3991) 		error = xfs_btree_read_buf_block(cur, &lptr, 0, &left, &lbp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3992) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3993) 			goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3994) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3995) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3996) 	 * If that won't work, see if we can join with the right neighbor block.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3997) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3998) 	} else if (!xfs_btree_ptr_is_null(cur, &rptr) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3999) 		   rrecs + xfs_btree_get_numrecs(block) <=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4000) 			cur->bc_ops->get_maxrecs(cur, level)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4001) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4002) 		 * Set "left" to be the starting block,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4003) 		 * "right" to be the right neighbor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4004) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4005) 		lptr = cptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4006) 		left = block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4007) 		lbp = bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4008) 		error = xfs_btree_read_buf_block(cur, &rptr, 0, &right, &rbp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4009) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4010) 			goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4011) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4012) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4013) 	 * Otherwise, we can't fix the imbalance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4014) 	 * Just return.  This is probably a logic error, but it's not fatal.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4015) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4016) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4017) 		error = xfs_btree_dec_cursor(cur, level, stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4018) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4019) 			goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4020) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4021) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4022) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4023) 	rrecs = xfs_btree_get_numrecs(right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4024) 	lrecs = xfs_btree_get_numrecs(left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4025) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4026) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4027) 	 * We're now going to join "left" and "right" by moving all the stuff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4028) 	 * in "right" to "left" and deleting "right".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4029) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4030) 	XFS_BTREE_STATS_ADD(cur, moves, rrecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4031) 	if (level > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4032) 		/* It's a non-leaf.  Move keys and pointers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4033) 		union xfs_btree_key	*lkp;	/* left btree key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4034) 		union xfs_btree_ptr	*lpp;	/* left address pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4035) 		union xfs_btree_key	*rkp;	/* right btree key */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4036) 		union xfs_btree_ptr	*rpp;	/* right address pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4037) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4038) 		lkp = xfs_btree_key_addr(cur, lrecs + 1, left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4039) 		lpp = xfs_btree_ptr_addr(cur, lrecs + 1, left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4040) 		rkp = xfs_btree_key_addr(cur, 1, right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4041) 		rpp = xfs_btree_ptr_addr(cur, 1, right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4042) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4043) 		for (i = 1; i < rrecs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4044) 			error = xfs_btree_debug_check_ptr(cur, rpp, i, level);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4045) 			if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4046) 				goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4047) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4048) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4049) 		xfs_btree_copy_keys(cur, lkp, rkp, rrecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4050) 		xfs_btree_copy_ptrs(cur, lpp, rpp, rrecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4051) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4052) 		xfs_btree_log_keys(cur, lbp, lrecs + 1, lrecs + rrecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4053) 		xfs_btree_log_ptrs(cur, lbp, lrecs + 1, lrecs + rrecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4054) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4055) 		/* It's a leaf.  Move records.  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4056) 		union xfs_btree_rec	*lrp;	/* left record pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4057) 		union xfs_btree_rec	*rrp;	/* right record pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4058) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4059) 		lrp = xfs_btree_rec_addr(cur, lrecs + 1, left);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4060) 		rrp = xfs_btree_rec_addr(cur, 1, right);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4061) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4062) 		xfs_btree_copy_recs(cur, lrp, rrp, rrecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4063) 		xfs_btree_log_recs(cur, lbp, lrecs + 1, lrecs + rrecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4064) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4065) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4066) 	XFS_BTREE_STATS_INC(cur, join);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4067) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4068) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4069) 	 * Fix up the number of records and right block pointer in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4070) 	 * surviving block, and log it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4071) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4072) 	xfs_btree_set_numrecs(left, lrecs + rrecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4073) 	xfs_btree_get_sibling(cur, right, &cptr, XFS_BB_RIGHTSIB),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4074) 	xfs_btree_set_sibling(cur, left, &cptr, XFS_BB_RIGHTSIB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4075) 	xfs_btree_log_block(cur, lbp, XFS_BB_NUMRECS | XFS_BB_RIGHTSIB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4076) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4077) 	/* If there is a right sibling, point it to the remaining block. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4078) 	xfs_btree_get_sibling(cur, left, &cptr, XFS_BB_RIGHTSIB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4079) 	if (!xfs_btree_ptr_is_null(cur, &cptr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4080) 		error = xfs_btree_read_buf_block(cur, &cptr, 0, &rrblock, &rrbp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4081) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4082) 			goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4083) 		xfs_btree_set_sibling(cur, rrblock, &lptr, XFS_BB_LEFTSIB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4084) 		xfs_btree_log_block(cur, rrbp, XFS_BB_LEFTSIB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4085) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4086) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4087) 	/* Free the deleted block. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4088) 	error = xfs_btree_free_block(cur, rbp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4089) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4090) 		goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4091) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4092) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4093) 	 * If we joined with the left neighbor, set the buffer in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4094) 	 * cursor to the left block, and fix up the index.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4095) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4096) 	if (bp != lbp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4097) 		cur->bc_bufs[level] = lbp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4098) 		cur->bc_ptrs[level] += lrecs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4099) 		cur->bc_ra[level] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4100) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4101) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4102) 	 * If we joined with the right neighbor and there's a level above
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4103) 	 * us, increment the cursor at that level.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4104) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4105) 	else if ((cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4106) 		   (level + 1 < cur->bc_nlevels)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4107) 		error = xfs_btree_increment(cur, level + 1, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4108) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4109) 			goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4110) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4112) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4113) 	 * Readjust the ptr at this level if it's not a leaf, since it's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4114) 	 * still pointing at the deletion point, which makes the cursor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4115) 	 * inconsistent.  If this makes the ptr 0, the caller fixes it up.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4116) 	 * We can't use decrement because it would change the next level up.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4117) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4118) 	if (level > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4119) 		cur->bc_ptrs[level]--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4121) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4122) 	 * We combined blocks, so we have to update the parent keys if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4123) 	 * btree supports overlapped intervals.  However, bc_ptrs[level + 1]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4124) 	 * points to the old block so that the caller knows which record to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4125) 	 * delete.  Therefore, the caller must be savvy enough to call updkeys
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4126) 	 * for us if we return stat == 2.  The other exit points from this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4127) 	 * function don't require deletions further up the tree, so they can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4128) 	 * call updkeys directly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4129) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4131) 	/* Return value means the next level up has something to do. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4132) 	*stat = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4133) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4135) error0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4136) 	if (tcur)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4137) 		xfs_btree_del_cursor(tcur, XFS_BTREE_ERROR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4138) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4141) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4142)  * Delete the record pointed to by cur.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4143)  * The cursor refers to the place where the record was (could be inserted)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4144)  * when the operation returns.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4145)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4146) int					/* error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4147) xfs_btree_delete(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4148) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4149) 	int			*stat)	/* success/failure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4151) 	int			error;	/* error return value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4152) 	int			level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4153) 	int			i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4154) 	bool			joined = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4156) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4157) 	 * Go up the tree, starting at leaf level.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4158) 	 *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4159) 	 * If 2 is returned then a join was done; go to the next level.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4160) 	 * Otherwise we are done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4161) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4162) 	for (level = 0, i = 2; i == 2; level++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4163) 		error = xfs_btree_delrec(cur, level, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4164) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4165) 			goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4166) 		if (i == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4167) 			joined = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4168) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4170) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4171) 	 * If we combined blocks as part of deleting the record, delrec won't
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4172) 	 * have updated the parent high keys so we have to do that here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4173) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4174) 	if (joined && (cur->bc_flags & XFS_BTREE_OVERLAPPING)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4175) 		error = xfs_btree_updkeys_force(cur, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4176) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4177) 			goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4178) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4180) 	if (i == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4181) 		for (level = 1; level < cur->bc_nlevels; level++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4182) 			if (cur->bc_ptrs[level] == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4183) 				error = xfs_btree_decrement(cur, level, &i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4184) 				if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4185) 					goto error0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4186) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4187) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4188) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4189) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4191) 	*stat = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4192) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4193) error0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4194) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4196) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4197) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4198)  * Get the data from the pointed-to record.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4199)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4200) int					/* error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4201) xfs_btree_get_rec(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4202) 	struct xfs_btree_cur	*cur,	/* btree cursor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4203) 	union xfs_btree_rec	**recp,	/* output: btree record */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4204) 	int			*stat)	/* output: success/failure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4205) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4206) 	struct xfs_btree_block	*block;	/* btree block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4207) 	struct xfs_buf		*bp;	/* buffer pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4208) 	int			ptr;	/* record number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4209) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4210) 	int			error;	/* error return value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4211) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4213) 	ptr = cur->bc_ptrs[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4214) 	block = xfs_btree_get_block(cur, 0, &bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4216) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4217) 	error = xfs_btree_check_block(cur, block, 0, bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4218) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4219) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4220) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4222) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4223) 	 * Off the right end or left end, return failure.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4224) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4225) 	if (ptr > xfs_btree_get_numrecs(block) || ptr <= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4226) 		*stat = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4227) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4228) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4229) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4230) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4231) 	 * Point to the record and extract its data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4232) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4233) 	*recp = xfs_btree_rec_addr(cur, ptr, block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4234) 	*stat = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4235) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4237) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4238) /* Visit a block in a btree. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4239) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4240) xfs_btree_visit_block(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4241) 	struct xfs_btree_cur		*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4242) 	int				level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4243) 	xfs_btree_visit_blocks_fn	fn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4244) 	void				*data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4246) 	struct xfs_btree_block		*block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4247) 	struct xfs_buf			*bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4248) 	union xfs_btree_ptr		rptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4249) 	int				error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4250) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4251) 	/* do right sibling readahead */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4252) 	xfs_btree_readahead(cur, level, XFS_BTCUR_RIGHTRA);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4253) 	block = xfs_btree_get_block(cur, level, &bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4255) 	/* process the block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4256) 	error = fn(cur, level, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4257) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4258) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4260) 	/* now read rh sibling block for next iteration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4261) 	xfs_btree_get_sibling(cur, block, &rptr, XFS_BB_RIGHTSIB);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4262) 	if (xfs_btree_ptr_is_null(cur, &rptr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4263) 		return -ENOENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4265) 	return xfs_btree_lookup_get_block(cur, level, &rptr, &block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4269) /* Visit every block in a btree. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4270) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4271) xfs_btree_visit_blocks(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4272) 	struct xfs_btree_cur		*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4273) 	xfs_btree_visit_blocks_fn	fn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4274) 	unsigned int			flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4275) 	void				*data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4276) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4277) 	union xfs_btree_ptr		lptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4278) 	int				level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4279) 	struct xfs_btree_block		*block = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4280) 	int				error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4282) 	cur->bc_ops->init_ptr_from_cur(cur, &lptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4283) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4284) 	/* for each level */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4285) 	for (level = cur->bc_nlevels - 1; level >= 0; level--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4286) 		/* grab the left hand block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4287) 		error = xfs_btree_lookup_get_block(cur, level, &lptr, &block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4288) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4289) 			return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4291) 		/* readahead the left most block for the next level down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4292) 		if (level > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4293) 			union xfs_btree_ptr     *ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4295) 			ptr = xfs_btree_ptr_addr(cur, 1, block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4296) 			xfs_btree_readahead_ptr(cur, ptr, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4298) 			/* save for the next iteration of the loop */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4299) 			xfs_btree_copy_ptrs(cur, &lptr, ptr, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4301) 			if (!(flags & XFS_BTREE_VISIT_LEAVES))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4302) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4303) 		} else if (!(flags & XFS_BTREE_VISIT_RECORDS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4304) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4305) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4307) 		/* for each buffer in the level */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4308) 		do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4309) 			error = xfs_btree_visit_block(cur, level, fn, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4310) 		} while (!error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4311) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4312) 		if (error != -ENOENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4313) 			return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4314) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4316) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4317) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4319) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4320)  * Change the owner of a btree.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4321)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4322)  * The mechanism we use here is ordered buffer logging. Because we don't know
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4323)  * how many buffers were are going to need to modify, we don't really want to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4324)  * have to make transaction reservations for the worst case of every buffer in a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4325)  * full size btree as that may be more space that we can fit in the log....
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4326)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4327)  * We do the btree walk in the most optimal manner possible - we have sibling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4328)  * pointers so we can just walk all the blocks on each level from left to right
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4329)  * in a single pass, and then move to the next level and do the same. We can
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4330)  * also do readahead on the sibling pointers to get IO moving more quickly,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4331)  * though for slow disks this is unlikely to make much difference to performance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4332)  * as the amount of CPU work we have to do before moving to the next block is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4333)  * relatively small.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4334)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4335)  * For each btree block that we load, modify the owner appropriately, set the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4336)  * buffer as an ordered buffer and log it appropriately. We need to ensure that
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4337)  * we mark the region we change dirty so that if the buffer is relogged in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4338)  * a subsequent transaction the changes we make here as an ordered buffer are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4339)  * correctly relogged in that transaction.  If we are in recovery context, then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4340)  * just queue the modified buffer as delayed write buffer so the transaction
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4341)  * recovery completion writes the changes to disk.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4342)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4343) struct xfs_btree_block_change_owner_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4344) 	uint64_t		new_owner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4345) 	struct list_head	*buffer_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4346) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4347) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4348) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4349) xfs_btree_block_change_owner(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4350) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4351) 	int			level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4352) 	void			*data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4353) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4354) 	struct xfs_btree_block_change_owner_info	*bbcoi = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4355) 	struct xfs_btree_block	*block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4356) 	struct xfs_buf		*bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4357) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4358) 	/* modify the owner */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4359) 	block = xfs_btree_get_block(cur, level, &bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4360) 	if (cur->bc_flags & XFS_BTREE_LONG_PTRS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4361) 		if (block->bb_u.l.bb_owner == cpu_to_be64(bbcoi->new_owner))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4362) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4363) 		block->bb_u.l.bb_owner = cpu_to_be64(bbcoi->new_owner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4364) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4365) 		if (block->bb_u.s.bb_owner == cpu_to_be32(bbcoi->new_owner))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4366) 			return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4367) 		block->bb_u.s.bb_owner = cpu_to_be32(bbcoi->new_owner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4368) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4369) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4370) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4371) 	 * If the block is a root block hosted in an inode, we might not have a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4372) 	 * buffer pointer here and we shouldn't attempt to log the change as the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4373) 	 * information is already held in the inode and discarded when the root
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4374) 	 * block is formatted into the on-disk inode fork. We still change it,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4375) 	 * though, so everything is consistent in memory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4376) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4377) 	if (!bp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4378) 		ASSERT(cur->bc_flags & XFS_BTREE_ROOT_IN_INODE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4379) 		ASSERT(level == cur->bc_nlevels - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4380) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4381) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4383) 	if (cur->bc_tp) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4384) 		if (!xfs_trans_ordered_buf(cur->bc_tp, bp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4385) 			xfs_btree_log_block(cur, bp, XFS_BB_OWNER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4386) 			return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4387) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4388) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4389) 		xfs_buf_delwri_queue(bp, bbcoi->buffer_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4390) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4392) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4393) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4395) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4396) xfs_btree_change_owner(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4397) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4398) 	uint64_t		new_owner,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4399) 	struct list_head	*buffer_list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4400) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4401) 	struct xfs_btree_block_change_owner_info	bbcoi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4403) 	bbcoi.new_owner = new_owner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4404) 	bbcoi.buffer_list = buffer_list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4406) 	return xfs_btree_visit_blocks(cur, xfs_btree_block_change_owner,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4407) 			XFS_BTREE_VISIT_ALL, &bbcoi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4408) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4410) /* Verify the v5 fields of a long-format btree block. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4411) xfs_failaddr_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4412) xfs_btree_lblock_v5hdr_verify(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4413) 	struct xfs_buf		*bp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4414) 	uint64_t		owner)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4415) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4416) 	struct xfs_mount	*mp = bp->b_mount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4417) 	struct xfs_btree_block	*block = XFS_BUF_TO_BLOCK(bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4418) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4419) 	if (!xfs_sb_version_hascrc(&mp->m_sb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4420) 		return __this_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4421) 	if (!uuid_equal(&block->bb_u.l.bb_uuid, &mp->m_sb.sb_meta_uuid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4422) 		return __this_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4423) 	if (block->bb_u.l.bb_blkno != cpu_to_be64(bp->b_bn))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4424) 		return __this_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4425) 	if (owner != XFS_RMAP_OWN_UNKNOWN &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4426) 	    be64_to_cpu(block->bb_u.l.bb_owner) != owner)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4427) 		return __this_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4428) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4431) /* Verify a long-format btree block. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4432) xfs_failaddr_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4433) xfs_btree_lblock_verify(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4434) 	struct xfs_buf		*bp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4435) 	unsigned int		max_recs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4436) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4437) 	struct xfs_mount	*mp = bp->b_mount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4438) 	struct xfs_btree_block	*block = XFS_BUF_TO_BLOCK(bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4439) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4440) 	/* numrecs verification */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4441) 	if (be16_to_cpu(block->bb_numrecs) > max_recs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4442) 		return __this_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4443) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4444) 	/* sibling pointer verification */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4445) 	if (block->bb_u.l.bb_leftsib != cpu_to_be64(NULLFSBLOCK) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4446) 	    !xfs_verify_fsbno(mp, be64_to_cpu(block->bb_u.l.bb_leftsib)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4447) 		return __this_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4448) 	if (block->bb_u.l.bb_rightsib != cpu_to_be64(NULLFSBLOCK) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4449) 	    !xfs_verify_fsbno(mp, be64_to_cpu(block->bb_u.l.bb_rightsib)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4450) 		return __this_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4452) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4453) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4455) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4456)  * xfs_btree_sblock_v5hdr_verify() -- verify the v5 fields of a short-format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4457)  *				      btree block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4458)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4459)  * @bp: buffer containing the btree block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4460)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4461) xfs_failaddr_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4462) xfs_btree_sblock_v5hdr_verify(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4463) 	struct xfs_buf		*bp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4464) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4465) 	struct xfs_mount	*mp = bp->b_mount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4466) 	struct xfs_btree_block	*block = XFS_BUF_TO_BLOCK(bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4467) 	struct xfs_perag	*pag = bp->b_pag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4469) 	if (!xfs_sb_version_hascrc(&mp->m_sb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4470) 		return __this_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4471) 	if (!uuid_equal(&block->bb_u.s.bb_uuid, &mp->m_sb.sb_meta_uuid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4472) 		return __this_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4473) 	if (block->bb_u.s.bb_blkno != cpu_to_be64(bp->b_bn))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4474) 		return __this_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4475) 	if (pag && be32_to_cpu(block->bb_u.s.bb_owner) != pag->pag_agno)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4476) 		return __this_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4477) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4478) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4479) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4480) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4481)  * xfs_btree_sblock_verify() -- verify a short-format btree block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4482)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4483)  * @bp: buffer containing the btree block
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4484)  * @max_recs: maximum records allowed in this btree node
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4485)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4486) xfs_failaddr_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4487) xfs_btree_sblock_verify(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4488) 	struct xfs_buf		*bp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4489) 	unsigned int		max_recs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4490) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4491) 	struct xfs_mount	*mp = bp->b_mount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4492) 	struct xfs_btree_block	*block = XFS_BUF_TO_BLOCK(bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4493) 	xfs_agblock_t		agno;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4495) 	/* numrecs verification */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4496) 	if (be16_to_cpu(block->bb_numrecs) > max_recs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4497) 		return __this_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4498) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4499) 	/* sibling pointer verification */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4500) 	agno = xfs_daddr_to_agno(mp, XFS_BUF_ADDR(bp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4501) 	if (block->bb_u.s.bb_leftsib != cpu_to_be32(NULLAGBLOCK) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4502) 	    !xfs_verify_agbno(mp, agno, be32_to_cpu(block->bb_u.s.bb_leftsib)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4503) 		return __this_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4504) 	if (block->bb_u.s.bb_rightsib != cpu_to_be32(NULLAGBLOCK) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4505) 	    !xfs_verify_agbno(mp, agno, be32_to_cpu(block->bb_u.s.bb_rightsib)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4506) 		return __this_address;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4507) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4508) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4509) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4510) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4511) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4512)  * Calculate the number of btree levels needed to store a given number of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4513)  * records in a short-format btree.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4514)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4515) uint
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4516) xfs_btree_compute_maxlevels(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4517) 	uint			*limits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4518) 	unsigned long		len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4519) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4520) 	uint			level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4521) 	unsigned long		maxblocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4523) 	maxblocks = (len + limits[0] - 1) / limits[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4524) 	for (level = 1; maxblocks > 1; level++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4525) 		maxblocks = (maxblocks + limits[1] - 1) / limits[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4526) 	return level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4527) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4528) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4529) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4530)  * Query a regular btree for all records overlapping a given interval.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4531)  * Start with a LE lookup of the key of low_rec and return all records
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4532)  * until we find a record with a key greater than the key of high_rec.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4533)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4534) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4535) xfs_btree_simple_query_range(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4536) 	struct xfs_btree_cur		*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4537) 	union xfs_btree_key		*low_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4538) 	union xfs_btree_key		*high_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4539) 	xfs_btree_query_range_fn	fn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4540) 	void				*priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4541) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4542) 	union xfs_btree_rec		*recp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4543) 	union xfs_btree_key		rec_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4544) 	int64_t				diff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4545) 	int				stat;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4546) 	bool				firstrec = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4547) 	int				error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4548) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4549) 	ASSERT(cur->bc_ops->init_high_key_from_rec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4550) 	ASSERT(cur->bc_ops->diff_two_keys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4551) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4552) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4553) 	 * Find the leftmost record.  The btree cursor must be set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4554) 	 * to the low record used to generate low_key.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4555) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4556) 	stat = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4557) 	error = xfs_btree_lookup(cur, XFS_LOOKUP_LE, &stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4558) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4559) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4561) 	/* Nothing?  See if there's anything to the right. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4562) 	if (!stat) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4563) 		error = xfs_btree_increment(cur, 0, &stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4564) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4565) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4566) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4568) 	while (stat) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4569) 		/* Find the record. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4570) 		error = xfs_btree_get_rec(cur, &recp, &stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4571) 		if (error || !stat)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4572) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4574) 		/* Skip if high_key(rec) < low_key. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4575) 		if (firstrec) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4576) 			cur->bc_ops->init_high_key_from_rec(&rec_key, recp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4577) 			firstrec = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4578) 			diff = cur->bc_ops->diff_two_keys(cur, low_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4579) 					&rec_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4580) 			if (diff > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4581) 				goto advloop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4582) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4583) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4584) 		/* Stop if high_key < low_key(rec). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4585) 		cur->bc_ops->init_key_from_rec(&rec_key, recp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4586) 		diff = cur->bc_ops->diff_two_keys(cur, &rec_key, high_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4587) 		if (diff > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4588) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4589) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4590) 		/* Callback */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4591) 		error = fn(cur, recp, priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4592) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4593) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4594) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4595) advloop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4596) 		/* Move on to the next record. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4597) 		error = xfs_btree_increment(cur, 0, &stat);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4598) 		if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4599) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4600) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4601) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4602) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4603) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4604) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4605) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4606) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4607)  * Query an overlapped interval btree for all records overlapping a given
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4608)  * interval.  This function roughly follows the algorithm given in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4609)  * "Interval Trees" of _Introduction to Algorithms_, which is section
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4610)  * 14.3 in the 2nd and 3rd editions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4611)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4612)  * First, generate keys for the low and high records passed in.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4613)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4614)  * For any leaf node, generate the high and low keys for the record.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4615)  * If the record keys overlap with the query low/high keys, pass the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4616)  * record to the function iterator.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4617)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4618)  * For any internal node, compare the low and high keys of each
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4619)  * pointer against the query low/high keys.  If there's an overlap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4620)  * follow the pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4621)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4622)  * As an optimization, we stop scanning a block when we find a low key
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4623)  * that is greater than the query's high key.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4624)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4625) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4626) xfs_btree_overlapped_query_range(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4627) 	struct xfs_btree_cur		*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4628) 	union xfs_btree_key		*low_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4629) 	union xfs_btree_key		*high_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4630) 	xfs_btree_query_range_fn	fn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4631) 	void				*priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4632) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4633) 	union xfs_btree_ptr		ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4634) 	union xfs_btree_ptr		*pp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4635) 	union xfs_btree_key		rec_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4636) 	union xfs_btree_key		rec_hkey;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4637) 	union xfs_btree_key		*lkp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4638) 	union xfs_btree_key		*hkp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4639) 	union xfs_btree_rec		*recp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4640) 	struct xfs_btree_block		*block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4641) 	int64_t				ldiff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4642) 	int64_t				hdiff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4643) 	int				level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4644) 	struct xfs_buf			*bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4645) 	int				i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4646) 	int				error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4647) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4648) 	/* Load the root of the btree. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4649) 	level = cur->bc_nlevels - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4650) 	cur->bc_ops->init_ptr_from_cur(cur, &ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4651) 	error = xfs_btree_lookup_get_block(cur, level, &ptr, &block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4652) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4653) 		return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4654) 	xfs_btree_get_block(cur, level, &bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4655) 	trace_xfs_btree_overlapped_query_range(cur, level, bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4656) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4657) 	error = xfs_btree_check_block(cur, block, level, bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4658) 	if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4659) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4660) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4661) 	cur->bc_ptrs[level] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4662) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4663) 	while (level < cur->bc_nlevels) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4664) 		block = xfs_btree_get_block(cur, level, &bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4665) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4666) 		/* End of node, pop back towards the root. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4667) 		if (cur->bc_ptrs[level] > be16_to_cpu(block->bb_numrecs)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4668) pop_up:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4669) 			if (level < cur->bc_nlevels - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4670) 				cur->bc_ptrs[level + 1]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4671) 			level++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4672) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4673) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4675) 		if (level == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4676) 			/* Handle a leaf node. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4677) 			recp = xfs_btree_rec_addr(cur, cur->bc_ptrs[0], block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4678) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4679) 			cur->bc_ops->init_high_key_from_rec(&rec_hkey, recp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4680) 			ldiff = cur->bc_ops->diff_two_keys(cur, &rec_hkey,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4681) 					low_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4682) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4683) 			cur->bc_ops->init_key_from_rec(&rec_key, recp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4684) 			hdiff = cur->bc_ops->diff_two_keys(cur, high_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4685) 					&rec_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4686) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4687) 			/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4688) 			 * If (record's high key >= query's low key) and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4689) 			 *    (query's high key >= record's low key), then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4690) 			 * this record overlaps the query range; callback.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4691) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4692) 			if (ldiff >= 0 && hdiff >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4693) 				error = fn(cur, recp, priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4694) 				if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4695) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4696) 			} else if (hdiff < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4697) 				/* Record is larger than high key; pop. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4698) 				goto pop_up;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4699) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4700) 			cur->bc_ptrs[level]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4701) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4702) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4703) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4704) 		/* Handle an internal node. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4705) 		lkp = xfs_btree_key_addr(cur, cur->bc_ptrs[level], block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4706) 		hkp = xfs_btree_high_key_addr(cur, cur->bc_ptrs[level], block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4707) 		pp = xfs_btree_ptr_addr(cur, cur->bc_ptrs[level], block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4708) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4709) 		ldiff = cur->bc_ops->diff_two_keys(cur, hkp, low_key);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4710) 		hdiff = cur->bc_ops->diff_two_keys(cur, high_key, lkp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4711) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4712) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4713) 		 * If (pointer's high key >= query's low key) and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4714) 		 *    (query's high key >= pointer's low key), then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4715) 		 * this record overlaps the query range; follow pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4716) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4717) 		if (ldiff >= 0 && hdiff >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4718) 			level--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4719) 			error = xfs_btree_lookup_get_block(cur, level, pp,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4720) 					&block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4721) 			if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4722) 				goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4723) 			xfs_btree_get_block(cur, level, &bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4724) 			trace_xfs_btree_overlapped_query_range(cur, level, bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4725) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4726) 			error = xfs_btree_check_block(cur, block, level, bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4727) 			if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4728) 				goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4729) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4730) 			cur->bc_ptrs[level] = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4731) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4732) 		} else if (hdiff < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4733) 			/* The low key is larger than the upper range; pop. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4734) 			goto pop_up;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4735) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4736) 		cur->bc_ptrs[level]++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4737) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4738) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4739) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4740) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4741) 	 * If we don't end this function with the cursor pointing at a record
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4742) 	 * block, a subsequent non-error cursor deletion will not release
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4743) 	 * node-level buffers, causing a buffer leak.  This is quite possible
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4744) 	 * with a zero-results range query, so release the buffers if we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4745) 	 * failed to return any results.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4746) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4747) 	if (cur->bc_bufs[0] == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4748) 		for (i = 0; i < cur->bc_nlevels; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4749) 			if (cur->bc_bufs[i]) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4750) 				xfs_trans_brelse(cur->bc_tp, cur->bc_bufs[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4751) 				cur->bc_bufs[i] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4752) 				cur->bc_ptrs[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4753) 				cur->bc_ra[i] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4754) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4755) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4756) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4757) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4758) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4759) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4760) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4761) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4762)  * Query a btree for all records overlapping a given interval of keys.  The
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4763)  * supplied function will be called with each record found; return one of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4764)  * XFS_BTREE_QUERY_RANGE_{CONTINUE,ABORT} values or the usual negative error
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4765)  * code.  This function returns -ECANCELED, zero, or a negative error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4766)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4767) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4768) xfs_btree_query_range(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4769) 	struct xfs_btree_cur		*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4770) 	union xfs_btree_irec		*low_rec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4771) 	union xfs_btree_irec		*high_rec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4772) 	xfs_btree_query_range_fn	fn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4773) 	void				*priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4774) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4775) 	union xfs_btree_rec		rec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4776) 	union xfs_btree_key		low_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4777) 	union xfs_btree_key		high_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4778) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4779) 	/* Find the keys of both ends of the interval. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4780) 	cur->bc_rec = *high_rec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4781) 	cur->bc_ops->init_rec_from_cur(cur, &rec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4782) 	cur->bc_ops->init_key_from_rec(&high_key, &rec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4783) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4784) 	cur->bc_rec = *low_rec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4785) 	cur->bc_ops->init_rec_from_cur(cur, &rec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4786) 	cur->bc_ops->init_key_from_rec(&low_key, &rec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4787) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4788) 	/* Enforce low key < high key. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4789) 	if (cur->bc_ops->diff_two_keys(cur, &low_key, &high_key) > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4790) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4791) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4792) 	if (!(cur->bc_flags & XFS_BTREE_OVERLAPPING))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4793) 		return xfs_btree_simple_query_range(cur, &low_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4794) 				&high_key, fn, priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4795) 	return xfs_btree_overlapped_query_range(cur, &low_key, &high_key,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4796) 			fn, priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4797) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4798) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4799) /* Query a btree for all records. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4800) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4801) xfs_btree_query_all(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4802) 	struct xfs_btree_cur		*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4803) 	xfs_btree_query_range_fn	fn,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4804) 	void				*priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4805) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4806) 	union xfs_btree_key		low_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4807) 	union xfs_btree_key		high_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4808) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4809) 	memset(&cur->bc_rec, 0, sizeof(cur->bc_rec));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4810) 	memset(&low_key, 0, sizeof(low_key));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4811) 	memset(&high_key, 0xFF, sizeof(high_key));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4812) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4813) 	return xfs_btree_simple_query_range(cur, &low_key, &high_key, fn, priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4814) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4815) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4816) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4817)  * Calculate the number of blocks needed to store a given number of records
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4818)  * in a short-format (per-AG metadata) btree.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4819)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4820) unsigned long long
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4821) xfs_btree_calc_size(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4822) 	uint			*limits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4823) 	unsigned long long	len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4824) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4825) 	int			level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4826) 	int			maxrecs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4827) 	unsigned long long	rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4828) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4829) 	maxrecs = limits[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4830) 	for (level = 0, rval = 0; len > 1; level++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4831) 		len += maxrecs - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4832) 		do_div(len, maxrecs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4833) 		maxrecs = limits[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4834) 		rval += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4835) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4836) 	return rval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4837) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4838) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4839) static int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4840) xfs_btree_count_blocks_helper(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4841) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4842) 	int			level,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4843) 	void			*data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4844) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4845) 	xfs_extlen_t		*blocks = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4846) 	(*blocks)++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4847) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4848) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4849) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4850) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4851) /* Count the blocks in a btree and return the result in *blocks. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4852) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4853) xfs_btree_count_blocks(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4854) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4855) 	xfs_extlen_t		*blocks)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4856) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4857) 	*blocks = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4858) 	return xfs_btree_visit_blocks(cur, xfs_btree_count_blocks_helper,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4859) 			XFS_BTREE_VISIT_ALL, blocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4860) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4861) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4862) /* Compare two btree pointers. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4863) int64_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4864) xfs_btree_diff_two_ptrs(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4865) 	struct xfs_btree_cur		*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4866) 	const union xfs_btree_ptr	*a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4867) 	const union xfs_btree_ptr	*b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4868) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4869) 	if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4870) 		return (int64_t)be64_to_cpu(a->l) - be64_to_cpu(b->l);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4871) 	return (int64_t)be32_to_cpu(a->s) - be32_to_cpu(b->s);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4872) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4873) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4874) /* If there's an extent, we're done. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4875) STATIC int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4876) xfs_btree_has_record_helper(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4877) 	struct xfs_btree_cur		*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4878) 	union xfs_btree_rec		*rec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4879) 	void				*priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4880) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4881) 	return -ECANCELED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4882) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4883) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4884) /* Is there a record covering a given range of keys? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4885) int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4886) xfs_btree_has_record(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4887) 	struct xfs_btree_cur	*cur,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4888) 	union xfs_btree_irec	*low,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4889) 	union xfs_btree_irec	*high,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4890) 	bool			*exists)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4891) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4892) 	int			error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4893) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4894) 	error = xfs_btree_query_range(cur, low, high,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4895) 			&xfs_btree_has_record_helper, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4896) 	if (error == -ECANCELED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4897) 		*exists = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4898) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4899) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4900) 	*exists = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4901) 	return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4902) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4903) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4904) /* Are there more records in this btree? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4905) bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4906) xfs_btree_has_more_records(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4907) 	struct xfs_btree_cur	*cur)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4908) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4909) 	struct xfs_btree_block	*block;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4910) 	struct xfs_buf		*bp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4911) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4912) 	block = xfs_btree_get_block(cur, 0, &bp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4913) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4914) 	/* There are still records in this block. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4915) 	if (cur->bc_ptrs[0] < xfs_btree_get_numrecs(block))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4916) 		return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4917) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4918) 	/* There are more record blocks. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4919) 	if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4920) 		return block->bb_u.l.bb_rightsib != cpu_to_be64(NULLFSBLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4921) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4922) 		return block->bb_u.s.bb_rightsib != cpu_to_be32(NULLAGBLOCK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4923) }