diff options
| -rw-r--r-- | fs/xfs/xfs_alloc_btree.c | 179 | ||||
| -rw-r--r-- | fs/xfs/xfs_btree.c | 129 | ||||
| -rw-r--r-- | fs/xfs/xfs_btree.h | 5 | ||||
| -rw-r--r-- | fs/xfs/xfs_ialloc_btree.c | 164 | 
4 files changed, 172 insertions, 305 deletions
diff --git a/fs/xfs/xfs_alloc_btree.c b/fs/xfs/xfs_alloc_btree.c index 8a8d1aeec52..f21a3e9cc3d 100644 --- a/fs/xfs/xfs_alloc_btree.c +++ b/fs/xfs/xfs_alloc_btree.c @@ -48,7 +48,6 @@ STATIC void xfs_alloc_log_block(xfs_trans_t *, xfs_buf_t *, int);  STATIC void xfs_alloc_log_keys(xfs_btree_cur_t *, xfs_buf_t *, int, int);  STATIC void xfs_alloc_log_ptrs(xfs_btree_cur_t *, xfs_buf_t *, int, int);  STATIC void xfs_alloc_log_recs(xfs_btree_cur_t *, xfs_buf_t *, int, int); -STATIC int xfs_alloc_newroot(xfs_btree_cur_t *, int *);  /*   * Internal functions. @@ -628,7 +627,7 @@ xfs_alloc_insrec(  	 */  	if (level >= cur->bc_nlevels) {  		XFS_STATS_INC(xs_abt_insrec); -		if ((error = xfs_alloc_newroot(cur, &i))) +		if ((error = xfs_btree_new_root(cur, &i)))  			return error;  		*bnop = NULLAGBLOCK;  		*stat = i; @@ -936,161 +935,6 @@ xfs_alloc_log_recs(  	xfs_trans_log_buf(cur->bc_tp, bp, first, last);  } -/* - * Allocate a new root block, fill it in. - */ -STATIC int				/* error */ -xfs_alloc_newroot( -	xfs_btree_cur_t		*cur,	/* btree cursor */ -	int			*stat)	/* success/failure */ -{ -	int			error;	/* error return value */ -	xfs_agblock_t		lbno;	/* left block number */ -	xfs_buf_t		*lbp;	/* left btree buffer */ -	xfs_alloc_block_t	*left;	/* left btree block */ -	xfs_mount_t		*mp;	/* mount structure */ -	xfs_agblock_t		nbno;	/* new block number */ -	xfs_buf_t		*nbp;	/* new (root) buffer */ -	xfs_alloc_block_t	*new;	/* new (root) btree block */ -	int			nptr;	/* new value for key index, 1 or 2 */ -	xfs_agblock_t		rbno;	/* right block number */ -	xfs_buf_t		*rbp;	/* right btree buffer */ -	xfs_alloc_block_t	*right;	/* right btree block */ - -	mp = cur->bc_mp; - -	ASSERT(cur->bc_nlevels < XFS_AG_MAXLEVELS(mp)); -	/* -	 * Get a buffer from the freelist blocks, for the new root. -	 */ -	error = xfs_alloc_get_freelist(cur->bc_tp, -					cur->bc_private.a.agbp, &nbno, 1); -	if (error) -		return error; -	/* -	 * None available, we fail. -	 */ -	if (nbno == NULLAGBLOCK) { -		*stat = 0; -		return 0; -	} -	xfs_trans_agbtree_delta(cur->bc_tp, 1); -	nbp = xfs_btree_get_bufs(mp, cur->bc_tp, cur->bc_private.a.agno, nbno, -		0); -	new = XFS_BUF_TO_ALLOC_BLOCK(nbp); -	/* -	 * Set the root data in the a.g. freespace structure. -	 */ -	{ -		xfs_agf_t	*agf;	/* a.g. freespace header */ -		xfs_agnumber_t	seqno; - -		agf = XFS_BUF_TO_AGF(cur->bc_private.a.agbp); -		agf->agf_roots[cur->bc_btnum] = cpu_to_be32(nbno); -		be32_add_cpu(&agf->agf_levels[cur->bc_btnum], 1); -		seqno = be32_to_cpu(agf->agf_seqno); -		mp->m_perag[seqno].pagf_levels[cur->bc_btnum]++; -		xfs_alloc_log_agf(cur->bc_tp, cur->bc_private.a.agbp, -			XFS_AGF_ROOTS | XFS_AGF_LEVELS); -	} -	/* -	 * At the previous root level there are now two blocks: the old -	 * root, and the new block generated when it was split. -	 * We don't know which one the cursor is pointing at, so we -	 * set up variables "left" and "right" for each case. -	 */ -	lbp = cur->bc_bufs[cur->bc_nlevels - 1]; -	left = XFS_BUF_TO_ALLOC_BLOCK(lbp); -#ifdef DEBUG -	if ((error = xfs_btree_check_sblock(cur, left, cur->bc_nlevels - 1, lbp))) -		return error; -#endif -	if (be32_to_cpu(left->bb_rightsib) != NULLAGBLOCK) { -		/* -		 * Our block is left, pick up the right block. -		 */ -		lbno = XFS_DADDR_TO_AGBNO(mp, XFS_BUF_ADDR(lbp)); -		rbno = be32_to_cpu(left->bb_rightsib); -		if ((error = xfs_btree_read_bufs(mp, cur->bc_tp, -				cur->bc_private.a.agno, rbno, 0, &rbp, -				XFS_ALLOC_BTREE_REF))) -			return error; -		right = XFS_BUF_TO_ALLOC_BLOCK(rbp); -		if ((error = xfs_btree_check_sblock(cur, right, -				cur->bc_nlevels - 1, rbp))) -			return error; -		nptr = 1; -	} else { -		/* -		 * Our block is right, pick up the left block. -		 */ -		rbp = lbp; -		right = left; -		rbno = XFS_DADDR_TO_AGBNO(mp, XFS_BUF_ADDR(rbp)); -		lbno = be32_to_cpu(right->bb_leftsib); -		if ((error = xfs_btree_read_bufs(mp, cur->bc_tp, -				cur->bc_private.a.agno, lbno, 0, &lbp, -				XFS_ALLOC_BTREE_REF))) -			return error; -		left = XFS_BUF_TO_ALLOC_BLOCK(lbp); -		if ((error = xfs_btree_check_sblock(cur, left, -				cur->bc_nlevels - 1, lbp))) -			return error; -		nptr = 2; -	} -	/* -	 * Fill in the new block's btree header and log it. -	 */ -	new->bb_magic = cpu_to_be32(xfs_magics[cur->bc_btnum]); -	new->bb_level = cpu_to_be16(cur->bc_nlevels); -	new->bb_numrecs = cpu_to_be16(2); -	new->bb_leftsib = cpu_to_be32(NULLAGBLOCK); -	new->bb_rightsib = cpu_to_be32(NULLAGBLOCK); -	xfs_alloc_log_block(cur->bc_tp, nbp, XFS_BB_ALL_BITS); -	ASSERT(lbno != NULLAGBLOCK && rbno != NULLAGBLOCK); -	/* -	 * Fill in the key data in the new root. -	 */ -	{ -		xfs_alloc_key_t		*kp;	/* btree key pointer */ - -		kp = XFS_ALLOC_KEY_ADDR(new, 1, cur); -		if (be16_to_cpu(left->bb_level) > 0) { -			kp[0] = *XFS_ALLOC_KEY_ADDR(left, 1, cur); -			kp[1] = *XFS_ALLOC_KEY_ADDR(right, 1, cur); -		} else { -			xfs_alloc_rec_t	*rp;	/* btree record pointer */ - -			rp = XFS_ALLOC_REC_ADDR(left, 1, cur); -			kp[0].ar_startblock = rp->ar_startblock; -			kp[0].ar_blockcount = rp->ar_blockcount; -			rp = XFS_ALLOC_REC_ADDR(right, 1, cur); -			kp[1].ar_startblock = rp->ar_startblock; -			kp[1].ar_blockcount = rp->ar_blockcount; -		} -	} -	xfs_alloc_log_keys(cur, nbp, 1, 2); -	/* -	 * Fill in the pointer data in the new root. -	 */ -	{ -		xfs_alloc_ptr_t		*pp;	/* btree address pointer */ - -		pp = XFS_ALLOC_PTR_ADDR(new, 1, cur); -		pp[0] = cpu_to_be32(lbno); -		pp[1] = cpu_to_be32(rbno); -	} -	xfs_alloc_log_ptrs(cur, nbp, 1, 2); -	/* -	 * Fix up the cursor. -	 */ -	xfs_btree_setbuf(cur, cur->bc_nlevels, nbp); -	cur->bc_ptrs[cur->bc_nlevels] = nptr; -	cur->bc_nlevels++; -	*stat = 1; -	return 0; -} -  /*   * Externally visible routines. @@ -1244,6 +1088,26 @@ xfs_allocbt_dup_cursor(  			cur->bc_btnum);  } +STATIC void +xfs_allocbt_set_root( +	struct xfs_btree_cur	*cur, +	union xfs_btree_ptr	*ptr, +	int			inc) +{ +	struct xfs_buf		*agbp = cur->bc_private.a.agbp; +	struct xfs_agf		*agf = XFS_BUF_TO_AGF(agbp); +	xfs_agnumber_t		seqno = be32_to_cpu(agf->agf_seqno); +	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_mp->m_perag[seqno].pagf_levels[btnum] += inc; + +	xfs_alloc_log_agf(cur->bc_tp, agbp, XFS_AGF_ROOTS | XFS_AGF_LEVELS); +} +  STATIC int  xfs_allocbt_alloc_block(  	struct xfs_btree_cur	*cur, @@ -1440,6 +1304,7 @@ static const struct xfs_btree_ops xfs_allocbt_ops = {  	.key_len		= sizeof(xfs_alloc_key_t),  	.dup_cursor		= xfs_allocbt_dup_cursor, +	.set_root		= xfs_allocbt_set_root,  	.alloc_block		= xfs_allocbt_alloc_block,  	.update_lastrec		= xfs_allocbt_update_lastrec,  	.get_maxrecs		= xfs_allocbt_get_maxrecs, diff --git a/fs/xfs/xfs_btree.c b/fs/xfs/xfs_btree.c index 80576695fbe..8de884c4dab 100644 --- a/fs/xfs/xfs_btree.c +++ b/fs/xfs/xfs_btree.c @@ -2467,3 +2467,132 @@ error0:  	XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR);  	return error;  } + +/* + * Allocate a new root block, fill it in. + */ +int				/* error */ +xfs_btree_new_root( +	struct xfs_btree_cur	*cur,	/* btree cursor */ +	int			*stat)	/* success/failure */ +{ +	struct xfs_btree_block	*block;	/* one half of the old root block */ +	struct xfs_buf		*bp;	/* buffer containing block */ +	int			error;	/* error return value */ +	struct xfs_buf		*lbp;	/* left buffer pointer */ +	struct xfs_btree_block	*left;	/* left btree block */ +	struct xfs_buf		*nbp;	/* new (root) buffer */ +	struct xfs_btree_block	*new;	/* new (root) btree block */ +	int			nptr;	/* new value for key index, 1 or 2 */ +	struct xfs_buf		*rbp;	/* right buffer pointer */ +	struct xfs_btree_block	*right;	/* right btree block */ +	union xfs_btree_ptr	rptr; +	union xfs_btree_ptr	lptr; + +	XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY); +	XFS_BTREE_STATS_INC(cur, newroot); + +	/* initialise our start point from the cursor */ +	cur->bc_ops->init_ptr_from_cur(cur, &rptr); + +	/* Allocate the new block. If we can't do it, we're toast. Give up. */ +	error = cur->bc_ops->alloc_block(cur, &rptr, &lptr, 1, stat); +	if (error) +		goto error0; +	if (*stat == 0) +		goto out0; +	XFS_BTREE_STATS_INC(cur, alloc); + +	/* Set up the new block. */ +	error = xfs_btree_get_buf_block(cur, &lptr, 0, &new, &nbp); +	if (error) +		goto error0; + +	/* Set the root in the holding structure  increasing the level by 1. */ +	cur->bc_ops->set_root(cur, &lptr, 1); + +	/* +	 * At the previous root level there are now two blocks: the old root, +	 * and the new block generated when it was split.  We don't know which +	 * one the cursor is pointing at, so we set up variables "left" and +	 * "right" for each case. +	 */ +	block = xfs_btree_get_block(cur, cur->bc_nlevels - 1, &bp); + +#ifdef DEBUG +	error = xfs_btree_check_block(cur, block, cur->bc_nlevels - 1, bp); +	if (error) +		goto error0; +#endif + +	xfs_btree_get_sibling(cur, block, &rptr, XFS_BB_RIGHTSIB); +	if (!xfs_btree_ptr_is_null(cur, &rptr)) { +		/* Our block is left, pick up the right block. */ +		lbp = bp; +		xfs_btree_buf_to_ptr(cur, lbp, &lptr); +		left = block; +		error = xfs_btree_read_buf_block(cur, &rptr, +					cur->bc_nlevels - 1, 0, &right, &rbp); +		if (error) +			goto error0; +		bp = rbp; +		nptr = 1; +	} else { +		/* Our block is right, pick up the left block. */ +		rbp = bp; +		xfs_btree_buf_to_ptr(cur, rbp, &rptr); +		right = block; +		xfs_btree_get_sibling(cur, right, &lptr, XFS_BB_LEFTSIB); +		error = xfs_btree_read_buf_block(cur, &lptr, +					cur->bc_nlevels - 1, 0, &left, &lbp); +		if (error) +			goto error0; +		bp = lbp; +		nptr = 2; +	} +	/* Fill in the new block's btree header and log it. */ +	xfs_btree_init_block(cur, cur->bc_nlevels, 2, new); +	xfs_btree_log_block(cur, nbp, XFS_BB_ALL_BITS); +	ASSERT(!xfs_btree_ptr_is_null(cur, &lptr) && +			!xfs_btree_ptr_is_null(cur, &rptr)); + +	/* Fill in the key data in the new root. */ +	if (xfs_btree_get_level(left) > 0) { +		xfs_btree_copy_keys(cur, +				xfs_btree_key_addr(cur, 1, new), +				xfs_btree_key_addr(cur, 1, left), 1); +		xfs_btree_copy_keys(cur, +				xfs_btree_key_addr(cur, 2, new), +				xfs_btree_key_addr(cur, 1, right), 1); +	} else { +		cur->bc_ops->init_key_from_rec( +				xfs_btree_key_addr(cur, 1, new), +				xfs_btree_rec_addr(cur, 1, left)); +		cur->bc_ops->init_key_from_rec( +				xfs_btree_key_addr(cur, 2, new), +				xfs_btree_rec_addr(cur, 1, right)); +	} +	xfs_btree_log_keys(cur, nbp, 1, 2); + +	/* Fill in the pointer data in the new root. */ +	xfs_btree_copy_ptrs(cur, +		xfs_btree_ptr_addr(cur, 1, new), &lptr, 1); +	xfs_btree_copy_ptrs(cur, +		xfs_btree_ptr_addr(cur, 2, new), &rptr, 1); +	xfs_btree_log_ptrs(cur, nbp, 1, 2); + +	/* Fix up the cursor. */ +	xfs_btree_setbuf(cur, cur->bc_nlevels, nbp); +	cur->bc_ptrs[cur->bc_nlevels] = nptr; +	cur->bc_nlevels++; +	XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); +	*stat = 1; +	return 0; +error0: +	XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR); +	return error; +out0: +	XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); +	*stat = 0; +	return 0; +} diff --git a/fs/xfs/xfs_btree.h b/fs/xfs/xfs_btree.h index 354a6656fad..18015392feb 100644 --- a/fs/xfs/xfs_btree.h +++ b/fs/xfs/xfs_btree.h @@ -187,6 +187,10 @@ struct xfs_btree_ops {  	/* cursor operations */  	struct xfs_btree_cur *(*dup_cursor)(struct xfs_btree_cur *); +	/* update btree root pointer */ +	void	(*set_root)(struct xfs_btree_cur *cur, +				union xfs_btree_ptr *nptr, int level_change); +  	/* block allocation / freeing */  	int	(*alloc_block)(struct xfs_btree_cur *cur,  			       union xfs_btree_ptr *start_bno, @@ -543,6 +547,7 @@ int xfs_btree_lshift(struct xfs_btree_cur *, int, int *);  int xfs_btree_rshift(struct xfs_btree_cur *, int, int *);  int xfs_btree_split(struct xfs_btree_cur *, int, union xfs_btree_ptr *,  		union xfs_btree_key *, struct xfs_btree_cur **, int *); +int xfs_btree_new_root(struct xfs_btree_cur *, int *);  /*   * Helpers. diff --git a/fs/xfs/xfs_ialloc_btree.c b/fs/xfs/xfs_ialloc_btree.c index c76190a83e4..7ba3c7bb398 100644 --- a/fs/xfs/xfs_ialloc_btree.c +++ b/fs/xfs/xfs_ialloc_btree.c @@ -44,7 +44,6 @@ STATIC void xfs_inobt_log_block(xfs_trans_t *, xfs_buf_t *, int);  STATIC void xfs_inobt_log_keys(xfs_btree_cur_t *, xfs_buf_t *, int, int);  STATIC void xfs_inobt_log_ptrs(xfs_btree_cur_t *, xfs_buf_t *, int, int);  STATIC void xfs_inobt_log_recs(xfs_btree_cur_t *, xfs_buf_t *, int, int); -STATIC int xfs_inobt_newroot(xfs_btree_cur_t *, int *);  /*   * Single level of the xfs_inobt_delete record deletion routine. @@ -556,7 +555,7 @@ xfs_inobt_insrec(  	 * and we're done.  	 */  	if (level >= cur->bc_nlevels) { -		error = xfs_inobt_newroot(cur, &i); +		error = xfs_btree_new_root(cur, &i);  		*bnop = NULLAGBLOCK;  		*stat = i;  		return error; @@ -827,152 +826,6 @@ xfs_inobt_log_recs(  	xfs_trans_log_buf(cur->bc_tp, bp, first, last);  } -/* - * Allocate a new root block, fill it in. - */ -STATIC int				/* error */ -xfs_inobt_newroot( -	xfs_btree_cur_t		*cur,	/* btree cursor */ -	int			*stat)	/* success/failure */ -{ -	xfs_agi_t		*agi;	/* a.g. inode header */ -	xfs_alloc_arg_t		args;	/* allocation argument structure */ -	xfs_inobt_block_t	*block;	/* one half of the old root block */ -	xfs_buf_t		*bp;	/* buffer containing block */ -	int			error;	/* error return value */ -	xfs_inobt_key_t		*kp;	/* btree key pointer */ -	xfs_agblock_t		lbno;	/* left block number */ -	xfs_buf_t		*lbp;	/* left buffer pointer */ -	xfs_inobt_block_t	*left;	/* left btree block */ -	xfs_buf_t		*nbp;	/* new (root) buffer */ -	xfs_inobt_block_t	*new;	/* new (root) btree block */ -	int			nptr;	/* new value for key index, 1 or 2 */ -	xfs_inobt_ptr_t		*pp;	/* btree address pointer */ -	xfs_agblock_t		rbno;	/* right block number */ -	xfs_buf_t		*rbp;	/* right buffer pointer */ -	xfs_inobt_block_t	*right;	/* right btree block */ -	xfs_inobt_rec_t		*rp;	/* btree record pointer */ - -	ASSERT(cur->bc_nlevels < XFS_IN_MAXLEVELS(cur->bc_mp)); - -	/* -	 * Get a block & a buffer. -	 */ -	agi = XFS_BUF_TO_AGI(cur->bc_private.a.agbp); -	args.tp = cur->bc_tp; -	args.mp = cur->bc_mp; -	args.fsbno = XFS_AGB_TO_FSB(args.mp, cur->bc_private.a.agno, -		be32_to_cpu(agi->agi_root)); -	args.mod = args.minleft = args.alignment = args.total = args.wasdel = -		args.isfl = args.userdata = args.minalignslop = 0; -	args.minlen = args.maxlen = args.prod = 1; -	args.type = XFS_ALLOCTYPE_NEAR_BNO; -	if ((error = xfs_alloc_vextent(&args))) -		return error; -	/* -	 * None available, we fail. -	 */ -	if (args.fsbno == NULLFSBLOCK) { -		*stat = 0; -		return 0; -	} -	ASSERT(args.len == 1); -	nbp = xfs_btree_get_bufs(args.mp, args.tp, args.agno, args.agbno, 0); -	new = XFS_BUF_TO_INOBT_BLOCK(nbp); -	/* -	 * Set the root data in the a.g. inode structure. -	 */ -	agi->agi_root = cpu_to_be32(args.agbno); -	be32_add_cpu(&agi->agi_level, 1); -	xfs_ialloc_log_agi(args.tp, cur->bc_private.a.agbp, -		XFS_AGI_ROOT | XFS_AGI_LEVEL); -	/* -	 * At the previous root level there are now two blocks: the old -	 * root, and the new block generated when it was split. -	 * We don't know which one the cursor is pointing at, so we -	 * set up variables "left" and "right" for each case. -	 */ -	bp = cur->bc_bufs[cur->bc_nlevels - 1]; -	block = XFS_BUF_TO_INOBT_BLOCK(bp); -#ifdef DEBUG -	if ((error = xfs_btree_check_sblock(cur, block, cur->bc_nlevels - 1, bp))) -		return error; -#endif -	if (be32_to_cpu(block->bb_rightsib) != NULLAGBLOCK) { -		/* -		 * Our block is left, pick up the right block. -		 */ -		lbp = bp; -		lbno = XFS_DADDR_TO_AGBNO(args.mp, XFS_BUF_ADDR(lbp)); -		left = block; -		rbno = be32_to_cpu(left->bb_rightsib); -		if ((error = xfs_btree_read_bufs(args.mp, args.tp, args.agno, -				rbno, 0, &rbp, XFS_INO_BTREE_REF))) -			return error; -		bp = rbp; -		right = XFS_BUF_TO_INOBT_BLOCK(rbp); -		if ((error = xfs_btree_check_sblock(cur, right, -				cur->bc_nlevels - 1, rbp))) -			return error; -		nptr = 1; -	} else { -		/* -		 * Our block is right, pick up the left block. -		 */ -		rbp = bp; -		rbno = XFS_DADDR_TO_AGBNO(args.mp, XFS_BUF_ADDR(rbp)); -		right = block; -		lbno = be32_to_cpu(right->bb_leftsib); -		if ((error = xfs_btree_read_bufs(args.mp, args.tp, args.agno, -				lbno, 0, &lbp, XFS_INO_BTREE_REF))) -			return error; -		bp = lbp; -		left = XFS_BUF_TO_INOBT_BLOCK(lbp); -		if ((error = xfs_btree_check_sblock(cur, left, -				cur->bc_nlevels - 1, lbp))) -			return error; -		nptr = 2; -	} -	/* -	 * Fill in the new block's btree header and log it. -	 */ -	new->bb_magic = cpu_to_be32(xfs_magics[cur->bc_btnum]); -	new->bb_level = cpu_to_be16(cur->bc_nlevels); -	new->bb_numrecs = cpu_to_be16(2); -	new->bb_leftsib = cpu_to_be32(NULLAGBLOCK); -	new->bb_rightsib = cpu_to_be32(NULLAGBLOCK); -	xfs_inobt_log_block(args.tp, nbp, XFS_BB_ALL_BITS); -	ASSERT(lbno != NULLAGBLOCK && rbno != NULLAGBLOCK); -	/* -	 * Fill in the key data in the new root. -	 */ -	kp = XFS_INOBT_KEY_ADDR(new, 1, cur); -	if (be16_to_cpu(left->bb_level) > 0) { -		kp[0] = *XFS_INOBT_KEY_ADDR(left, 1, cur); -		kp[1] = *XFS_INOBT_KEY_ADDR(right, 1, cur); -	} else { -		rp = XFS_INOBT_REC_ADDR(left, 1, cur); -		kp[0].ir_startino = rp->ir_startino; -		rp = XFS_INOBT_REC_ADDR(right, 1, cur); -		kp[1].ir_startino = rp->ir_startino; -	} -	xfs_inobt_log_keys(cur, nbp, 1, 2); -	/* -	 * Fill in the pointer data in the new root. -	 */ -	pp = XFS_INOBT_PTR_ADDR(new, 1, cur); -	pp[0] = cpu_to_be32(lbno); -	pp[1] = cpu_to_be32(rbno); -	xfs_inobt_log_ptrs(cur, nbp, 1, 2); -	/* -	 * Fix up the cursor. -	 */ -	xfs_btree_setbuf(cur, cur->bc_nlevels, nbp); -	cur->bc_ptrs[cur->bc_nlevels] = nptr; -	cur->bc_nlevels++; -	*stat = 1; -	return 0; -}  /*   * Externally visible routines. @@ -1128,6 +981,20 @@ xfs_inobt_dup_cursor(  			cur->bc_private.a.agbp, cur->bc_private.a.agno);  } +STATIC void +xfs_inobt_set_root( +	struct xfs_btree_cur	*cur, +	union xfs_btree_ptr	*nptr, +	int			inc)	/* level change */ +{ +	struct xfs_buf		*agbp = cur->bc_private.a.agbp; +	struct xfs_agi		*agi = XFS_BUF_TO_AGI(agbp); + +	agi->agi_root = nptr->s; +	be32_add_cpu(&agi->agi_level, inc); +	xfs_ialloc_log_agi(cur->bc_tp, agbp, XFS_AGI_ROOT | XFS_AGI_LEVEL); +} +  STATIC int  xfs_inobt_alloc_block(  	struct xfs_btree_cur	*cur, @@ -1281,6 +1148,7 @@ static const struct xfs_btree_ops xfs_inobt_ops = {  	.key_len		= sizeof(xfs_inobt_key_t),  	.dup_cursor		= xfs_inobt_dup_cursor, +	.set_root		= xfs_inobt_set_root,  	.alloc_block		= xfs_inobt_alloc_block,  	.get_maxrecs		= xfs_inobt_get_maxrecs,  	.init_key_from_rec	= xfs_inobt_init_key_from_rec,  |