Commit ee138217 authored by Chandan Babu R's avatar Chandan Babu R
Browse files

Merge tag 'btree-remove-btnum-6.9_2024-02-23' of...

Merge tag 'btree-remove-btnum-6.9_2024-02-23' of https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux

 into xfs-6.9-mergeC

xfs: remove bc_btnum from btree cursors

From Christoph Hellwig,

This series continues the migration of btree geometry information out of
the cursor structure and into the ops structure.  This time around, we
replace the btree type enumeration (btnum) with an explicit name string
in the btree ops structure.  This enables easy creation of /any/ new
btree type without having to mess with libxfs.

Signed-off-by: default avatarDarrick J. Wong <djwong@kernel.org>
Signed-off-by: default avatarChandan Babu R <chandanbabu@kernel.org>

* tag 'btree-remove-btnum-6.9_2024-02-23' of https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux:
  xfs: remove xfs_btnum_t
  xfs: pass a 'bool is_finobt' to xfs_inobt_insert
  xfs: split xfs_inobt_init_cursor
  xfs: split xfs_inobt_insert_sprec
  xfs: remove the which variable in xchk_iallocbt
  xfs: remove the btnum argument to xfs_inobt_count_blocks
  xfs: remove xfs_inobt_cur
  xfs: split xfs_allocbt_init_cursor
  xfs: refactor the btree cursor allocation logic in xchk_ag_btcur_init
  xfs: add a sick_mask to struct xfs_btree_ops
  xfs: add a name field to struct xfs_btree_ops
  xfs: split the agf_roots and agf_levels arrays
  xfs: remove xfs_bmbt_stage_cursor
  xfs: fold xfs_bmbt_init_common into xfs_bmbt_init_cursor
  xfs: make staging file forks explicit
  xfs: make full use of xfs_btree_stage_ifakeroot in xfs_bmbt_stage_cursor
  xfs: remove xfs_rmapbt_stage_cursor
  xfs: fold xfs_rmapbt_init_common into xfs_rmapbt_init_cursor
  xfs: remove xfs_refcountbt_stage_cursor
  xfs: fold xfs_refcountbt_init_common into xfs_refcountbt_init_cursor
  xfs: remove xfs_inobt_stage_cursor
  xfs: fold xfs_inobt_init_common into xfs_inobt_init_cursor
  xfs: remove xfs_allocbt_stage_cursor
  xfs: fold xfs_allocbt_init_common into xfs_allocbt_init_cursor
  xfs: don't override bc_ops for staging btrees
  xfs: add a xfs_btree_init_ptr_from_cur
  xfs: move comment about two 2 keys per pointer in the rmap btree
