diff options
| -rw-r--r-- | fs/xfs/xfs_bmap.c | 2 | ||||
| -rw-r--r-- | fs/xfs/xfs_bmap_btree.c | 113 | ||||
| -rw-r--r-- | fs/xfs/xfs_bmap_btree.h | 6 | ||||
| -rw-r--r-- | fs/xfs/xfs_btree.c | 101 | ||||
| -rw-r--r-- | fs/xfs/xfs_btree.h | 1 | 
5 files changed, 104 insertions, 119 deletions
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c index 7d6c4ace805..315bc291268 100644 --- a/fs/xfs/xfs_bmap.c +++ b/fs/xfs/xfs_bmap.c @@ -476,7 +476,7 @@ xfs_bmap_add_attrfork_btree(  			goto error0;  		/* must be at least one entry */  		XFS_WANT_CORRUPTED_GOTO(stat == 1, error0); -		if ((error = xfs_bmbt_newroot(cur, flags, &stat))) +		if ((error = xfs_btree_new_iroot(cur, flags, &stat)))  			goto error0;  		if (stat == 0) {  			xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); diff --git a/fs/xfs/xfs_bmap_btree.c b/fs/xfs/xfs_bmap_btree.c index e7539263457..204f276aeaa 100644 --- a/fs/xfs/xfs_bmap_btree.c +++ b/fs/xfs/xfs_bmap_btree.c @@ -525,7 +525,7 @@ xfs_bmbt_insrec(  				cur->bc_private.b.whichfork);  			block = xfs_bmbt_get_block(cur, level, &bp);  		} else if (level == cur->bc_nlevels - 1) { -			if ((error = xfs_bmbt_newroot(cur, &logflags, stat)) || +			if ((error = xfs_btree_new_iroot(cur, &logflags, stat)) ||  			    *stat == 0) {  				XFS_BMBT_TRACE_CURSOR(cur, ERROR);  				return error; @@ -1183,117 +1183,6 @@ xfs_bmbt_log_recs(  }  /* - * Give the bmap btree a new root block.  Copy the old broot contents - * down into a real block and make the broot point to it. - */ -int						/* error */ -xfs_bmbt_newroot( -	xfs_btree_cur_t		*cur,		/* btree cursor */ -	int			*logflags,	/* logging flags for inode */ -	int			*stat)		/* return status - 0 fail */ -{ -	xfs_alloc_arg_t		args;		/* allocation arguments */ -	xfs_bmbt_block_t	*block;		/* bmap btree block */ -	xfs_buf_t		*bp;		/* buffer for block */ -	xfs_bmbt_block_t	*cblock;	/* child btree block */ -	xfs_bmbt_key_t		*ckp;		/* child key pointer */ -	xfs_bmbt_ptr_t		*cpp;		/* child ptr pointer */ -	int			error;		/* error return code */ -#ifdef DEBUG -	int			i;		/* loop counter */ -#endif -	xfs_bmbt_key_t		*kp;		/* pointer to bmap btree key */ -	int			level;		/* btree level */ -	xfs_bmbt_ptr_t		*pp;		/* pointer to bmap block addr */ - -	XFS_BMBT_TRACE_CURSOR(cur, ENTRY); -	level = cur->bc_nlevels - 1; -	block = xfs_bmbt_get_block(cur, level, &bp); -	/* -	 * Copy the root into a real block. -	 */ -	args.mp = cur->bc_mp; -	pp = XFS_BMAP_PTR_IADDR(block, 1, cur); -	args.tp = cur->bc_tp; -	args.fsbno = cur->bc_private.b.firstblock; -	args.mod = args.minleft = args.alignment = args.total = args.isfl = -		args.userdata = args.minalignslop = 0; -	args.minlen = args.maxlen = args.prod = 1; -	args.wasdel = cur->bc_private.b.flags & XFS_BTCUR_BPRV_WASDEL; -	args.firstblock = args.fsbno; -	if (args.fsbno == NULLFSBLOCK) { -#ifdef DEBUG -		if ((error = xfs_btree_check_lptr_disk(cur, *pp, level))) { -			XFS_BMBT_TRACE_CURSOR(cur, ERROR); -			return error; -		} -#endif -		args.fsbno = be64_to_cpu(*pp); -		args.type = XFS_ALLOCTYPE_START_BNO; -	} else if (cur->bc_private.b.flist->xbf_low) -		args.type = XFS_ALLOCTYPE_START_BNO; -	else -		args.type = XFS_ALLOCTYPE_NEAR_BNO; -	if ((error = xfs_alloc_vextent(&args))) { -		XFS_BMBT_TRACE_CURSOR(cur, ERROR); -		return error; -	} -	if (args.fsbno == NULLFSBLOCK) { -		XFS_BMBT_TRACE_CURSOR(cur, EXIT); -		*stat = 0; -		return 0; -	} -	ASSERT(args.len == 1); -	cur->bc_private.b.firstblock = args.fsbno; -	cur->bc_private.b.allocated++; -	cur->bc_private.b.ip->i_d.di_nblocks++; -	XFS_TRANS_MOD_DQUOT_BYINO(args.mp, args.tp, cur->bc_private.b.ip, -			  XFS_TRANS_DQ_BCOUNT, 1L); -	bp = xfs_btree_get_bufl(args.mp, cur->bc_tp, args.fsbno, 0); -	cblock = XFS_BUF_TO_BMBT_BLOCK(bp); -	*cblock = *block; -	be16_add_cpu(&block->bb_level, 1); -	block->bb_numrecs = cpu_to_be16(1); -	cur->bc_nlevels++; -	cur->bc_ptrs[level + 1] = 1; -	kp = XFS_BMAP_KEY_IADDR(block, 1, cur); -	ckp = XFS_BMAP_KEY_IADDR(cblock, 1, cur); -	memcpy(ckp, kp, be16_to_cpu(cblock->bb_numrecs) * sizeof(*kp)); -	cpp = XFS_BMAP_PTR_IADDR(cblock, 1, cur); -#ifdef DEBUG -	for (i = 0; i < be16_to_cpu(cblock->bb_numrecs); i++) { -		if ((error = xfs_btree_check_lptr_disk(cur, pp[i], level))) { -			XFS_BMBT_TRACE_CURSOR(cur, ERROR); -			return error; -		} -	} -#endif -	memcpy(cpp, pp, be16_to_cpu(cblock->bb_numrecs) * sizeof(*pp)); -#ifdef DEBUG -	if ((error = xfs_btree_check_lptr(cur, args.fsbno, level))) { -		XFS_BMBT_TRACE_CURSOR(cur, ERROR); -		return error; -	} -#endif -	*pp = cpu_to_be64(args.fsbno); -	xfs_iroot_realloc(cur->bc_private.b.ip, 1 - be16_to_cpu(cblock->bb_numrecs), -		cur->bc_private.b.whichfork); -	xfs_btree_setbuf(cur, level, bp); -	/* -	 * Do all this logging at the end so that -	 * the root is at the right level. -	 */ -	xfs_bmbt_log_block(cur, bp, XFS_BB_ALL_BITS); -	xfs_bmbt_log_keys(cur, bp, 1, be16_to_cpu(cblock->bb_numrecs)); -	xfs_bmbt_log_ptrs(cur, bp, 1, be16_to_cpu(cblock->bb_numrecs)); -	XFS_BMBT_TRACE_CURSOR(cur, EXIT); -	*logflags |= -		XFS_ILOG_CORE | XFS_ILOG_FBROOT(cur->bc_private.b.whichfork); -	*stat = 1; -	return 0; -} - -/*   * Set all the fields in a bmap extent record from the arguments.   */  void diff --git a/fs/xfs/xfs_bmap_btree.h b/fs/xfs/xfs_bmap_btree.h index 6bfd62ec54f..26fd8ace3e7 100644 --- a/fs/xfs/xfs_bmap_btree.h +++ b/fs/xfs/xfs_bmap_btree.h @@ -255,12 +255,6 @@ extern void xfs_bmbt_log_block(struct xfs_btree_cur *, struct xfs_buf *, int);  extern void xfs_bmbt_log_recs(struct xfs_btree_cur *, struct xfs_buf *, int,  				int); -/* - * Give the bmap btree a new root block.  Copy the old broot contents - * down into a real block and make the broot point to it. - */ -extern int xfs_bmbt_newroot(struct xfs_btree_cur *cur, int *lflags, int *stat); -  extern void xfs_bmbt_set_all(xfs_bmbt_rec_host_t *r, xfs_bmbt_irec_t *s);  extern void xfs_bmbt_set_allf(xfs_bmbt_rec_host_t *r, xfs_fileoff_t o,  			xfs_fsblock_t b, xfs_filblks_t c, xfs_exntst_t v); diff --git a/fs/xfs/xfs_btree.c b/fs/xfs/xfs_btree.c index 8de884c4dab..3b6e01dea66 100644 --- a/fs/xfs/xfs_btree.c +++ b/fs/xfs/xfs_btree.c @@ -2469,6 +2469,107 @@ error0:  }  /* + * Copy the old inode root contents into a real block and make the + * broot point to it. + */ +int						/* error */ +xfs_btree_new_iroot( +	struct xfs_btree_cur	*cur,		/* btree cursor */ +	int			*logflags,	/* logging flags for inode */ +	int			*stat)		/* return status - 0 fail */ +{ +	struct xfs_buf		*cbp;		/* buffer for cblock */ +	struct xfs_btree_block	*block;		/* btree block */ +	struct xfs_btree_block	*cblock;	/* child btree block */ +	union xfs_btree_key	*ckp;		/* child key pointer */ +	union xfs_btree_ptr	*cpp;		/* child ptr pointer */ +	union xfs_btree_key	*kp;		/* pointer to btree key */ +	union xfs_btree_ptr	*pp;		/* pointer to block addr */ +	union xfs_btree_ptr	nptr;		/* new block addr */ +	int			level;		/* btree level */ +	int			error;		/* error return code */ +#ifdef DEBUG +	int			i;		/* loop counter */ +#endif + +	XFS_BTREE_TRACE_CURSOR(cur, XBT_ENTRY); +	XFS_BTREE_STATS_INC(cur, newroot); + +	ASSERT(cur->bc_flags & XFS_BTREE_ROOT_IN_INODE); + +	level = cur->bc_nlevels - 1; + +	block = xfs_btree_get_iroot(cur); +	pp = xfs_btree_ptr_addr(cur, 1, block); + +	/* Allocate the new block. If we can't do it, we're toast. Give up. */ +	error = cur->bc_ops->alloc_block(cur, pp, &nptr, 1, stat); +	if (error) +		goto error0; +	if (*stat == 0) { +		XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); +		return 0; +	} +	XFS_BTREE_STATS_INC(cur, alloc); + +	/* Copy the root into a real block. */ +	error = xfs_btree_get_buf_block(cur, &nptr, 0, &cblock, &cbp); +	if (error) +		goto error0; + +	memcpy(cblock, block, xfs_btree_block_len(cur)); + +	be16_add_cpu(&block->bb_level, 1); +	xfs_btree_set_numrecs(block, 1); +	cur->bc_nlevels++; +	cur->bc_ptrs[level + 1] = 1; + +	kp = xfs_btree_key_addr(cur, 1, block); +	ckp = xfs_btree_key_addr(cur, 1, cblock); +	xfs_btree_copy_keys(cur, ckp, kp, xfs_btree_get_numrecs(cblock)); + +	cpp = xfs_btree_ptr_addr(cur, 1, cblock); +#ifdef DEBUG +	for (i = 0; i < be16_to_cpu(cblock->bb_numrecs); i++) { +		error = xfs_btree_check_ptr(cur, pp, i, level); +		if (error) +			goto error0; +	} +#endif +	xfs_btree_copy_ptrs(cur, cpp, pp, xfs_btree_get_numrecs(cblock)); + +#ifdef DEBUG +	error = xfs_btree_check_ptr(cur, &nptr, 0, level); +	if (error) +		goto error0; +#endif +	xfs_btree_copy_ptrs(cur, pp, &nptr, 1); + +	xfs_iroot_realloc(cur->bc_private.b.ip, +			  1 - xfs_btree_get_numrecs(cblock), +			  cur->bc_private.b.whichfork); + +	xfs_btree_setbuf(cur, level, cbp); + +	/* +	 * Do all this logging at the end so that +	 * the root is at the right level. +	 */ +	xfs_btree_log_block(cur, cbp, XFS_BB_ALL_BITS); +	xfs_btree_log_keys(cur, cbp, 1, be16_to_cpu(cblock->bb_numrecs)); +	xfs_btree_log_ptrs(cur, cbp, 1, be16_to_cpu(cblock->bb_numrecs)); + +	*logflags |= +		XFS_ILOG_CORE | XFS_ILOG_FBROOT(cur->bc_private.b.whichfork); +	*stat = 1; +	XFS_BTREE_TRACE_CURSOR(cur, XBT_EXIT); +	return 0; +error0: +	XFS_BTREE_TRACE_CURSOR(cur, XBT_ERROR); +	return error; +} + +/*   * Allocate a new root block, fill it in.   */  int				/* error */ diff --git a/fs/xfs/xfs_btree.h b/fs/xfs/xfs_btree.h index 18015392feb..21eec863f00 100644 --- a/fs/xfs/xfs_btree.h +++ b/fs/xfs/xfs_btree.h @@ -548,6 +548,7 @@ 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 *); +int xfs_btree_new_iroot(struct xfs_btree_cur *, int *, int *);  /*   * Helpers.  |