diff options
Diffstat (limited to 'fs/xfs/libxfs/xfs_bmap.c')
| -rw-r--r-- | fs/xfs/libxfs/xfs_bmap.c | 101 | 
1 files changed, 34 insertions, 67 deletions
| diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c index b48230f1a361..4dccd4d90622 100644 --- a/fs/xfs/libxfs/xfs_bmap.c +++ b/fs/xfs/libxfs/xfs_bmap.c @@ -37,8 +37,7 @@  #include "xfs_icache.h"  #include "xfs_iomap.h" - -kmem_zone_t		*xfs_bmap_free_item_zone; +struct kmem_cache		*xfs_bmap_intent_cache;  /*   * Miscellaneous helper functions @@ -93,6 +92,7 @@ xfs_bmap_compute_maxlevels(  			maxblocks = (maxblocks + minnoderecs - 1) / minnoderecs;  	}  	mp->m_bm_maxlevels[whichfork] = level; +	ASSERT(mp->m_bm_maxlevels[whichfork] <= xfs_bmbt_maxlevels_ondisk());  }  unsigned int @@ -239,11 +239,11 @@ xfs_bmap_get_bp(  	if (!cur)  		return NULL; -	for (i = 0; i < XFS_BTREE_MAXLEVELS; i++) { -		if (!cur->bc_bufs[i]) +	for (i = 0; i < cur->bc_maxlevels; 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 */ @@ -316,7 +316,7 @@ xfs_check_block(   */  STATIC void  xfs_bmap_check_leaf_extents( -	xfs_btree_cur_t		*cur,	/* btree cursor or null */ +	struct xfs_btree_cur	*cur,	/* btree cursor or null */  	xfs_inode_t		*ip,		/* incore inode pointer */  	int			whichfork)	/* data or attr fork */  { @@ -522,56 +522,6 @@ xfs_bmap_validate_ret(  #endif /* DEBUG */  /* - * bmap free list manipulation functions - */ - -/* - * Add the extent to the list of extents to be free at transaction end. - * The list is maintained sorted (by block number). - */ -void -__xfs_bmap_add_free( -	struct xfs_trans		*tp, -	xfs_fsblock_t			bno, -	xfs_filblks_t			len, -	const struct xfs_owner_info	*oinfo, -	bool				skip_discard) -{ -	struct xfs_extent_free_item	*new;		/* new element */ -#ifdef DEBUG -	struct xfs_mount		*mp = tp->t_mountp; -	xfs_agnumber_t			agno; -	xfs_agblock_t			agbno; - -	ASSERT(bno != NULLFSBLOCK); -	ASSERT(len > 0); -	ASSERT(len <= MAXEXTLEN); -	ASSERT(!isnullstartblock(bno)); -	agno = XFS_FSB_TO_AGNO(mp, bno); -	agbno = XFS_FSB_TO_AGBNO(mp, bno); -	ASSERT(agno < mp->m_sb.sb_agcount); -	ASSERT(agbno < mp->m_sb.sb_agblocks); -	ASSERT(len < mp->m_sb.sb_agblocks); -	ASSERT(agbno + len <= mp->m_sb.sb_agblocks); -#endif -	ASSERT(xfs_bmap_free_item_zone != NULL); - -	new = kmem_cache_alloc(xfs_bmap_free_item_zone, -			       GFP_KERNEL | __GFP_NOFAIL); -	new->xefi_startblock = bno; -	new->xefi_blockcount = (xfs_extlen_t)len; -	if (oinfo) -		new->xefi_oinfo = *oinfo; -	else -		new->xefi_oinfo = XFS_RMAP_OINFO_SKIP_UPDATE; -	new->xefi_skip_discard = skip_discard; -	trace_xfs_bmap_free_defer(tp->t_mountp, -			XFS_FSB_TO_AGNO(tp->t_mountp, bno), 0, -			XFS_FSB_TO_AGBNO(tp->t_mountp, bno), len); -	xfs_defer_add(tp, XFS_DEFER_OPS_TYPE_FREE, &new->xefi_list); -} - -/*   * Inode fork format manipulation functions   */ @@ -625,12 +575,12 @@ xfs_bmap_btree_to_extents(  	if ((error = xfs_btree_check_block(cur, cblock, 0, cbp)))  		return error;  	xfs_rmap_ino_bmbt_owner(&oinfo, ip->i_ino, whichfork); -	xfs_bmap_add_free(cur->bc_tp, cbno, 1, &oinfo); +	xfs_free_extent_later(cur->bc_tp, cbno, 1, &oinfo);  	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; @@ -925,7 +875,7 @@ xfs_bmap_add_attrfork_btree(  	int			*flags)		/* inode logging flags */  {  	struct xfs_btree_block	*block = ip->i_df.if_broot; -	xfs_btree_cur_t		*cur;		/* btree cursor */ +	struct xfs_btree_cur	*cur;		/* btree cursor */  	int			error;		/* error return value */  	xfs_mount_t		*mp;		/* file system mount struct */  	int			stat;		/* newroot status */ @@ -968,7 +918,7 @@ xfs_bmap_add_attrfork_extents(  	struct xfs_inode	*ip,		/* incore inode pointer */  	int			*flags)		/* inode logging flags */  { -	xfs_btree_cur_t		*cur;		/* bmap btree cursor */ +	struct xfs_btree_cur	*cur;		/* bmap btree cursor */  	int			error;		/* error return value */  	if (ip->i_df.if_nextents * sizeof(struct xfs_bmbt_rec) <= @@ -1988,11 +1938,11 @@ xfs_bmap_add_extent_unwritten_real(  	xfs_inode_t		*ip,	/* incore inode pointer */  	int			whichfork,  	struct xfs_iext_cursor	*icur, -	xfs_btree_cur_t		**curp,	/* if *curp is null, not a btree */ +	struct xfs_btree_cur	**curp,	/* if *curp is null, not a btree */  	xfs_bmbt_irec_t		*new,	/* new data to add to file extents */  	int			*logflagsp) /* inode logging flags */  { -	xfs_btree_cur_t		*cur;	/* btree cursor */ +	struct xfs_btree_cur	*cur;	/* btree cursor */  	int			error;	/* error return value */  	int			i;	/* temp state */  	struct xfs_ifork	*ifp;	/* inode fork pointer */ @@ -5045,7 +4995,7 @@ xfs_bmap_del_extent_real(  	xfs_inode_t		*ip,	/* incore inode pointer */  	xfs_trans_t		*tp,	/* current transaction pointer */  	struct xfs_iext_cursor	*icur, -	xfs_btree_cur_t		*cur,	/* if null, not a btree */ +	struct xfs_btree_cur	*cur,	/* if null, not a btree */  	xfs_bmbt_irec_t		*del,	/* data to remove from extents */  	int			*logflagsp, /* inode logging flags */  	int			whichfork, /* data or attr fork */ @@ -5296,7 +5246,7 @@ xfs_bmap_del_extent_real(  		if (xfs_is_reflink_inode(ip) && whichfork == XFS_DATA_FORK) {  			xfs_refcount_decrease_extent(tp, del);  		} else { -			__xfs_bmap_add_free(tp, del->br_startblock, +			__xfs_free_extent_later(tp, del->br_startblock,  					del->br_blockcount, NULL,  					(bflags & XFS_BMAPI_NODISCARD) ||  					del->br_state == XFS_EXT_UNWRITTEN); @@ -6189,7 +6139,7 @@ __xfs_bmap_add(  			bmap->br_blockcount,  			bmap->br_state); -	bi = kmem_alloc(sizeof(struct xfs_bmap_intent), KM_NOFS); +	bi = kmem_cache_alloc(xfs_bmap_intent_cache, GFP_NOFS | __GFP_NOFAIL);  	INIT_LIST_HEAD(&bi->bi_list);  	bi->bi_type = type;  	bi->bi_owner = ip; @@ -6300,3 +6250,20 @@ xfs_bmap_validate_extent(  		return __this_address;  	return NULL;  } + +int __init +xfs_bmap_intent_init_cache(void) +{ +	xfs_bmap_intent_cache = kmem_cache_create("xfs_bmap_intent", +			sizeof(struct xfs_bmap_intent), +			0, 0, NULL); + +	return xfs_bmap_intent_cache != NULL ? 0 : -ENOMEM; +} + +void +xfs_bmap_intent_destroy_cache(void) +{ +	kmem_cache_destroy(xfs_bmap_intent_cache); +	xfs_bmap_intent_cache = NULL; +} |