parents 681cb87b ec793e69
Loading
Loading
Loading
Loading
+6 −7
Original line number Diff line number Diff line
@@ -669,14 +669,13 @@ xfs_agfblock_init(
	agf->agf_versionnum = cpu_to_be32(XFS_AGF_VERSION);
	agf->agf_seqno = cpu_to_be32(id->agno);
	agf->agf_length = cpu_to_be32(id->agsize);
	agf->agf_roots[XFS_BTNUM_BNOi] = cpu_to_be32(XFS_BNO_BLOCK(mp));
	agf->agf_roots[XFS_BTNUM_CNTi] = cpu_to_be32(XFS_CNT_BLOCK(mp));
	agf->agf_levels[XFS_BTNUM_BNOi] = cpu_to_be32(1);
	agf->agf_levels[XFS_BTNUM_CNTi] = cpu_to_be32(1);
	agf->agf_bno_root = cpu_to_be32(XFS_BNO_BLOCK(mp));
	agf->agf_cnt_root = cpu_to_be32(XFS_CNT_BLOCK(mp));
	agf->agf_bno_level = cpu_to_be32(1);
	agf->agf_cnt_level = cpu_to_be32(1);
	if (xfs_has_rmapbt(mp)) {
		agf->agf_roots[XFS_BTNUM_RMAPi] =
					cpu_to_be32(XFS_RMAP_BLOCK(mp));
		agf->agf_levels[XFS_BTNUM_RMAPi] = cpu_to_be32(1);
		agf->agf_rmap_root = cpu_to_be32(XFS_RMAP_BLOCK(mp));
		agf->agf_rmap_level = cpu_to_be32(1);
		agf->agf_rmap_blocks = cpu_to_be32(1);
	}

+5 −3
Original line number Diff line number Diff line
@@ -36,8 +36,9 @@ struct xfs_perag {
	atomic_t	pag_active_ref;	/* active reference count */
	wait_queue_head_t pag_active_wq;/* woken active_ref falls to zero */
	unsigned long	pag_opstate;
	uint8_t		pagf_levels[XFS_BTNUM_AGF];
					/* # of levels in bno & cnt btree */
	uint8_t		pagf_bno_level;	/* # of levels in bno btree */
	uint8_t		pagf_cnt_level;	/* # of levels in cnt btree */
	uint8_t		pagf_rmap_level;/* # of levels in rmap btree */
	uint32_t	pagf_flcount;	/* count of blocks in freelist */
	xfs_extlen_t	pagf_freeblks;	/* total free blocks */
	xfs_extlen_t	pagf_longest;	/* longest free space */
@@ -86,7 +87,8 @@ struct xfs_perag {
	 * Alternate btree heights so that online repair won't trip the write
	 * verifiers while rebuilding the AG btrees.
	 */
	uint8_t		pagf_repair_levels[XFS_BTNUM_AGF];
	uint8_t		pagf_repair_bno_level;
	uint8_t		pagf_repair_cnt_level;
	uint8_t		pagf_repair_refcount_level;
#endif

+43 −56
Original line number Diff line number Diff line
@@ -273,9 +273,8 @@ xfs_alloc_complain_bad_rec(
	struct xfs_mount		*mp = cur->bc_mp;

	xfs_warn(mp,
		"%s Freespace BTree record corruption in AG %d detected at %pS!",
		cur->bc_btnum == XFS_BTNUM_BNO ? "Block" : "Size",
		cur->bc_ag.pag->pag_agno, fa);
		"%sbt record corruption in AG %d detected at %pS!",
		cur->bc_ops->name, cur->bc_ag.pag->pag_agno, fa);
	xfs_warn(mp,
		"start block 0x%x block count 0x%x", irec->ar_startblock,
		irec->ar_blockcount);
@@ -863,8 +862,8 @@ xfs_alloc_cur_setup(
	 * attempt a small allocation.
	 */
	if (!acur->cnt)
		acur->cnt = xfs_allocbt_init_cursor(args->mp, args->tp,
					args->agbp, args->pag, XFS_BTNUM_CNT);
		acur->cnt = xfs_cntbt_init_cursor(args->mp, args->tp,
					args->agbp, args->pag);
	error = xfs_alloc_lookup_ge(acur->cnt, 0, args->maxlen, &i);
	if (error)
		return error;
@@ -873,11 +872,11 @@ xfs_alloc_cur_setup(
	 * Allocate the bnobt left and right search cursors.
	 */
	if (!acur->bnolt)
		acur->bnolt = xfs_allocbt_init_cursor(args->mp, args->tp,
					args->agbp, args->pag, XFS_BTNUM_BNO);
		acur->bnolt = xfs_bnobt_init_cursor(args->mp, args->tp,
					args->agbp, args->pag);
	if (!acur->bnogt)
		acur->bnogt = xfs_allocbt_init_cursor(args->mp, args->tp,
					args->agbp, args->pag, XFS_BTNUM_BNO);
		acur->bnogt = xfs_bnobt_init_cursor(args->mp, args->tp,
					args->agbp, args->pag);
	return i == 1 ? 0 : -ENOSPC;
}

@@ -919,7 +918,7 @@ xfs_alloc_cur_check(
	bool			busy;
	unsigned		busy_gen = 0;
	bool			deactivate = false;
	bool			isbnobt = cur->bc_btnum == XFS_BTNUM_BNO;
	bool			isbnobt = xfs_btree_is_bno(cur->bc_ops);

	*new = 0;

@@ -996,8 +995,7 @@ xfs_alloc_cur_check(
out:
	if (deactivate)
		cur->bc_flags &= ~XFS_BTREE_ALLOCBT_ACTIVE;
	trace_xfs_alloc_cur_check(args->mp, cur->bc_btnum, bno, len, diff,
				  *new);
	trace_xfs_alloc_cur_check(cur, bno, len, diff, *new);
	return 0;
}

@@ -1236,8 +1234,8 @@ xfs_alloc_ag_vextent_exact(
	/*
	 * Allocate/initialize a cursor for the by-number freespace btree.
	 */
	bno_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp,
					  args->pag, XFS_BTNUM_BNO);
	bno_cur = xfs_bnobt_init_cursor(args->mp, args->tp, args->agbp,
					  args->pag);

	/*
	 * Lookup bno and minlen in the btree (minlen is irrelevant, really).
@@ -1297,8 +1295,8 @@ xfs_alloc_ag_vextent_exact(
	 * We are allocating agbno for args->len
	 * Allocate/initialize a cursor for the by-size btree.
	 */
	cnt_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp,
					args->pag, XFS_BTNUM_CNT);
	cnt_cur = xfs_cntbt_init_cursor(args->mp, args->tp, args->agbp,
					args->pag);
	ASSERT(args->agbno + args->len <= be32_to_cpu(agf->agf_length));
	error = xfs_alloc_fixup_trees(cnt_cur, bno_cur, fbno, flen, args->agbno,
				      args->len, XFSA_FIXUP_BNO_OK);
@@ -1712,8 +1710,8 @@ xfs_alloc_ag_vextent_size(
	/*
	 * Allocate and initialize a cursor for the by-size btree.
	 */
	cnt_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp,
					args->pag, XFS_BTNUM_CNT);
	cnt_cur = xfs_cntbt_init_cursor(args->mp, args->tp, args->agbp,
					args->pag);
	bno_cur = NULL;

	/*
@@ -1898,8 +1896,8 @@ xfs_alloc_ag_vextent_size(
	/*
	 * Allocate and initialize a cursor for the by-block tree.
	 */
	bno_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp,
					args->pag, XFS_BTNUM_BNO);
	bno_cur = xfs_bnobt_init_cursor(args->mp, args->tp, args->agbp,
					args->pag);
	if ((error = xfs_alloc_fixup_trees(cnt_cur, bno_cur, fbno, flen,
			rbno, rlen, XFSA_FIXUP_CNT_OK)))
		goto error0;
@@ -1973,7 +1971,7 @@ xfs_free_ag_extent(
	/*
	 * Allocate and initialize a cursor for the by-block btree.
	 */
	bno_cur = xfs_allocbt_init_cursor(mp, tp, agbp, pag, XFS_BTNUM_BNO);
	bno_cur = xfs_bnobt_init_cursor(mp, tp, agbp, pag);
	/*
	 * Look for a neighboring block on the left (lower block numbers)
	 * that is contiguous with this space.
@@ -2047,7 +2045,7 @@ xfs_free_ag_extent(
	/*
	 * Now allocate and initialize a cursor for the by-size tree.
	 */
	cnt_cur = xfs_allocbt_init_cursor(mp, tp, agbp, pag, XFS_BTNUM_CNT);
	cnt_cur = xfs_cntbt_init_cursor(mp, tp, agbp, pag);
	/*
	 * Have both left and right contiguous neighbors.
	 * Merge all three into a single free block.
@@ -2335,8 +2333,9 @@ xfs_alloc_min_freelist(
	struct xfs_perag	*pag)
{
	/* AG btrees have at least 1 level. */
	static const uint8_t	fake_levels[XFS_BTNUM_AGF] = {1, 1, 1};
	const uint8_t		*levels = pag ? pag->pagf_levels : fake_levels;
	const unsigned int	bno_level = pag ? pag->pagf_bno_level : 1;
	const unsigned int	cnt_level = pag ? pag->pagf_cnt_level : 1;
	const unsigned int	rmap_level = pag ? pag->pagf_rmap_level : 1;
	unsigned int		min_free;

	ASSERT(mp->m_alloc_maxlevels > 0);
@@ -2363,16 +2362,12 @@ xfs_alloc_min_freelist(
	 */

	/* space needed by-bno freespace btree */
	min_free = min_t(unsigned int, levels[XFS_BTNUM_BNOi] + 1,
				       mp->m_alloc_maxlevels) * 2 - 2;
	min_free = min(bno_level + 1, mp->m_alloc_maxlevels) * 2 - 2;
	/* space needed by-size freespace btree */
	min_free += min_t(unsigned int, levels[XFS_BTNUM_CNTi] + 1,
				       mp->m_alloc_maxlevels) * 2 - 2;
	min_free += min(cnt_level + 1, mp->m_alloc_maxlevels) * 2 - 2;
	/* space needed reverse mapping used space btree */
	if (xfs_has_rmapbt(mp))
		min_free += min_t(unsigned int, levels[XFS_BTNUM_RMAPi] + 1,
						mp->m_rmap_maxlevels) * 2 - 2;

		min_free += min(rmap_level + 1, mp->m_rmap_maxlevels) * 2 - 2;
	return min_free;
}

@@ -2759,8 +2754,8 @@ xfs_exact_minlen_extent_available(
	xfs_extlen_t		flen;
	int			error = 0;

	cnt_cur = xfs_allocbt_init_cursor(args->mp, args->tp, agbp,
					args->pag, XFS_BTNUM_CNT);
	cnt_cur = xfs_cntbt_init_cursor(args->mp, args->tp, agbp,
					args->pag);
	error = xfs_alloc_lookup_ge(cnt_cur, 0, args->minlen, stat);
	if (error)
		goto out;
@@ -3056,8 +3051,8 @@ xfs_alloc_log_agf(
		offsetof(xfs_agf_t, agf_versionnum),
		offsetof(xfs_agf_t, agf_seqno),
		offsetof(xfs_agf_t, agf_length),
		offsetof(xfs_agf_t, agf_roots[0]),
		offsetof(xfs_agf_t, agf_levels[0]),
		offsetof(xfs_agf_t, agf_bno_root),   /* also cnt/rmap root */
		offsetof(xfs_agf_t, agf_bno_level),  /* also cnt/rmap levels */
		offsetof(xfs_agf_t, agf_flfirst),
		offsetof(xfs_agf_t, agf_fllast),
		offsetof(xfs_agf_t, agf_flcount),
@@ -3236,12 +3231,10 @@ xfs_agf_verify(
	    be32_to_cpu(agf->agf_freeblks) > agf_length)
		return __this_address;

	if (be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]) < 1 ||
	    be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]) < 1 ||
	    be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]) >
						mp->m_alloc_maxlevels ||
	    be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]) >
						mp->m_alloc_maxlevels)
	if (be32_to_cpu(agf->agf_bno_level) < 1 ||
	    be32_to_cpu(agf->agf_cnt_level) < 1 ||
	    be32_to_cpu(agf->agf_bno_level) > mp->m_alloc_maxlevels ||
	    be32_to_cpu(agf->agf_cnt_level) > mp->m_alloc_maxlevels)
		return __this_address;

	if (xfs_has_lazysbcount(mp) &&
@@ -3252,9 +3245,8 @@ xfs_agf_verify(
		if (be32_to_cpu(agf->agf_rmap_blocks) > agf_length)
			return __this_address;

		if (be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]) < 1 ||
		    be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]) >
							mp->m_rmap_maxlevels)
		if (be32_to_cpu(agf->agf_rmap_level) < 1 ||
		    be32_to_cpu(agf->agf_rmap_level) > mp->m_rmap_maxlevels)
			return __this_address;
	}

