diff options
Diffstat (limited to 'fs/xfs/libxfs/xfs_btree.c')
| -rw-r--r-- | fs/xfs/libxfs/xfs_btree.c | 93 | 
1 files changed, 53 insertions, 40 deletions
diff --git a/fs/xfs/libxfs/xfs_btree.c b/fs/xfs/libxfs/xfs_btree.c index fd300dc93ca4..2d25bab68764 100644 --- a/fs/xfs/libxfs/xfs_btree.c +++ b/fs/xfs/libxfs/xfs_btree.c @@ -20,6 +20,7 @@  #include "xfs_trace.h"  #include "xfs_alloc.h"  #include "xfs_log.h" +#include "xfs_btree_staging.h"  /*   * Cursor allocation zone. @@ -214,7 +215,7 @@ xfs_btree_check_sptr(  {  	if (level <= 0)  		return false; -	return xfs_verify_agbno(cur->bc_mp, cur->bc_private.a.agno, agbno); +	return xfs_verify_agbno(cur->bc_mp, cur->bc_ag.agno, agbno);  }  /* @@ -234,8 +235,8 @@ xfs_btree_check_ptr(  			return 0;  		xfs_err(cur->bc_mp,  "Inode %llu fork %d: Corrupt btree %d pointer at level %d index %d.", -				cur->bc_private.b.ip->i_ino, -				cur->bc_private.b.whichfork, cur->bc_btnum, +				cur->bc_ino.ip->i_ino, +				cur->bc_ino.whichfork, cur->bc_btnum,  				level, index);  	} else {  		if (xfs_btree_check_sptr(cur, be32_to_cpu((&ptr->s)[index]), @@ -243,7 +244,7 @@ xfs_btree_check_ptr(  			return 0;  		xfs_err(cur->bc_mp,  "AG %u: Corrupt btree %d pointer at level %d index %d.", -				cur->bc_private.a.agno, cur->bc_btnum, +				cur->bc_ag.agno, cur->bc_btnum,  				level, index);  	} @@ -378,10 +379,12 @@ xfs_btree_del_cursor(  	 * allocated indirect blocks' accounting.  	 */  	ASSERT(cur->bc_btnum != XFS_BTNUM_BMAP || -	       cur->bc_private.b.allocated == 0); +	       cur->bc_ino.allocated == 0);  	/*  	 * Free the cursor.  	 */ +	if (unlikely(cur->bc_flags & XFS_BTREE_STAGING)) +		kmem_free((void *)cur->bc_ops);  	kmem_cache_free(xfs_btree_cur_zone, cur);  } @@ -642,6 +645,17 @@ xfs_btree_ptr_addr(  		((char *)block + xfs_btree_ptr_offset(cur, n, level));  } +struct xfs_ifork * +xfs_btree_ifork_ptr( +	struct xfs_btree_cur	*cur) +{ +	ASSERT(cur->bc_flags & XFS_BTREE_ROOT_IN_INODE); + +	if (cur->bc_flags & XFS_BTREE_STAGING) +		return cur->bc_ino.ifake->if_fork; +	return XFS_IFORK_PTR(cur->bc_ino.ip, cur->bc_ino.whichfork); +} +  /*   * Get the root block which is stored in the inode.   * @@ -652,9 +666,8 @@ STATIC struct xfs_btree_block *  xfs_btree_get_iroot(  	struct xfs_btree_cur	*cur)  { -	struct xfs_ifork	*ifp; +	struct xfs_ifork	*ifp = xfs_btree_ifork_ptr(cur); -	ifp = XFS_IFORK_PTR(cur->bc_private.b.ip, cur->bc_private.b.whichfork);  	return (struct xfs_btree_block *)ifp->if_broot;  } @@ -881,13 +894,13 @@ xfs_btree_readahead_sblock(  	if ((lr & XFS_BTCUR_LEFTRA) && left != NULLAGBLOCK) { -		xfs_btree_reada_bufs(cur->bc_mp, cur->bc_private.a.agno, +		xfs_btree_reada_bufs(cur->bc_mp, cur->bc_ag.agno,  				     left, 1, cur->bc_ops->buf_ops);  		rval++;  	}  	if ((lr & XFS_BTCUR_RIGHTRA) && right != NULLAGBLOCK) { -		xfs_btree_reada_bufs(cur->bc_mp, cur->bc_private.a.agno, +		xfs_btree_reada_bufs(cur->bc_mp, cur->bc_ag.agno,  				     right, 1, cur->bc_ops->buf_ops);  		rval++;  	} @@ -945,7 +958,7 @@ xfs_btree_ptr_to_daddr(  		*daddr = XFS_FSB_TO_DADDR(cur->bc_mp, fsbno);  	} else {  		agbno = be32_to_cpu(ptr->s); -		*daddr = XFS_AGB_TO_DADDR(cur->bc_mp, cur->bc_private.a.agno, +		*daddr = XFS_AGB_TO_DADDR(cur->bc_mp, cur->bc_ag.agno,  				agbno);  	} @@ -1014,7 +1027,7 @@ xfs_btree_ptr_is_null(  		return ptr->s == cpu_to_be32(NULLAGBLOCK);  } -STATIC void +void  xfs_btree_set_ptr_null(  	struct xfs_btree_cur	*cur,  	union xfs_btree_ptr	*ptr) @@ -1050,7 +1063,7 @@ xfs_btree_get_sibling(  	}  } -STATIC void +void  xfs_btree_set_sibling(  	struct xfs_btree_cur	*cur,  	struct xfs_btree_block	*block, @@ -1128,7 +1141,7 @@ xfs_btree_init_block(  				 btnum, level, numrecs, owner, 0);  } -STATIC void +void  xfs_btree_init_block_cur(  	struct xfs_btree_cur	*cur,  	struct xfs_buf		*bp, @@ -1144,9 +1157,9 @@ xfs_btree_init_block_cur(  	 * code.  	 */  	if (cur->bc_flags & XFS_BTREE_LONG_PTRS) -		owner = cur->bc_private.b.ip->i_ino; +		owner = cur->bc_ino.ip->i_ino;  	else -		owner = cur->bc_private.a.agno; +		owner = cur->bc_ag.agno;  	xfs_btree_init_block_int(cur->bc_mp, XFS_BUF_TO_BLOCK(bp), bp->b_bn,  				 cur->bc_btnum, level, numrecs, @@ -1220,7 +1233,7 @@ xfs_btree_set_refs(  	}  } -STATIC int +int  xfs_btree_get_buf_block(  	struct xfs_btree_cur	*cur,  	union xfs_btree_ptr	*ptr, @@ -1280,7 +1293,7 @@ xfs_btree_read_buf_block(  /*   * Copy keys from one btree block to another.   */ -STATIC void +void  xfs_btree_copy_keys(  	struct xfs_btree_cur	*cur,  	union xfs_btree_key	*dst_key, @@ -1308,11 +1321,11 @@ xfs_btree_copy_recs(  /*   * Copy block pointers from one btree block to another.   */ -STATIC void +void  xfs_btree_copy_ptrs(  	struct xfs_btree_cur	*cur,  	union xfs_btree_ptr	*dst_ptr, -	union xfs_btree_ptr	*src_ptr, +	const union xfs_btree_ptr *src_ptr,  	int			numptrs)  {  	ASSERT(numptrs >= 0); @@ -1393,8 +1406,8 @@ xfs_btree_log_keys(  				  xfs_btree_key_offset(cur, first),  				  xfs_btree_key_offset(cur, last + 1) - 1);  	} else { -		xfs_trans_log_inode(cur->bc_tp, cur->bc_private.b.ip, -				xfs_ilog_fbroot(cur->bc_private.b.whichfork)); +		xfs_trans_log_inode(cur->bc_tp, cur->bc_ino.ip, +				xfs_ilog_fbroot(cur->bc_ino.whichfork));  	}  } @@ -1436,8 +1449,8 @@ xfs_btree_log_ptrs(  				xfs_btree_ptr_offset(cur, first, level),  				xfs_btree_ptr_offset(cur, last + 1, level) - 1);  	} else { -		xfs_trans_log_inode(cur->bc_tp, cur->bc_private.b.ip, -			xfs_ilog_fbroot(cur->bc_private.b.whichfork)); +		xfs_trans_log_inode(cur->bc_tp, cur->bc_ino.ip, +			xfs_ilog_fbroot(cur->bc_ino.whichfork));  	}  } @@ -1505,8 +1518,8 @@ xfs_btree_log_block(  		xfs_trans_buf_set_type(cur->bc_tp, bp, XFS_BLFT_BTREE_BUF);  		xfs_trans_log_buf(cur->bc_tp, bp, first, last);  	} else { -		xfs_trans_log_inode(cur->bc_tp, cur->bc_private.b.ip, -			xfs_ilog_fbroot(cur->bc_private.b.whichfork)); +		xfs_trans_log_inode(cur->bc_tp, cur->bc_ino.ip, +			xfs_ilog_fbroot(cur->bc_ino.whichfork));  	}  } @@ -1743,10 +1756,10 @@ xfs_btree_lookup_get_block(  	/* Check the inode owner since the verifiers don't. */  	if (xfs_sb_version_hascrc(&cur->bc_mp->m_sb) && -	    !(cur->bc_private.b.flags & XFS_BTCUR_BPRV_INVALID_OWNER) && +	    !(cur->bc_ino.flags & XFS_BTCUR_BMBT_INVALID_OWNER) &&  	    (cur->bc_flags & XFS_BTREE_LONG_PTRS) &&  	    be64_to_cpu((*blkp)->bb_u.l.bb_owner) != -			cur->bc_private.b.ip->i_ino) +			cur->bc_ino.ip->i_ino)  		goto out_bad;  	/* Did we get the level we were looking for? */ @@ -1762,7 +1775,7 @@ xfs_btree_lookup_get_block(  out_bad:  	*blkp = NULL; -	xfs_buf_corruption_error(bp); +	xfs_buf_mark_corrupt(bp);  	xfs_trans_brelse(cur->bc_tp, bp);  	return -EFSCORRUPTED;  } @@ -2938,9 +2951,9 @@ xfs_btree_new_iroot(  	xfs_btree_copy_ptrs(cur, pp, &nptr, 1); -	xfs_iroot_realloc(cur->bc_private.b.ip, +	xfs_iroot_realloc(cur->bc_ino.ip,  			  1 - xfs_btree_get_numrecs(cblock), -			  cur->bc_private.b.whichfork); +			  cur->bc_ino.whichfork);  	xfs_btree_setbuf(cur, level, cbp); @@ -2953,7 +2966,7 @@ xfs_btree_new_iroot(  	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); +		XFS_ILOG_CORE | xfs_ilog_fbroot(cur->bc_ino.whichfork);  	*stat = 1;  	return 0;  error0: @@ -3105,11 +3118,11 @@ xfs_btree_make_block_unfull(  	if ((cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) &&  	    level == cur->bc_nlevels - 1) { -		struct xfs_inode *ip = cur->bc_private.b.ip; +		struct xfs_inode *ip = cur->bc_ino.ip;  		if (numrecs < cur->bc_ops->get_dmaxrecs(cur, level)) {  			/* A root block that can be made bigger. */ -			xfs_iroot_realloc(ip, 1, cur->bc_private.b.whichfork); +			xfs_iroot_realloc(ip, 1, cur->bc_ino.whichfork);  			*stat = 1;  		} else {  			/* A root block that needs replacing */ @@ -3455,8 +3468,8 @@ STATIC int  xfs_btree_kill_iroot(  	struct xfs_btree_cur	*cur)  { -	int			whichfork = cur->bc_private.b.whichfork; -	struct xfs_inode	*ip = cur->bc_private.b.ip; +	int			whichfork = cur->bc_ino.whichfork; +	struct xfs_inode	*ip = cur->bc_ino.ip;  	struct xfs_ifork	*ifp = XFS_IFORK_PTR(ip, whichfork);  	struct xfs_btree_block	*block;  	struct xfs_btree_block	*cblock; @@ -3514,8 +3527,8 @@ xfs_btree_kill_iroot(  	index = numrecs - cur->bc_ops->get_maxrecs(cur, level);  	if (index) { -		xfs_iroot_realloc(cur->bc_private.b.ip, index, -				  cur->bc_private.b.whichfork); +		xfs_iroot_realloc(cur->bc_ino.ip, index, +				  cur->bc_ino.whichfork);  		block = ifp->if_broot;  	} @@ -3544,7 +3557,7 @@ xfs_btree_kill_iroot(  	cur->bc_bufs[level - 1] = NULL;  	be16_add_cpu(&block->bb_level, -1);  	xfs_trans_log_inode(cur->bc_tp, ip, -		XFS_ILOG_CORE | xfs_ilog_fbroot(cur->bc_private.b.whichfork)); +		XFS_ILOG_CORE | xfs_ilog_fbroot(cur->bc_ino.whichfork));  	cur->bc_nlevels--;  out0:  	return 0; @@ -3712,8 +3725,8 @@ xfs_btree_delrec(  	 */  	if (level == cur->bc_nlevels - 1) {  		if (cur->bc_flags & XFS_BTREE_ROOT_IN_INODE) { -			xfs_iroot_realloc(cur->bc_private.b.ip, -1, -					  cur->bc_private.b.whichfork); +			xfs_iroot_realloc(cur->bc_ino.ip, -1, +					  cur->bc_ino.whichfork);  			error = xfs_btree_kill_iroot(cur);  			if (error)  |