linux-xfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Chandan Babu R <chandan.babu@oracle.com>
To: "Darrick J. Wong" <djwong@kernel.org>
Cc: chandanrlinux@gmail.com, linux-xfs@vger.kernel.org
Subject: Re: [PATCH 07/14] xfs: support dynamic btree cursor heights
Date: Mon, 20 Sep 2021 15:25:00 +0530	[thread overview]
Message-ID: <87k0jb7erv.fsf@debian-BULLSEYE-live-builder-AMD64> (raw)
In-Reply-To: <163192858823.416199.17720760425094444911.stgit@magnolia>

On 18 Sep 2021 at 06:59, Darrick J. Wong wrote:
> From: Darrick J. Wong <djwong@kernel.org>
>
> Split out the btree level information into a separate struct and put it
> at the end of the cursor structure as a VLA.  The realtime rmap btree
> (which is rooted in an inode) will require the ability to support many
> more levels than a per-AG btree cursor, which means that we're going to
> create two btree cursor caches to conserve memory for the more common
> case.
>

Looks good.

Reviewed-by: Chandan Babu R <chandan.babu@oracle.com>

> Signed-off-by: Darrick J. Wong <djwong@kernel.org>
> ---
>  fs/xfs/libxfs/xfs_alloc.c |    6 +-
>  fs/xfs/libxfs/xfs_bmap.c  |   10 +--
>  fs/xfs/libxfs/xfs_btree.c |  154 +++++++++++++++++++++++----------------------
>  fs/xfs/libxfs/xfs_btree.h |   28 ++++++--
>  fs/xfs/scrub/bitmap.c     |   16 ++---
>  fs/xfs/scrub/bmap.c       |    2 -
>  fs/xfs/scrub/btree.c      |   40 ++++++------
>  fs/xfs/scrub/trace.c      |    7 +-
>  fs/xfs/scrub/trace.h      |   10 +--
>  fs/xfs/xfs_super.c        |    2 -
>  fs/xfs/xfs_trace.h        |    2 -
>  11 files changed, 147 insertions(+), 130 deletions(-)
>
>
> diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c
> index 35fb1dd3be95..55c5adc9b54e 100644
> --- a/fs/xfs/libxfs/xfs_alloc.c
> +++ b/fs/xfs/libxfs/xfs_alloc.c
> @@ -488,8 +488,8 @@ xfs_alloc_fixup_trees(
>  		struct xfs_btree_block	*bnoblock;
>  		struct xfs_btree_block	*cntblock;
>  
> -		bnoblock = XFS_BUF_TO_BLOCK(bno_cur->bc_bufs[0]);
> -		cntblock = XFS_BUF_TO_BLOCK(cnt_cur->bc_bufs[0]);
> +		bnoblock = XFS_BUF_TO_BLOCK(bno_cur->bc_levels[0].bp);
> +		cntblock = XFS_BUF_TO_BLOCK(cnt_cur->bc_levels[0].bp);
>  
>  		if (XFS_IS_CORRUPT(mp,
>  				   bnoblock->bb_numrecs !=
> @@ -1512,7 +1512,7 @@ xfs_alloc_ag_vextent_lastblock(
>  	 * than minlen.
>  	 */
>  	if (*len || args->alignment > 1) {
> -		acur->cnt->bc_ptrs[0] = 1;
> +		acur->cnt->bc_levels[0].ptr = 1;
>  		do {
>  			error = xfs_alloc_get_rec(acur->cnt, bno, len, &i);
>  			if (error)
> diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
> index 499c977cbf56..644b956301b6 100644
> --- a/fs/xfs/libxfs/xfs_bmap.c
> +++ b/fs/xfs/libxfs/xfs_bmap.c
> @@ -240,10 +240,10 @@ xfs_bmap_get_bp(
>  		return NULL;
>  
>  	for (i = 0; i < XFS_BTREE_MAXLEVELS; i++) {
> -		if (!cur->bc_bufs[i])
> +		if (!cur->bc_levels[i].bp)
>  			break;
> -		if (xfs_buf_daddr(cur->bc_bufs[i]) == bno)
> -			return cur->bc_bufs[i];
> +		if (xfs_buf_daddr(cur->bc_levels[i].bp) == bno)
> +			return cur->bc_levels[i].bp;
>  	}
>  
>  	/* Chase down all the log items to see if the bp is there */
> @@ -629,8 +629,8 @@ xfs_bmap_btree_to_extents(
>  	ip->i_nblocks--;
>  	xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, -1L);
>  	xfs_trans_binval(tp, cbp);
> -	if (cur->bc_bufs[0] == cbp)
> -		cur->bc_bufs[0] = NULL;
> +	if (cur->bc_levels[0].bp == cbp)
> +		cur->bc_levels[0].bp = NULL;
>  	xfs_iroot_realloc(ip, -1, whichfork);
>  	ASSERT(ifp->if_broot == NULL);
>  	ifp->if_format = XFS_DINODE_FMT_EXTENTS;
> diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c
> index bc4e49f0456a..93fb50516bc2 100644
> --- a/fs/xfs/libxfs/xfs_btree.c
> +++ b/fs/xfs/libxfs/xfs_btree.c
> @@ -367,8 +367,8 @@ xfs_btree_del_cursor(
>  	 * way we won't have initialized all the entries down to 0.
>  	 */
>  	for (i = 0; i < cur->bc_nlevels; i++) {
> -		if (cur->bc_bufs[i])
> -			xfs_trans_brelse(cur->bc_tp, cur->bc_bufs[i]);
> +		if (cur->bc_levels[i].bp)
> +			xfs_trans_brelse(cur->bc_tp, cur->bc_levels[i].bp);
>  		else if (!error)
>  			break;
>  	}
> @@ -415,9 +415,9 @@ xfs_btree_dup_cursor(
>  	 * For each level current, re-get the buffer and copy the ptr value.
>  	 */
>  	for (i = 0; i < new->bc_nlevels; i++) {
> -		new->bc_ptrs[i] = cur->bc_ptrs[i];
> -		new->bc_ra[i] = cur->bc_ra[i];
> -		bp = cur->bc_bufs[i];
> +		new->bc_levels[i].ptr = cur->bc_levels[i].ptr;
> +		new->bc_levels[i].ra = cur->bc_levels[i].ra;
> +		bp = cur->bc_levels[i].bp;
>  		if (bp) {
>  			error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
>  						   xfs_buf_daddr(bp), mp->m_bsize,
> @@ -429,7 +429,7 @@ xfs_btree_dup_cursor(
>  				return error;
>  			}
>  		}
> -		new->bc_bufs[i] = bp;
> +		new->bc_levels[i].bp = bp;
>  	}
>  	*ncur = new;
>  	return 0;
> @@ -681,7 +681,7 @@ xfs_btree_get_block(
>  		return xfs_btree_get_iroot(cur);
>  	}
>  
> -	*bpp = cur->bc_bufs[level];
> +	*bpp = cur->bc_levels[level].bp;
>  	return XFS_BUF_TO_BLOCK(*bpp);
>  }
>  
> @@ -711,7 +711,7 @@ xfs_btree_firstrec(
>  	/*
>  	 * Set the ptr value to 1, that's the first record/key.
>  	 */
> -	cur->bc_ptrs[level] = 1;
> +	cur->bc_levels[level].ptr = 1;
>  	return 1;
>  }
>  
> @@ -741,7 +741,7 @@ xfs_btree_lastrec(
>  	/*
>  	 * Set the ptr value to numrecs, that's the last record/key.
>  	 */
> -	cur->bc_ptrs[level] = be16_to_cpu(block->bb_numrecs);
> +	cur->bc_levels[level].ptr = be16_to_cpu(block->bb_numrecs);
>  	return 1;
>  }
>  
> @@ -922,11 +922,11 @@ xfs_btree_readahead(
>  	    (lev == cur->bc_nlevels - 1))
>  		return 0;
>  
> -	if ((cur->bc_ra[lev] | lr) == cur->bc_ra[lev])
> +	if ((cur->bc_levels[lev].ra | lr) == cur->bc_levels[lev].ra)
>  		return 0;
>  
> -	cur->bc_ra[lev] |= lr;
> -	block = XFS_BUF_TO_BLOCK(cur->bc_bufs[lev]);
> +	cur->bc_levels[lev].ra |= lr;
> +	block = XFS_BUF_TO_BLOCK(cur->bc_levels[lev].bp);
>  
>  	if (cur->bc_flags & XFS_BTREE_LONG_PTRS)
>  		return xfs_btree_readahead_lblock(cur, lr, block);
> @@ -991,22 +991,22 @@ xfs_btree_setbuf(
>  {
>  	struct xfs_btree_block	*b;	/* btree block */
>  
> -	if (cur->bc_bufs[lev])
> -		xfs_trans_brelse(cur->bc_tp, cur->bc_bufs[lev]);
> -	cur->bc_bufs[lev] = bp;
> -	cur->bc_ra[lev] = 0;
> +	if (cur->bc_levels[lev].bp)
> +		xfs_trans_brelse(cur->bc_tp, cur->bc_levels[lev].bp);
> +	cur->bc_levels[lev].bp = bp;
> +	cur->bc_levels[lev].ra = 0;
>  
>  	b = XFS_BUF_TO_BLOCK(bp);
>  	if (cur->bc_flags & XFS_BTREE_LONG_PTRS) {
>  		if (b->bb_u.l.bb_leftsib == cpu_to_be64(NULLFSBLOCK))
> -			cur->bc_ra[lev] |= XFS_BTCUR_LEFTRA;
> +			cur->bc_levels[lev].ra |= XFS_BTCUR_LEFTRA;
>  		if (b->bb_u.l.bb_rightsib == cpu_to_be64(NULLFSBLOCK))
> -			cur->bc_ra[lev] |= XFS_BTCUR_RIGHTRA;
> +			cur->bc_levels[lev].ra |= XFS_BTCUR_RIGHTRA;
>  	} else {
>  		if (b->bb_u.s.bb_leftsib == cpu_to_be32(NULLAGBLOCK))
> -			cur->bc_ra[lev] |= XFS_BTCUR_LEFTRA;
> +			cur->bc_levels[lev].ra |= XFS_BTCUR_LEFTRA;
>  		if (b->bb_u.s.bb_rightsib == cpu_to_be32(NULLAGBLOCK))
> -			cur->bc_ra[lev] |= XFS_BTCUR_RIGHTRA;
> +			cur->bc_levels[lev].ra |= XFS_BTCUR_RIGHTRA;
>  	}
>  }
>  
> @@ -1548,7 +1548,7 @@ xfs_btree_increment(
>  #endif
>  
>  	/* We're done if we remain in the block after the increment. */
> -	if (++cur->bc_ptrs[level] <= xfs_btree_get_numrecs(block))
> +	if (++cur->bc_levels[level].ptr <= xfs_btree_get_numrecs(block))
>  		goto out1;
>  
>  	/* Fail if we just went off the right edge of the tree. */
> @@ -1571,7 +1571,7 @@ xfs_btree_increment(
>  			goto error0;
>  #endif
>  
> -		if (++cur->bc_ptrs[lev] <= xfs_btree_get_numrecs(block))
> +		if (++cur->bc_levels[lev].ptr <= xfs_btree_get_numrecs(block))
>  			break;
>  
>  		/* Read-ahead the right block for the next loop. */
> @@ -1598,14 +1598,14 @@ xfs_btree_increment(
>  	for (block = xfs_btree_get_block(cur, lev, &bp); lev > level; ) {
>  		union xfs_btree_ptr	*ptrp;
>  
> -		ptrp = xfs_btree_ptr_addr(cur, cur->bc_ptrs[lev], block);
> +		ptrp = xfs_btree_ptr_addr(cur, cur->bc_levels[lev].ptr, block);
>  		--lev;
>  		error = xfs_btree_read_buf_block(cur, ptrp, 0, &block, &bp);
>  		if (error)
>  			goto error0;
>  
>  		xfs_btree_setbuf(cur, lev, bp);
> -		cur->bc_ptrs[lev] = 1;
> +		cur->bc_levels[lev].ptr = 1;
>  	}
>  out1:
>  	*stat = 1;
> @@ -1641,7 +1641,7 @@ xfs_btree_decrement(
>  	xfs_btree_readahead(cur, level, XFS_BTCUR_LEFTRA);
>  
>  	/* We're done if we remain in the block after the decrement. */
> -	if (--cur->bc_ptrs[level] > 0)
> +	if (--cur->bc_levels[level].ptr > 0)
>  		goto out1;
>  
>  	/* Get a pointer to the btree block. */
> @@ -1665,7 +1665,7 @@ xfs_btree_decrement(
>  	 * Stop when we don't go off the left edge of a block.
>  	 */
>  	for (lev = level + 1; lev < cur->bc_nlevels; lev++) {
> -		if (--cur->bc_ptrs[lev] > 0)
> +		if (--cur->bc_levels[lev].ptr > 0)
>  			break;
>  		/* Read-ahead the left block for the next loop. */
>  		xfs_btree_readahead(cur, lev, XFS_BTCUR_LEFTRA);
> @@ -1691,13 +1691,13 @@ xfs_btree_decrement(
>  	for (block = xfs_btree_get_block(cur, lev, &bp); lev > level; ) {
>  		union xfs_btree_ptr	*ptrp;
>  
> -		ptrp = xfs_btree_ptr_addr(cur, cur->bc_ptrs[lev], block);
> +		ptrp = xfs_btree_ptr_addr(cur, cur->bc_levels[lev].ptr, block);
>  		--lev;
>  		error = xfs_btree_read_buf_block(cur, ptrp, 0, &block, &bp);
>  		if (error)
>  			goto error0;
>  		xfs_btree_setbuf(cur, lev, bp);
> -		cur->bc_ptrs[lev] = xfs_btree_get_numrecs(block);
> +		cur->bc_levels[lev].ptr = xfs_btree_get_numrecs(block);
>  	}
>  out1:
>  	*stat = 1;
> @@ -1735,7 +1735,7 @@ xfs_btree_lookup_get_block(
>  	 *
>  	 * Otherwise throw it away and get a new one.
>  	 */
> -	bp = cur->bc_bufs[level];
> +	bp = cur->bc_levels[level].bp;
>  	error = xfs_btree_ptr_to_daddr(cur, pp, &daddr);
>  	if (error)
>  		return error;
> @@ -1864,7 +1864,7 @@ xfs_btree_lookup(
>  					return -EFSCORRUPTED;
>  				}
>  
> -				cur->bc_ptrs[0] = dir != XFS_LOOKUP_LE;
> +				cur->bc_levels[0].ptr = dir != XFS_LOOKUP_LE;
>  				*stat = 0;
>  				return 0;
>  			}
> @@ -1916,7 +1916,7 @@ xfs_btree_lookup(
>  			if (error)
>  				goto error0;
>  
> -			cur->bc_ptrs[level] = keyno;
> +			cur->bc_levels[level].ptr = keyno;
>  		}
>  	}
>  
> @@ -1933,7 +1933,7 @@ xfs_btree_lookup(
>  		    !xfs_btree_ptr_is_null(cur, &ptr)) {
>  			int	i;
>  
> -			cur->bc_ptrs[0] = keyno;
> +			cur->bc_levels[0].ptr = keyno;
>  			error = xfs_btree_increment(cur, 0, &i);
>  			if (error)
>  				goto error0;
> @@ -1944,7 +1944,7 @@ xfs_btree_lookup(
>  		}
>  	} else if (dir == XFS_LOOKUP_LE && diff > 0)
>  		keyno--;
> -	cur->bc_ptrs[0] = keyno;
> +	cur->bc_levels[0].ptr = keyno;
>  
>  	/* Return if we succeeded or not. */
>  	if (keyno == 0 || keyno > xfs_btree_get_numrecs(block))
> @@ -2104,7 +2104,7 @@ __xfs_btree_updkeys(
>  		if (error)
>  			return error;
>  #endif
> -		ptr = cur->bc_ptrs[level];
> +		ptr = cur->bc_levels[level].ptr;
>  		nlkey = xfs_btree_key_addr(cur, ptr, block);
>  		nhkey = xfs_btree_high_key_addr(cur, ptr, block);
>  		if (!force_all &&
> @@ -2171,7 +2171,7 @@ xfs_btree_update_keys(
>  		if (error)
>  			return error;
>  #endif
> -		ptr = cur->bc_ptrs[level];
> +		ptr = cur->bc_levels[level].ptr;
>  		kp = xfs_btree_key_addr(cur, ptr, block);
>  		xfs_btree_copy_keys(cur, kp, &key, 1);
>  		xfs_btree_log_keys(cur, bp, ptr, ptr);
> @@ -2205,7 +2205,7 @@ xfs_btree_update(
>  		goto error0;
>  #endif
>  	/* Get the address of the rec to be updated. */
> -	ptr = cur->bc_ptrs[0];
> +	ptr = cur->bc_levels[0].ptr;
>  	rp = xfs_btree_rec_addr(cur, ptr, block);
>  
>  	/* Fill in the new contents and log them. */
> @@ -2280,7 +2280,7 @@ xfs_btree_lshift(
>  	 * If the cursor entry is the one that would be moved, don't
>  	 * do it... it's too complicated.
>  	 */
> -	if (cur->bc_ptrs[level] <= 1)
> +	if (cur->bc_levels[level].ptr <= 1)
>  		goto out0;
>  
>  	/* Set up the left neighbor as "left". */
> @@ -2414,7 +2414,7 @@ xfs_btree_lshift(
>  		goto error0;
>  
>  	/* Slide the cursor value left one. */
> -	cur->bc_ptrs[level]--;
> +	cur->bc_levels[level].ptr--;
>  
>  	*stat = 1;
>  	return 0;
> @@ -2476,7 +2476,7 @@ xfs_btree_rshift(
>  	 * do it... it's too complicated.
>  	 */
>  	lrecs = xfs_btree_get_numrecs(left);
> -	if (cur->bc_ptrs[level] >= lrecs)
> +	if (cur->bc_levels[level].ptr >= lrecs)
>  		goto out0;
>  
>  	/* Set up the right neighbor as "right". */
> @@ -2664,7 +2664,7 @@ __xfs_btree_split(
>  	 */
>  	lrecs = xfs_btree_get_numrecs(left);
>  	rrecs = lrecs / 2;
> -	if ((lrecs & 1) && cur->bc_ptrs[level] <= rrecs + 1)
> +	if ((lrecs & 1) && cur->bc_levels[level].ptr <= rrecs + 1)
>  		rrecs++;
>  	src_index = (lrecs - rrecs + 1);
>  
> @@ -2760,9 +2760,9 @@ __xfs_btree_split(
>  	 * If it's just pointing past the last entry in left, then we'll
>  	 * insert there, so don't change anything in that case.
>  	 */
> -	if (cur->bc_ptrs[level] > lrecs + 1) {
> +	if (cur->bc_levels[level].ptr > lrecs + 1) {
>  		xfs_btree_setbuf(cur, level, rbp);
> -		cur->bc_ptrs[level] -= lrecs;
> +		cur->bc_levels[level].ptr -= lrecs;
>  	}
>  	/*
>  	 * If there are more levels, we'll need another cursor which refers
> @@ -2772,7 +2772,7 @@ __xfs_btree_split(
>  		error = xfs_btree_dup_cursor(cur, curp);
>  		if (error)
>  			goto error0;
> -		(*curp)->bc_ptrs[level + 1]++;
> +		(*curp)->bc_levels[level + 1].ptr++;
>  	}
>  	*ptrp = rptr;
>  	*stat = 1;
> @@ -2934,7 +2934,7 @@ xfs_btree_new_iroot(
>  	xfs_btree_set_numrecs(block, 1);
>  	cur->bc_nlevels++;
>  	ASSERT(cur->bc_nlevels <= XFS_BTREE_MAXLEVELS);
> -	cur->bc_ptrs[level + 1] = 1;
> +	cur->bc_levels[level + 1].ptr = 1;
>  
>  	kp = xfs_btree_key_addr(cur, 1, block);
>  	ckp = xfs_btree_key_addr(cur, 1, cblock);
> @@ -3095,7 +3095,7 @@ xfs_btree_new_root(
>  
>  	/* Fix up the cursor. */
>  	xfs_btree_setbuf(cur, cur->bc_nlevels, nbp);
> -	cur->bc_ptrs[cur->bc_nlevels] = nptr;
> +	cur->bc_levels[cur->bc_nlevels].ptr = nptr;
>  	cur->bc_nlevels++;
>  	ASSERT(cur->bc_nlevels <= XFS_BTREE_MAXLEVELS);
>  	*stat = 1;
> @@ -3154,7 +3154,7 @@ xfs_btree_make_block_unfull(
>  		return error;
>  
>  	if (*stat) {
> -		*oindex = *index = cur->bc_ptrs[level];
> +		*oindex = *index = cur->bc_levels[level].ptr;
>  		return 0;
>  	}
>  
> @@ -3169,7 +3169,7 @@ xfs_btree_make_block_unfull(
>  		return error;
>  
>  
> -	*index = cur->bc_ptrs[level];
> +	*index = cur->bc_levels[level].ptr;
>  	return 0;
>  }
>  
> @@ -3216,7 +3216,7 @@ xfs_btree_insrec(
>  	}
>  
>  	/* If we're off the left edge, return failure. */
> -	ptr = cur->bc_ptrs[level];
> +	ptr = cur->bc_levels[level].ptr;
>  	if (ptr == 0) {
>  		*stat = 0;
>  		return 0;
> @@ -3559,7 +3559,7 @@ xfs_btree_kill_iroot(
>  	if (error)
>  		return error;
>  
> -	cur->bc_bufs[level - 1] = NULL;
> +	cur->bc_levels[level - 1].bp = NULL;
>  	be16_add_cpu(&block->bb_level, -1);
>  	xfs_trans_log_inode(cur->bc_tp, ip,
>  		XFS_ILOG_CORE | xfs_ilog_fbroot(cur->bc_ino.whichfork));
> @@ -3592,8 +3592,8 @@ xfs_btree_kill_root(
>  	if (error)
>  		return error;
>  
> -	cur->bc_bufs[level] = NULL;
> -	cur->bc_ra[level] = 0;
> +	cur->bc_levels[level].bp = NULL;
> +	cur->bc_levels[level].ra = 0;
>  	cur->bc_nlevels--;
>  
>  	return 0;
> @@ -3652,7 +3652,7 @@ xfs_btree_delrec(
>  	tcur = NULL;
>  
>  	/* Get the index of the entry being deleted, check for nothing there. */
> -	ptr = cur->bc_ptrs[level];
> +	ptr = cur->bc_levels[level].ptr;
>  	if (ptr == 0) {
>  		*stat = 0;
>  		return 0;
> @@ -3962,7 +3962,7 @@ xfs_btree_delrec(
>  				xfs_btree_del_cursor(tcur, XFS_BTREE_NOERROR);
>  				tcur = NULL;
>  				if (level == 0)
> -					cur->bc_ptrs[0]++;
> +					cur->bc_levels[0].ptr++;
>  
>  				*stat = 1;
>  				return 0;
> @@ -4099,9 +4099,9 @@ xfs_btree_delrec(
>  	 * cursor to the left block, and fix up the index.
>  	 */
>  	if (bp != lbp) {
> -		cur->bc_bufs[level] = lbp;
> -		cur->bc_ptrs[level] += lrecs;
> -		cur->bc_ra[level] = 0;
> +		cur->bc_levels[level].bp = lbp;
> +		cur->bc_levels[level].ptr += lrecs;
> +		cur->bc_levels[level].ra = 0;
>  	}
>  	/*
>  	 * If we joined with the right neighbor and there's a level above
> @@ -4121,11 +4121,11 @@ xfs_btree_delrec(
>  	 * We can't use decrement because it would change the next level up.
>  	 */
>  	if (level > 0)
> -		cur->bc_ptrs[level]--;
> +		cur->bc_levels[level].ptr--;
>  
>  	/*
>  	 * We combined blocks, so we have to update the parent keys if the
> -	 * btree supports overlapped intervals.  However, bc_ptrs[level + 1]
> +	 * btree supports overlapped intervals.  However, bc_levels[level + 1].ptr
>  	 * points to the old block so that the caller knows which record to
>  	 * delete.  Therefore, the caller must be savvy enough to call updkeys
>  	 * for us if we return stat == 2.  The other exit points from this
> @@ -4184,7 +4184,7 @@ xfs_btree_delete(
>  
>  	if (i == 0) {
>  		for (level = 1; level < cur->bc_nlevels; level++) {
> -			if (cur->bc_ptrs[level] == 0) {
> +			if (cur->bc_levels[level].ptr == 0) {
>  				error = xfs_btree_decrement(cur, level, &i);
>  				if (error)
>  					goto error0;
> @@ -4215,7 +4215,7 @@ xfs_btree_get_rec(
>  	int			error;	/* error return value */
>  #endif
>  
> -	ptr = cur->bc_ptrs[0];
> +	ptr = cur->bc_levels[0].ptr;
>  	block = xfs_btree_get_block(cur, 0, &bp);
>  
>  #ifdef DEBUG
> @@ -4663,23 +4663,23 @@ xfs_btree_overlapped_query_range(
>  	if (error)
>  		goto out;
>  #endif
> -	cur->bc_ptrs[level] = 1;
> +	cur->bc_levels[level].ptr = 1;
>  
>  	while (level < cur->bc_nlevels) {
>  		block = xfs_btree_get_block(cur, level, &bp);
>  
>  		/* End of node, pop back towards the root. */
> -		if (cur->bc_ptrs[level] > be16_to_cpu(block->bb_numrecs)) {
> +		if (cur->bc_levels[level].ptr > be16_to_cpu(block->bb_numrecs)) {
>  pop_up:
>  			if (level < cur->bc_nlevels - 1)
> -				cur->bc_ptrs[level + 1]++;
> +				cur->bc_levels[level + 1].ptr++;
>  			level++;
>  			continue;
>  		}
>  
>  		if (level == 0) {
>  			/* Handle a leaf node. */
> -			recp = xfs_btree_rec_addr(cur, cur->bc_ptrs[0], block);
> +			recp = xfs_btree_rec_addr(cur, cur->bc_levels[0].ptr, block);
>  
>  			cur->bc_ops->init_high_key_from_rec(&rec_hkey, recp);
>  			ldiff = cur->bc_ops->diff_two_keys(cur, &rec_hkey,
> @@ -4702,14 +4702,14 @@ xfs_btree_overlapped_query_range(
>  				/* Record is larger than high key; pop. */
>  				goto pop_up;
>  			}
> -			cur->bc_ptrs[level]++;
> +			cur->bc_levels[level].ptr++;
>  			continue;
>  		}
>  
>  		/* Handle an internal node. */
> -		lkp = xfs_btree_key_addr(cur, cur->bc_ptrs[level], block);
> -		hkp = xfs_btree_high_key_addr(cur, cur->bc_ptrs[level], block);
> -		pp = xfs_btree_ptr_addr(cur, cur->bc_ptrs[level], block);
> +		lkp = xfs_btree_key_addr(cur, cur->bc_levels[level].ptr, block);
> +		hkp = xfs_btree_high_key_addr(cur, cur->bc_levels[level].ptr, block);
> +		pp = xfs_btree_ptr_addr(cur, cur->bc_levels[level].ptr, block);
>  
>  		ldiff = cur->bc_ops->diff_two_keys(cur, hkp, low_key);
>  		hdiff = cur->bc_ops->diff_two_keys(cur, high_key, lkp);
> @@ -4732,13 +4732,13 @@ xfs_btree_overlapped_query_range(
>  			if (error)
>  				goto out;
>  #endif
> -			cur->bc_ptrs[level] = 1;
> +			cur->bc_levels[level].ptr = 1;
>  			continue;
>  		} else if (hdiff < 0) {
>  			/* The low key is larger than the upper range; pop. */
>  			goto pop_up;
>  		}
> -		cur->bc_ptrs[level]++;
> +		cur->bc_levels[level].ptr++;
>  	}
>  
>  out:
> @@ -4749,13 +4749,13 @@ xfs_btree_overlapped_query_range(
>  	 * with a zero-results range query, so release the buffers if we
>  	 * failed to return any results.
>  	 */
> -	if (cur->bc_bufs[0] == NULL) {
> +	if (cur->bc_levels[0].bp == NULL) {
>  		for (i = 0; i < cur->bc_nlevels; i++) {
> -			if (cur->bc_bufs[i]) {
> -				xfs_trans_brelse(cur->bc_tp, cur->bc_bufs[i]);
> -				cur->bc_bufs[i] = NULL;
> -				cur->bc_ptrs[i] = 0;
> -				cur->bc_ra[i] = 0;
> +			if (cur->bc_levels[i].bp) {
> +				xfs_trans_brelse(cur->bc_tp, cur->bc_levels[i].bp);
> +				cur->bc_levels[i].bp = NULL;
> +				cur->bc_levels[i].ptr = 0;
> +				cur->bc_levels[i].ra = 0;
>  			}
>  		}
>  	}
> @@ -4917,7 +4917,7 @@ xfs_btree_has_more_records(
>  	block = xfs_btree_get_block(cur, 0, &bp);
>  
>  	/* There are still records in this block. */
> -	if (cur->bc_ptrs[0] < xfs_btree_get_numrecs(block))
> +	if (cur->bc_levels[0].ptr < xfs_btree_get_numrecs(block))
>  		return true;
>  
>  	/* There are more record blocks. */
> diff --git a/fs/xfs/libxfs/xfs_btree.h b/fs/xfs/libxfs/xfs_btree.h
> index 513ade4a89f8..827c44bf24dc 100644
> --- a/fs/xfs/libxfs/xfs_btree.h
> +++ b/fs/xfs/libxfs/xfs_btree.h
> @@ -212,6 +212,19 @@ struct xfs_btree_cur_ino {
>  #define	XFS_BTCUR_BMBT_INVALID_OWNER	(1 << 1)
>  };
>  
> +struct xfs_btree_level {
> +	/* buffer pointer */
> +	struct xfs_buf	*bp;
> +
> +	/* key/record number */
> +	unsigned int	ptr;
> +
> +	/* readahead info */
> +#define	XFS_BTCUR_LEFTRA	1	/* left sibling has been read-ahead */
> +#define	XFS_BTCUR_RIGHTRA	2	/* right sibling has been read-ahead */
> +	uint8_t		ra;
> +};
> +
>  /*
>   * Btree cursor structure.
>   * This collects all information needed by the btree code in one place.
> @@ -223,11 +236,6 @@ struct xfs_btree_cur
>  	const struct xfs_btree_ops *bc_ops;
>  	uint			bc_flags; /* btree features - below */
>  	union xfs_btree_irec	bc_rec;	/* current insert/search record value */
> -	struct xfs_buf	*bc_bufs[XFS_BTREE_MAXLEVELS];	/* buf ptr per level */
> -	int		bc_ptrs[XFS_BTREE_MAXLEVELS];	/* key/record # */
> -	uint8_t		bc_ra[XFS_BTREE_MAXLEVELS];	/* readahead bits */
> -#define	XFS_BTCUR_LEFTRA	1	/* left sibling has been read-ahead */
> -#define	XFS_BTCUR_RIGHTRA	2	/* right sibling has been read-ahead */
>  	uint8_t		bc_nlevels;	/* number of levels in the tree */
>  	uint8_t		bc_blocklog;	/* log2(blocksize) of btree blocks */
>  	xfs_btnum_t	bc_btnum;	/* identifies which btree type */
> @@ -243,8 +251,17 @@ struct xfs_btree_cur
>  		struct xfs_btree_cur_ag	bc_ag;
>  		struct xfs_btree_cur_ino bc_ino;
>  	};
> +
> +	/* Must be at the end of the struct! */
> +	struct xfs_btree_level	bc_levels[];
>  };
>  
> +static inline size_t xfs_btree_cur_sizeof(unsigned int nlevels)
> +{
> +	return sizeof(struct xfs_btree_cur) +
> +	       sizeof(struct xfs_btree_level) * (nlevels);
> +}
> +
>  /* cursor flags */
>  #define XFS_BTREE_LONG_PTRS		(1<<0)	/* pointers are 64bits long */
>  #define XFS_BTREE_ROOT_IN_INODE		(1<<1)	/* root may be variable size */
> @@ -258,7 +275,6 @@ struct xfs_btree_cur
>   */
>  #define XFS_BTREE_STAGING		(1<<5)
>  
> -
>  #define	XFS_BTREE_NOERROR	0
>  #define	XFS_BTREE_ERROR		1
>  
> diff --git a/fs/xfs/scrub/bitmap.c b/fs/xfs/scrub/bitmap.c
> index d6d24c866bc4..b8b8e871e3b7 100644
> --- a/fs/xfs/scrub/bitmap.c
> +++ b/fs/xfs/scrub/bitmap.c
> @@ -222,20 +222,20 @@ xbitmap_disunion(
>   * 1  2  3
>   *
>   * Pretend for this example that each leaf block has 100 btree records.  For
> - * the first btree record, we'll observe that bc_ptrs[0] == 1, so we record
> - * that we saw block 1.  Then we observe that bc_ptrs[1] == 1, so we record
> + * the first btree record, we'll observe that bc_levels[0].ptr == 1, so we record
> + * that we saw block 1.  Then we observe that bc_levels[1].ptr == 1, so we record
>   * block 4.  The list is [1, 4].
>   *
> - * For the second btree record, we see that bc_ptrs[0] == 2, so we exit the
> + * For the second btree record, we see that bc_levels[0].ptr == 2, so we exit the
>   * loop.  The list remains [1, 4].
>   *
>   * For the 101st btree record, we've moved onto leaf block 2.  Now
> - * bc_ptrs[0] == 1 again, so we record that we saw block 2.  We see that
> - * bc_ptrs[1] == 2, so we exit the loop.  The list is now [1, 4, 2].
> + * bc_levels[0].ptr == 1 again, so we record that we saw block 2.  We see that
> + * bc_levels[1].ptr == 2, so we exit the loop.  The list is now [1, 4, 2].
>   *
> - * For the 102nd record, bc_ptrs[0] == 2, so we continue.
> + * For the 102nd record, bc_levels[0].ptr == 2, so we continue.
>   *
> - * For the 201st record, we've moved on to leaf block 3.  bc_ptrs[0] == 1, so
> + * For the 201st record, we've moved on to leaf block 3.  bc_levels[0].ptr == 1, so
>   * we add 3 to the list.  Now it is [1, 4, 2, 3].
>   *
>   * For the 300th record we just exit, with the list being [1, 4, 2, 3].
> @@ -256,7 +256,7 @@ xbitmap_set_btcur_path(
>  	int			i;
>  	int			error;
>  
> -	for (i = 0; i < cur->bc_nlevels && cur->bc_ptrs[i] == 1; i++) {
> +	for (i = 0; i < cur->bc_nlevels && cur->bc_levels[i].ptr == 1; i++) {
>  		xfs_btree_get_block(cur, i, &bp);
>  		if (!bp)
>  			continue;
> diff --git a/fs/xfs/scrub/bmap.c b/fs/xfs/scrub/bmap.c
> index 017da9ceaee9..a4cbbc346f60 100644
> --- a/fs/xfs/scrub/bmap.c
> +++ b/fs/xfs/scrub/bmap.c
> @@ -402,7 +402,7 @@ xchk_bmapbt_rec(
>  	 * the root since the verifiers don't do that.
>  	 */
>  	if (xfs_has_crc(bs->cur->bc_mp) &&
> -	    bs->cur->bc_ptrs[0] == 1) {
> +	    bs->cur->bc_levels[0].ptr == 1) {
>  		for (i = 0; i < bs->cur->bc_nlevels - 1; i++) {
>  			block = xfs_btree_get_block(bs->cur, i, &bp);
>  			owner = be64_to_cpu(block->bb_u.l.bb_owner);
> diff --git a/fs/xfs/scrub/btree.c b/fs/xfs/scrub/btree.c
> index 7b7762ae22e5..5a453ce151ed 100644
> --- a/fs/xfs/scrub/btree.c
> +++ b/fs/xfs/scrub/btree.c
> @@ -136,7 +136,7 @@ xchk_btree_rec(
>  	struct xfs_buf		*bp;
>  
>  	block = xfs_btree_get_block(cur, 0, &bp);
> -	rec = xfs_btree_rec_addr(cur, cur->bc_ptrs[0], block);
> +	rec = xfs_btree_rec_addr(cur, cur->bc_levels[0].ptr, block);
>  
>  	trace_xchk_btree_rec(bs->sc, cur, 0);
>  
> @@ -153,7 +153,7 @@ xchk_btree_rec(
>  	/* Is this at least as large as the parent low key? */
>  	cur->bc_ops->init_key_from_rec(&key, rec);
>  	keyblock = xfs_btree_get_block(cur, 1, &bp);
> -	keyp = xfs_btree_key_addr(cur, cur->bc_ptrs[1], keyblock);
> +	keyp = xfs_btree_key_addr(cur, cur->bc_levels[1].ptr, keyblock);
>  	if (cur->bc_ops->diff_two_keys(cur, &key, keyp) < 0)
>  		xchk_btree_set_corrupt(bs->sc, cur, 1);
>  
> @@ -162,7 +162,7 @@ xchk_btree_rec(
>  
>  	/* Is this no larger than the parent high key? */
>  	cur->bc_ops->init_high_key_from_rec(&hkey, rec);
> -	keyp = xfs_btree_high_key_addr(cur, cur->bc_ptrs[1], keyblock);
> +	keyp = xfs_btree_high_key_addr(cur, cur->bc_levels[1].ptr, keyblock);
>  	if (cur->bc_ops->diff_two_keys(cur, keyp, &hkey) < 0)
>  		xchk_btree_set_corrupt(bs->sc, cur, 1);
>  }
> @@ -184,7 +184,7 @@ xchk_btree_key(
>  	struct xfs_buf		*bp;
>  
>  	block = xfs_btree_get_block(cur, level, &bp);
> -	key = xfs_btree_key_addr(cur, cur->bc_ptrs[level], block);
> +	key = xfs_btree_key_addr(cur, cur->bc_levels[level].ptr, block);
>  
>  	trace_xchk_btree_key(bs->sc, cur, level);
>  
> @@ -200,7 +200,7 @@ xchk_btree_key(
>  
>  	/* Is this at least as large as the parent low key? */
>  	keyblock = xfs_btree_get_block(cur, level + 1, &bp);
> -	keyp = xfs_btree_key_addr(cur, cur->bc_ptrs[level + 1], keyblock);
> +	keyp = xfs_btree_key_addr(cur, cur->bc_levels[level + 1].ptr, keyblock);
>  	if (cur->bc_ops->diff_two_keys(cur, key, keyp) < 0)
>  		xchk_btree_set_corrupt(bs->sc, cur, level);
>  
> @@ -208,8 +208,8 @@ xchk_btree_key(
>  		return;
>  
>  	/* Is this no larger than the parent high key? */
> -	key = xfs_btree_high_key_addr(cur, cur->bc_ptrs[level], block);
> -	keyp = xfs_btree_high_key_addr(cur, cur->bc_ptrs[level + 1], keyblock);
> +	key = xfs_btree_high_key_addr(cur, cur->bc_levels[level].ptr, block);
> +	keyp = xfs_btree_high_key_addr(cur, cur->bc_levels[level + 1].ptr, keyblock);
>  	if (cur->bc_ops->diff_two_keys(cur, keyp, key) < 0)
>  		xchk_btree_set_corrupt(bs->sc, cur, level);
>  }
> @@ -292,7 +292,7 @@ xchk_btree_block_check_sibling(
>  
>  	/* Compare upper level pointer to sibling pointer. */
>  	pblock = xfs_btree_get_block(ncur, level + 1, &pbp);
> -	pp = xfs_btree_ptr_addr(ncur, ncur->bc_ptrs[level + 1], pblock);
> +	pp = xfs_btree_ptr_addr(ncur, ncur->bc_levels[level + 1].ptr, pblock);
>  	if (!xchk_btree_ptr_ok(bs, level + 1, pp))
>  		goto out;
>  	if (pbp)
> @@ -597,7 +597,7 @@ xchk_btree_block_keys(
>  
>  	/* Obtain the parent's copy of the keys for this block. */
>  	parent_block = xfs_btree_get_block(cur, level + 1, &bp);
> -	parent_keys = xfs_btree_key_addr(cur, cur->bc_ptrs[level + 1],
> +	parent_keys = xfs_btree_key_addr(cur, cur->bc_levels[level + 1].ptr,
>  			parent_block);
>  
>  	if (cur->bc_ops->diff_two_keys(cur, &block_keys, parent_keys) != 0)
> @@ -608,7 +608,7 @@ xchk_btree_block_keys(
>  
>  	/* Get high keys */
>  	high_bk = xfs_btree_high_key_from_key(cur, &block_keys);
> -	high_pk = xfs_btree_high_key_addr(cur, cur->bc_ptrs[level + 1],
> +	high_pk = xfs_btree_high_key_addr(cur, cur->bc_levels[level + 1].ptr,
>  			parent_block);
>  
>  	if (cur->bc_ops->diff_two_keys(cur, high_bk, high_pk) != 0)
> @@ -672,18 +672,18 @@ xchk_btree(
>  	if (error || !block)
>  		goto out;
>  
> -	cur->bc_ptrs[level] = 1;
> +	cur->bc_levels[level].ptr = 1;
>  
>  	while (level < cur->bc_nlevels) {
>  		block = xfs_btree_get_block(cur, level, &bp);
>  
>  		if (level == 0) {
>  			/* End of leaf, pop back towards the root. */
> -			if (cur->bc_ptrs[level] >
> +			if (cur->bc_levels[level].ptr >
>  			    be16_to_cpu(block->bb_numrecs)) {
>  				xchk_btree_block_keys(bs, level, block);
>  				if (level < cur->bc_nlevels - 1)
> -					cur->bc_ptrs[level + 1]++;
> +					cur->bc_levels[level + 1].ptr++;
>  				level++;
>  				continue;
>  			}
> @@ -692,7 +692,7 @@ xchk_btree(
>  			xchk_btree_rec(bs);
>  
>  			/* Call out to the record checker. */
> -			recp = xfs_btree_rec_addr(cur, cur->bc_ptrs[0], block);
> +			recp = xfs_btree_rec_addr(cur, cur->bc_levels[0].ptr, block);
>  			error = bs->scrub_rec(bs, recp);
>  			if (error)
>  				break;
> @@ -700,15 +700,15 @@ xchk_btree(
>  			    (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT))
>  				break;
>  
> -			cur->bc_ptrs[level]++;
> +			cur->bc_levels[level].ptr++;
>  			continue;
>  		}
>  
>  		/* End of node, pop back towards the root. */
> -		if (cur->bc_ptrs[level] > be16_to_cpu(block->bb_numrecs)) {
> +		if (cur->bc_levels[level].ptr > be16_to_cpu(block->bb_numrecs)) {
>  			xchk_btree_block_keys(bs, level, block);
>  			if (level < cur->bc_nlevels - 1)
> -				cur->bc_ptrs[level + 1]++;
> +				cur->bc_levels[level + 1].ptr++;
>  			level++;
>  			continue;
>  		}
> @@ -717,9 +717,9 @@ xchk_btree(
>  		xchk_btree_key(bs, level);
>  
>  		/* Drill another level deeper. */
> -		pp = xfs_btree_ptr_addr(cur, cur->bc_ptrs[level], block);
> +		pp = xfs_btree_ptr_addr(cur, cur->bc_levels[level].ptr, block);
>  		if (!xchk_btree_ptr_ok(bs, level, pp)) {
> -			cur->bc_ptrs[level]++;
> +			cur->bc_levels[level].ptr++;
>  			continue;
>  		}
>  		level--;
> @@ -727,7 +727,7 @@ xchk_btree(
>  		if (error || !block)
>  			goto out;
>  
> -		cur->bc_ptrs[level] = 1;
> +		cur->bc_levels[level].ptr = 1;
>  	}
>  
>  out:
> diff --git a/fs/xfs/scrub/trace.c b/fs/xfs/scrub/trace.c
> index c0ef53fe6611..816dfc8e5a80 100644
> --- a/fs/xfs/scrub/trace.c
> +++ b/fs/xfs/scrub/trace.c
> @@ -21,10 +21,11 @@ xchk_btree_cur_fsbno(
>  	struct xfs_btree_cur	*cur,
>  	int			level)
>  {
> -	if (level < cur->bc_nlevels && cur->bc_bufs[level])
> +	if (level < cur->bc_nlevels && cur->bc_levels[level].bp)
>  		return XFS_DADDR_TO_FSB(cur->bc_mp,
> -				xfs_buf_daddr(cur->bc_bufs[level]));
> -	if (level == cur->bc_nlevels - 1 && cur->bc_flags & XFS_BTREE_LONG_PTRS)
> +				xfs_buf_daddr(cur->bc_levels[level].bp));
> +	else if (level == cur->bc_nlevels - 1 &&
> +		 cur->bc_flags & XFS_BTREE_LONG_PTRS)
>  		return XFS_INO_TO_FSB(cur->bc_mp, cur->bc_ino.ip->i_ino);
>  	if (!(cur->bc_flags & XFS_BTREE_LONG_PTRS))
>  		return XFS_AGB_TO_FSB(cur->bc_mp, cur->bc_ag.pag->pag_agno, 0);
> diff --git a/fs/xfs/scrub/trace.h b/fs/xfs/scrub/trace.h
> index a7bbb84f91a7..93ece6df02e3 100644
> --- a/fs/xfs/scrub/trace.h
> +++ b/fs/xfs/scrub/trace.h
> @@ -348,7 +348,7 @@ TRACE_EVENT(xchk_btree_op_error,
>  		__entry->level = level;
>  		__entry->agno = XFS_FSB_TO_AGNO(cur->bc_mp, fsbno);
>  		__entry->bno = XFS_FSB_TO_AGBNO(cur->bc_mp, fsbno);
> -		__entry->ptr = cur->bc_ptrs[level];
> +		__entry->ptr = cur->bc_levels[level].ptr;
>  		__entry->error = error;
>  		__entry->ret_ip = ret_ip;
>  	),
> @@ -389,7 +389,7 @@ TRACE_EVENT(xchk_ifork_btree_op_error,
>  		__entry->type = sc->sm->sm_type;
>  		__entry->btnum = cur->bc_btnum;
>  		__entry->level = level;
> -		__entry->ptr = cur->bc_ptrs[level];
> +		__entry->ptr = cur->bc_levels[level].ptr;
>  		__entry->agno = XFS_FSB_TO_AGNO(cur->bc_mp, fsbno);
>  		__entry->bno = XFS_FSB_TO_AGBNO(cur->bc_mp, fsbno);
>  		__entry->error = error;
> @@ -431,7 +431,7 @@ TRACE_EVENT(xchk_btree_error,
>  		__entry->level = level;
>  		__entry->agno = XFS_FSB_TO_AGNO(cur->bc_mp, fsbno);
>  		__entry->bno = XFS_FSB_TO_AGBNO(cur->bc_mp, fsbno);
> -		__entry->ptr = cur->bc_ptrs[level];
> +		__entry->ptr = cur->bc_levels[level].ptr;
>  		__entry->ret_ip = ret_ip;
>  	),
>  	TP_printk("dev %d:%d type %s btree %s level %d ptr %d agno 0x%x agbno 0x%x ret_ip %pS",
> @@ -471,7 +471,7 @@ TRACE_EVENT(xchk_ifork_btree_error,
>  		__entry->level = level;
>  		__entry->agno = XFS_FSB_TO_AGNO(cur->bc_mp, fsbno);
>  		__entry->bno = XFS_FSB_TO_AGBNO(cur->bc_mp, fsbno);
> -		__entry->ptr = cur->bc_ptrs[level];
> +		__entry->ptr = cur->bc_levels[level].ptr;
>  		__entry->ret_ip = ret_ip;
>  	),
>  	TP_printk("dev %d:%d ino 0x%llx fork %s type %s btree %s level %d ptr %d agno 0x%x agbno 0x%x ret_ip %pS",
> @@ -511,7 +511,7 @@ DECLARE_EVENT_CLASS(xchk_sbtree_class,
>  		__entry->bno = XFS_FSB_TO_AGBNO(cur->bc_mp, fsbno);
>  		__entry->level = level;
>  		__entry->nlevels = cur->bc_nlevels;
> -		__entry->ptr = cur->bc_ptrs[level];
> +		__entry->ptr = cur->bc_levels[level].ptr;
>  	),
>  	TP_printk("dev %d:%d type %s btree %s agno 0x%x agbno 0x%x level %d nlevels %d ptr %d",
>  		  MAJOR(__entry->dev), MINOR(__entry->dev),
> diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> index c4e0cd1c1c8c..30bae0657343 100644
> --- a/fs/xfs/xfs_super.c
> +++ b/fs/xfs/xfs_super.c
> @@ -1966,7 +1966,7 @@ xfs_init_zones(void)
>  		goto out_destroy_log_ticket_zone;
>  
>  	xfs_btree_cur_zone = kmem_cache_create("xfs_btree_cur",
> -					       sizeof(struct xfs_btree_cur),
> +				xfs_btree_cur_sizeof(XFS_BTREE_MAXLEVELS),
>  					       0, 0, NULL);
>  	if (!xfs_btree_cur_zone)
>  		goto out_destroy_bmap_free_item_zone;
> diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
> index 1033a95fbf8e..4a8076ef8cb4 100644
> --- a/fs/xfs/xfs_trace.h
> +++ b/fs/xfs/xfs_trace.h
> @@ -2476,7 +2476,7 @@ DECLARE_EVENT_CLASS(xfs_btree_cur_class,
>  		__entry->btnum = cur->bc_btnum;
>  		__entry->level = level;
>  		__entry->nlevels = cur->bc_nlevels;
> -		__entry->ptr = cur->bc_ptrs[level];
> +		__entry->ptr = cur->bc_levels[level].ptr;
>  		__entry->daddr = bp ? xfs_buf_daddr(bp) : -1;
>  	),
>  	TP_printk("dev %d:%d btree %s level %d/%d ptr %d daddr 0x%llx",


-- 
chandan

  reply	other threads:[~2021-09-20 10:10 UTC|newest]

Thread overview: 48+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-18  1:29 [PATCHSET RFC chandan 00/14] xfs: support dynamic btree cursor height Darrick J. Wong
2021-09-18  1:29 ` [PATCH 01/14] xfs: remove xfs_btree_cur_t typedef Darrick J. Wong
2021-09-20  9:53   ` Chandan Babu R
2021-09-21  8:36   ` Christoph Hellwig
2021-09-18  1:29 ` [PATCH 02/14] xfs: don't allocate scrub contexts on the stack Darrick J. Wong
2021-09-20  9:53   ` Chandan Babu R
2021-09-20 17:39     ` Darrick J. Wong
2021-09-21  8:39   ` Christoph Hellwig
2021-09-18  1:29 ` [PATCH 03/14] xfs: dynamically allocate btree scrub context structure Darrick J. Wong
2021-09-20  9:53   ` Chandan Babu R
2021-09-21  8:43   ` Christoph Hellwig
2021-09-22 16:17     ` Darrick J. Wong
2021-09-18  1:29 ` [PATCH 04/14] xfs: stricter btree height checking when looking for errors Darrick J. Wong
2021-09-20  9:54   ` Chandan Babu R
2021-09-18  1:29 ` [PATCH 05/14] xfs: stricter btree height checking when scanning for btree roots Darrick J. Wong
2021-09-20  9:54   ` Chandan Babu R
2021-09-18  1:29 ` [PATCH 06/14] xfs: check that bc_nlevels never overflows Darrick J. Wong
2021-09-20  9:54   ` Chandan Babu R
2021-09-21  8:44   ` Christoph Hellwig
2021-09-18  1:29 ` [PATCH 07/14] xfs: support dynamic btree cursor heights Darrick J. Wong
2021-09-20  9:55   ` Chandan Babu R [this message]
2021-09-21  8:49   ` Christoph Hellwig
2021-09-18  1:29 ` [PATCH 08/14] xfs: refactor btree cursor allocation function Darrick J. Wong
2021-09-20  9:55   ` Chandan Babu R
2021-09-21  8:53   ` Christoph Hellwig
2021-09-18  1:29 ` [PATCH 09/14] xfs: fix maxlevels comparisons in the btree staging code Darrick J. Wong
2021-09-20  9:55   ` Chandan Babu R
2021-09-21  8:56   ` Christoph Hellwig
2021-09-22 15:59     ` Darrick J. Wong
2021-09-18  1:30 ` [PATCH 10/14] xfs: encode the max btree height in the cursor Darrick J. Wong
2021-09-20  9:55   ` Chandan Babu R
2021-09-21  8:57   ` Christoph Hellwig
2021-09-18  1:30 ` [PATCH 11/14] xfs: dynamically allocate cursors based on maxlevels Darrick J. Wong
2021-09-20  9:56   ` Chandan Babu R
2021-09-20 23:06   ` Dave Chinner
2021-09-20 23:36     ` Dave Chinner
2021-09-21  9:03     ` Christoph Hellwig
2021-09-22 18:55       ` Darrick J. Wong
2021-09-22 17:38     ` Darrick J. Wong
2021-09-22 23:10       ` Dave Chinner
2021-09-23  1:58         ` Darrick J. Wong
2021-09-23  5:56           ` Chandan Babu R
2021-09-18  1:30 ` [PATCH 12/14] xfs: compute actual maximum btree height for critical reservation calculation Darrick J. Wong
2021-09-20  9:56   ` Chandan Babu R
2021-09-18  1:30 ` [PATCH 13/14] xfs: compute the maximum height of the rmap btree when reflink enabled Darrick J. Wong
2021-09-20  9:56   ` Chandan Babu R
2021-09-18  1:30 ` [PATCH 14/14] xfs: kill XFS_BTREE_MAXLEVELS Darrick J. Wong
2021-09-20  9:57   ` Chandan Babu R

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87k0jb7erv.fsf@debian-BULLSEYE-live-builder-AMD64 \
    --to=chandan.babu@oracle.com \
    --cc=chandanrlinux@gmail.com \
    --cc=djwong@kernel.org \
    --cc=linux-xfs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).