@@ -3380,12 +3372,9 @@ xfs_alloc_read_agf(
		pag->pagf_btreeblks = be32_to_cpu(agf->agf_btreeblks);
		pag->pagf_flcount = be32_to_cpu(agf->agf_flcount);
		pag->pagf_longest = be32_to_cpu(agf->agf_longest);
		pag->pagf_levels[XFS_BTNUM_BNOi] =
			be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNOi]);
		pag->pagf_levels[XFS_BTNUM_CNTi] =
			be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi]);
		pag->pagf_levels[XFS_BTNUM_RMAPi] =
			be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAPi]);
		pag->pagf_bno_level = be32_to_cpu(agf->agf_bno_level);
		pag->pagf_cnt_level = be32_to_cpu(agf->agf_cnt_level);
		pag->pagf_rmap_level = be32_to_cpu(agf->agf_rmap_level);
		pag->pagf_refcount_level = be32_to_cpu(agf->agf_refcount_level);
		if (xfs_agfl_needs_reset(pag->pag_mount, agf))
			set_bit(XFS_AGSTATE_AGFL_NEEDS_RESET, &pag->pag_opstate);
@@ -3414,10 +3403,8 @@ xfs_alloc_read_agf(
		ASSERT(pag->pagf_btreeblks == be32_to_cpu(agf->agf_btreeblks));
		ASSERT(pag->pagf_flcount == be32_to_cpu(agf->agf_flcount));
		ASSERT(pag->pagf_longest == be32_to_cpu(agf->agf_longest));
		ASSERT(pag->pagf_levels[XFS_BTNUM_BNOi] ==
		       be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNOi]));
		ASSERT(pag->pagf_levels[XFS_BTNUM_CNTi] ==
		       be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNTi]));
		ASSERT(pag->pagf_bno_level == be32_to_cpu(agf->agf_bno_level));
		ASSERT(pag->pagf_cnt_level == be32_to_cpu(agf->agf_cnt_level));
	}
#endif
	if (agfbpp)
@@ -4039,7 +4026,7 @@ xfs_alloc_query_range(
	union xfs_btree_irec			high_brec = { .a = *high_rec };
	struct xfs_alloc_query_range_info	query = { .priv = priv, .fn = fn };

	ASSERT(cur->bc_btnum == XFS_BTNUM_BNO);
	ASSERT(xfs_btree_is_bno(cur->bc_ops));
	return xfs_btree_query_range(cur, &low_brec, &high_brec,
			xfs_alloc_query_range_helper, &query);
}
@@ -4053,7 +4040,7 @@ xfs_alloc_query_all(
{
	struct xfs_alloc_query_range_info	query;

	ASSERT(cur->bc_btnum == XFS_BTNUM_BNO);
	ASSERT(xfs_btree_is_bno(cur->bc_ops));
	query.priv = priv;
	query.fn = fn;
	return xfs_btree_query_all(cur, xfs_alloc_query_range_helper, &query);
+87 −69
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
#include "xfs_alloc.h"
#include "xfs_extent_busy.h"
#include "xfs_error.h"
#include "xfs_health.h"
#include "xfs_trace.h"
#include "xfs_trans.h"
#include "xfs_ag.h"
@@ -23,13 +24,22 @@
static struct kmem_cache	*xfs_allocbt_cur_cache;

STATIC struct xfs_btree_cur *
xfs_allocbt_dup_cursor(
xfs_bnobt_dup_cursor(
	struct xfs_btree_cur	*cur)
{
	return xfs_allocbt_init_cursor(cur->bc_mp, cur->bc_tp,
			cur->bc_ag.agbp, cur->bc_ag.pag, cur->bc_btnum);
	return xfs_bnobt_init_cursor(cur->bc_mp, cur->bc_tp, cur->bc_ag.agbp,
			cur->bc_ag.pag);
}

STATIC struct xfs_btree_cur *
xfs_cntbt_dup_cursor(
	struct xfs_btree_cur	*cur)
{
	return xfs_cntbt_init_cursor(cur->bc_mp, cur->bc_tp, cur->bc_ag.agbp,
			cur->bc_ag.pag);
}


STATIC void
xfs_allocbt_set_root(
	struct xfs_btree_cur		*cur,
@@ -38,13 +48,18 @@ xfs_allocbt_set_root(
{
	struct xfs_buf		*agbp = cur->bc_ag.agbp;
	struct xfs_agf		*agf = agbp->b_addr;
	int			btnum = cur->bc_btnum;

	ASSERT(ptr->s != 0);

	agf->agf_roots[btnum] = ptr->s;
	be32_add_cpu(&agf->agf_levels[btnum], inc);
	cur->bc_ag.pag->pagf_levels[btnum] += inc;
	if (xfs_btree_is_bno(cur->bc_ops)) {
		agf->agf_bno_root = ptr->s;
		be32_add_cpu(&agf->agf_bno_level, inc);
		cur->bc_ag.pag->pagf_bno_level += inc;
	} else {
		agf->agf_cnt_root = ptr->s;
		be32_add_cpu(&agf->agf_cnt_level, inc);
		cur->bc_ag.pag->pagf_cnt_level += inc;
	}

	xfs_alloc_log_agf(cur->bc_tp, agbp, XFS_AGF_ROOTS | XFS_AGF_LEVELS);
}
@@ -116,7 +131,7 @@ xfs_allocbt_update_lastrec(
	__be32			len;
	int			numrecs;

	ASSERT(cur->bc_btnum == XFS_BTNUM_CNT);
	ASSERT(!xfs_btree_is_bno(cur->bc_ops));

	switch (reason) {
	case LASTREC_UPDATE:
@@ -226,7 +241,10 @@ xfs_allocbt_init_ptr_from_cur(

	ASSERT(cur->bc_ag.pag->pag_agno == be32_to_cpu(agf->agf_seqno));

	ptr->s = agf->agf_roots[cur->bc_btnum];
	if (xfs_btree_is_bno(cur->bc_ops))
		ptr->s = agf->agf_bno_root;
	else
		ptr->s = agf->agf_cnt_root;
}

STATIC int64_t
@@ -299,7 +317,6 @@ xfs_allocbt_verify(
	struct xfs_perag	*pag = bp->b_pag;
	xfs_failaddr_t		fa;
	unsigned int		level;
	xfs_btnum_t		btnum = XFS_BTNUM_BNOi;

	if (!xfs_verify_magic(bp, block->bb_magic))
		return __this_address;
@@ -320,21 +337,27 @@ xfs_allocbt_verify(
	 * against.
	 */
	level = be16_to_cpu(block->bb_level);
	if (bp->b_ops->magic[0] == cpu_to_be32(XFS_ABTC_MAGIC))
		btnum = XFS_BTNUM_CNTi;
	if (pag && xfs_perag_initialised_agf(pag)) {
		unsigned int	maxlevel = pag->pagf_levels[btnum];
		unsigned int	maxlevel, repair_maxlevel = 0;

#ifdef CONFIG_XFS_ONLINE_REPAIR
		/*
		 * Online repair could be rewriting the free space btrees, so
		 * we'll validate against the larger of either tree while this
		 * is going on.
		 */
		maxlevel = max_t(unsigned int, maxlevel,
				 pag->pagf_repair_levels[btnum]);
		if (bp->b_ops->magic[0] == cpu_to_be32(XFS_ABTC_MAGIC)) {
			maxlevel = pag->pagf_cnt_level;
#ifdef CONFIG_XFS_ONLINE_REPAIR
			repair_maxlevel = pag->pagf_repair_cnt_level;
#endif
		} else {
			maxlevel = pag->pagf_bno_level;
#ifdef CONFIG_XFS_ONLINE_REPAIR
			repair_maxlevel = pag->pagf_repair_bno_level;
#endif
		if (level >= maxlevel)
		}

		if (level >= max(maxlevel, repair_maxlevel))
			return __this_address;
	} else if (level >= mp->m_alloc_maxlevels)
		return __this_address;
@@ -455,6 +478,7 @@ xfs_allocbt_keys_contiguous(
}

const struct xfs_btree_ops xfs_bnobt_ops = {
	.name			= "bno",
	.type			= XFS_BTREE_TYPE_AG,

	.rec_len		= sizeof(xfs_alloc_rec_t),
@@ -463,8 +487,9 @@ const struct xfs_btree_ops xfs_bnobt_ops = {

	.lru_refs		= XFS_ALLOC_BTREE_REF,
	.statoff		= XFS_STATS_CALC_INDEX(xs_abtb_2),
	.sick_mask		= XFS_SICK_AG_BNOBT,

	.dup_cursor		= xfs_allocbt_dup_cursor,
	.dup_cursor		= xfs_bnobt_dup_cursor,
	.set_root		= xfs_allocbt_set_root,
	.alloc_block		= xfs_allocbt_alloc_block,
	.free_block		= xfs_allocbt_free_block,
@@ -484,6 +509,7 @@ const struct xfs_btree_ops xfs_bnobt_ops = {
};

const struct xfs_btree_ops xfs_cntbt_ops = {
	.name			= "cnt",
	.type			= XFS_BTREE_TYPE_AG,
	.geom_flags		= XFS_BTGEO_LASTREC_UPDATE,

@@ -493,8 +519,9 @@ const struct xfs_btree_ops xfs_cntbt_ops = {

	.lru_refs		= XFS_ALLOC_BTREE_REF,
	.statoff		= XFS_STATS_CALC_INDEX(xs_abtc_2),
	.sick_mask		= XFS_SICK_AG_CNTBT,

	.dup_cursor		= xfs_allocbt_dup_cursor,
	.dup_cursor		= xfs_cntbt_dup_cursor,
	.set_root		= xfs_allocbt_set_root,
	.alloc_block		= xfs_allocbt_alloc_block,
	.free_block		= xfs_allocbt_free_block,
@@ -513,65 +540,55 @@ const struct xfs_btree_ops xfs_cntbt_ops = {
	.keys_contiguous	= NULL, /* not needed right now */
};

/* Allocate most of a new allocation btree cursor. */
STATIC struct xfs_btree_cur *
xfs_allocbt_init_common(
/*
 * Allocate a new bnobt cursor.
 *
 * For staging cursors tp and agbp are NULL.
 */
struct xfs_btree_cur *
xfs_bnobt_init_cursor(
	struct xfs_mount	*mp,
	struct xfs_trans	*tp,
	struct xfs_perag	*pag,
	xfs_btnum_t		btnum)
	struct xfs_buf		*agbp,
	struct xfs_perag	*pag)
{
	const struct xfs_btree_ops *ops = &xfs_bnobt_ops;
	struct xfs_btree_cur	*cur;

	ASSERT(btnum == XFS_BTNUM_BNO || btnum == XFS_BTNUM_CNT);

	if (btnum == XFS_BTNUM_CNT)
		ops = &xfs_cntbt_ops;

	cur = xfs_btree_alloc_cursor(mp, tp, btnum, ops, mp->m_alloc_maxlevels,
			xfs_allocbt_cur_cache);
	cur = xfs_btree_alloc_cursor(mp, tp, &xfs_bnobt_ops,
			mp->m_alloc_maxlevels, xfs_allocbt_cur_cache);
	cur->bc_ag.pag = xfs_perag_hold(pag);
	cur->bc_ag.agbp = agbp;
	if (agbp) {
		struct xfs_agf		*agf = agbp->b_addr;

		cur->bc_nlevels = be32_to_cpu(agf->agf_bno_level);
	}
	return cur;
}

/*
 * Allocate a new allocation btree cursor.
 * Allocate a new cntbt cursor.
 *
 * For staging cursors tp and agbp are NULL.
 */
struct xfs_btree_cur *			/* new alloc btree cursor */
xfs_allocbt_init_cursor(
	struct xfs_mount	*mp,		/* file system mount point */
	struct xfs_trans	*tp,		/* transaction pointer */
	struct xfs_buf		*agbp,		/* buffer for agf structure */
	struct xfs_perag	*pag,
	xfs_btnum_t		btnum)		/* btree identifier */
struct xfs_btree_cur *
xfs_cntbt_init_cursor(
	struct xfs_mount	*mp,
	struct xfs_trans	*tp,
	struct xfs_buf		*agbp,
	struct xfs_perag	*pag)
{
	struct xfs_agf		*agf = agbp->b_addr;
	struct xfs_btree_cur	*cur;

	cur = xfs_allocbt_init_common(mp, tp, pag, btnum);
	if (btnum == XFS_BTNUM_CNT)
		cur->bc_nlevels = be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]);
	else
		cur->bc_nlevels = be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]);

	cur = xfs_btree_alloc_cursor(mp, tp, &xfs_cntbt_ops,
			mp->m_alloc_maxlevels, xfs_allocbt_cur_cache);
	cur->bc_ag.pag = xfs_perag_hold(pag);
	cur->bc_ag.agbp = agbp;
	if (agbp) {
		struct xfs_agf		*agf = agbp->b_addr;

	return cur;
		cur->bc_nlevels = be32_to_cpu(agf->agf_cnt_level);
	}

/* Create a free space btree cursor with a fake root for staging. */
struct xfs_btree_cur *
xfs_allocbt_stage_cursor(
	struct xfs_mount	*mp,
	struct xbtree_afakeroot	*afake,
	struct xfs_perag	*pag,
	xfs_btnum_t		btnum)
{
	struct xfs_btree_cur	*cur;

	cur = xfs_allocbt_init_common(mp, NULL, pag, btnum);
	xfs_btree_stage_afakeroot(cur, afake);
	return cur;
}

@@ -590,15 +607,16 @@ xfs_allocbt_commit_staged_btree(

	ASSERT(cur->bc_flags & XFS_BTREE_STAGING);

	agf->agf_roots[cur->bc_btnum] = cpu_to_be32(afake->af_root);
	agf->agf_levels[cur->bc_btnum] = cpu_to_be32(afake->af_levels);
	xfs_alloc_log_agf(tp, agbp, XFS_AGF_ROOTS | XFS_AGF_LEVELS);

	if (cur->bc_btnum == XFS_BTNUM_BNO) {
		xfs_btree_commit_afakeroot(cur, tp, agbp, &xfs_bnobt_ops);
	if (xfs_btree_is_bno(cur->bc_ops)) {
		agf->agf_bno_root = cpu_to_be32(afake->af_root);
		agf->agf_bno_level = cpu_to_be32(afake->af_levels);
	} else {
		xfs_btree_commit_afakeroot(cur, tp, agbp, &xfs_cntbt_ops);
		agf->agf_cnt_root = cpu_to_be32(afake->af_root);
		agf->agf_cnt_level = cpu_to_be32(afake->af_levels);
	}
	xfs_alloc_log_agf(tp, agbp, XFS_AGF_ROOTS | XFS_AGF_LEVELS);

	xfs_btree_commit_afakeroot(cur, tp, agbp);
}

/* Calculate number of records in an alloc btree block. */
+5 −5
Original line number Diff line number Diff line
@@ -47,12 +47,12 @@ struct xbtree_afakeroot;
		 (maxrecs) * sizeof(xfs_alloc_key_t) + \
		 ((index) - 1) * sizeof(xfs_alloc_ptr_t)))

extern struct xfs_btree_cur *xfs_allocbt_init_cursor(struct xfs_mount *mp,
struct xfs_btree_cur *xfs_bnobt_init_cursor(struct xfs_mount *mp,
		struct xfs_trans *tp, struct xfs_buf *bp,
		struct xfs_perag *pag, xfs_btnum_t btnum);
struct xfs_btree_cur *xfs_allocbt_stage_cursor(struct xfs_mount *mp,
		struct xbtree_afakeroot *afake, struct xfs_perag *pag,
		xfs_btnum_t btnum);
		struct xfs_perag *pag);
struct xfs_btree_cur *xfs_cntbt_init_cursor(struct xfs_mount *mp,
		struct xfs_trans *tp, struct xfs_buf *bp,
		struct xfs_perag *pag);
extern int xfs_allocbt_maxrecs(struct xfs_mount *, int, int);
extern xfs_extlen_t xfs_allocbt_calc_size(struct xfs_mount *mp,
		unsigned long long len);
Loading