Commit c201d9ca authored by Darrick J. Wong's avatar Darrick J. Wong
Browse files

xfs: rename xfs_bmap_add_free to xfs_free_extent_later



xfs_bmap_add_free isn't a block mapping function; it schedules deferred
freeing operations for a later point in a compound transaction chain.
While it's primarily used by bunmapi, its use has expanded beyond that.
Move it to xfs_alloc.c and rename the function since it's now general
freeing functionality.  Bring the slab cache bits in line with the
way we handle the other intent items.

Signed-off-by: default avatarDarrick J. Wong <djwong@kernel.org>
Reviewed-by: default avatarChandan Babu R <chandan.babu@oracle.com>
parent f3c799c2
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -850,7 +850,7 @@ xfs_ag_shrink_space(
		if (err2 != -ENOSPC)
			goto resv_err;

		__xfs_bmap_add_free(*tpp, args.fsbno, delta, NULL, true);
		__xfs_free_extent_later(*tpp, args.fsbno, delta, NULL, true);

		/*
		 * Roll the transaction before trying to re-init the per-ag
+67 −4
Original line number Diff line number Diff line
@@ -27,7 +27,7 @@
#include "xfs_ag_resv.h"
#include "xfs_bmap.h"

extern struct kmem_cache	*xfs_bmap_free_item_cache;
struct kmem_cache	*xfs_extfree_item_cache;

struct workqueue_struct *xfs_alloc_wq;

@@ -2440,7 +2440,7 @@ xfs_agfl_reset(

/*
 * Defer an AGFL block free. This is effectively equivalent to
 * xfs_bmap_add_free() with some special handling particular to AGFL blocks.
 * xfs_free_extent_later() with some special handling particular to AGFL blocks.
 *
 * Deferring AGFL frees helps prevent log reservation overruns due to too many
 * allocation operations in a transaction. AGFL frees are prone to this problem
@@ -2459,10 +2459,10 @@ xfs_defer_agfl_block(
	struct xfs_mount		*mp = tp->t_mountp;
	struct xfs_extent_free_item	*new;		/* new element */

	ASSERT(xfs_bmap_free_item_cache != NULL);
	ASSERT(xfs_extfree_item_cache != NULL);
	ASSERT(oinfo != NULL);

	new = kmem_cache_alloc(xfs_bmap_free_item_cache,
	new = kmem_cache_alloc(xfs_extfree_item_cache,
			       GFP_KERNEL | __GFP_NOFAIL);
	new->xefi_startblock = XFS_AGB_TO_FSB(mp, agno, agbno);
	new->xefi_blockcount = 1;
@@ -2474,6 +2474,52 @@ xfs_defer_agfl_block(
	xfs_defer_add(tp, XFS_DEFER_OPS_TYPE_AGFL_FREE, &new->xefi_list);
}

/*
 * Add the extent to the list of extents to be free at transaction end.
 * The list is maintained sorted (by block number).
 */
void
__xfs_free_extent_later(
	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_extfree_item_cache != NULL);

	new = kmem_cache_alloc(xfs_extfree_item_cache,
			       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);
}

#ifdef DEBUG
/*
 * Check if an AGF has a free extent record whose length is equal to
@@ -3499,3 +3545,20 @@ xfs_agfl_walk(

	return 0;
}

int __init
xfs_extfree_intent_init_cache(void)
{
	xfs_extfree_item_cache = kmem_cache_create("xfs_extfree_intent",
			sizeof(struct xfs_extent_free_item),
			0, 0, NULL);

	return xfs_extfree_item_cache != NULL ? 0 : -ENOMEM;
}

void
xfs_extfree_intent_destroy_cache(void)
{
	kmem_cache_destroy(xfs_extfree_item_cache);
	xfs_extfree_item_cache = NULL;
}
+32 −0
Original line number Diff line number Diff line
@@ -248,4 +248,36 @@ xfs_buf_to_agfl_bno(
	return bp->b_addr;
}

void __xfs_free_extent_later(struct xfs_trans *tp, xfs_fsblock_t bno,
		xfs_filblks_t len, const struct xfs_owner_info *oinfo,
		bool skip_discard);

/*
 * List of extents to be free "later".
 * The list is kept sorted on xbf_startblock.
 */
struct xfs_extent_free_item {
	struct list_head	xefi_list;
	xfs_fsblock_t		xefi_startblock;/* starting fs block number */
	xfs_extlen_t		xefi_blockcount;/* number of blocks in extent */
	bool			xefi_skip_discard;
	struct xfs_owner_info	xefi_oinfo;	/* extent owner */
};

static inline void
xfs_free_extent_later(
	struct xfs_trans		*tp,
	xfs_fsblock_t			bno,
	xfs_filblks_t			len,
	const struct xfs_owner_info	*oinfo)
{
	__xfs_free_extent_later(tp, bno, len, oinfo, false);
}


extern struct kmem_cache	*xfs_extfree_item_cache;

int __init xfs_extfree_intent_init_cache(void);
void xfs_extfree_intent_destroy_cache(void);

#endif	/* __XFS_ALLOC_H__ */
+2 −53
Original line number Diff line number Diff line
@@ -38,7 +38,6 @@
#include "xfs_iomap.h"

struct kmem_cache		*xfs_bmap_intent_cache;
struct kmem_cache		*xfs_bmap_free_item_cache;

/*
 * Miscellaneous helper functions
@@ -522,56 +521,6 @@ xfs_bmap_validate_ret(
#define	xfs_bmap_validate_ret(bno,len,flags,mval,onmap,nmap)	do { } while (0)
#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_cache != NULL);

	new = kmem_cache_alloc(xfs_bmap_free_item_cache,
			       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
 */
@@ -626,7 +575,7 @@ 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);
@@ -5297,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);
+0 −28
Original line number Diff line number Diff line
@@ -13,8 +13,6 @@ struct xfs_inode;
struct xfs_mount;
struct xfs_trans;

extern struct kmem_cache	*xfs_bmap_free_item_cache;

/*
 * Argument structure for xfs_bmap_alloc.
 */
@@ -44,19 +42,6 @@ struct xfs_bmalloca {
	int			flags;
};

/*
 * List of extents to be free "later".
 * The list is kept sorted on xbf_startblock.
 */
struct xfs_extent_free_item
{
	xfs_fsblock_t		xefi_startblock;/* starting fs block number */
	xfs_extlen_t		xefi_blockcount;/* number of blocks in extent */
	bool			xefi_skip_discard;
	struct list_head	xefi_list;
	struct xfs_owner_info	xefi_oinfo;	/* extent owner */
};

#define	XFS_BMAP_MAX_NMAP	4

/*
@@ -189,9 +174,6 @@ unsigned int xfs_bmap_compute_attr_offset(struct xfs_mount *mp);
int	xfs_bmap_add_attrfork(struct xfs_inode *ip, int size, int rsvd);
void	xfs_bmap_local_to_extents_empty(struct xfs_trans *tp,
		struct xfs_inode *ip, int whichfork);
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);
void	xfs_bmap_compute_maxlevels(struct xfs_mount *mp, int whichfork);
int	xfs_bmap_first_unused(struct xfs_trans *tp, struct xfs_inode *ip,
		xfs_extlen_t len, xfs_fileoff_t *unused, int whichfork);
@@ -239,16 +221,6 @@ int xfs_bmap_add_extent_unwritten_real(struct xfs_trans *tp,
		struct xfs_iext_cursor *icur, struct xfs_btree_cur **curp,
		struct xfs_bmbt_irec *new, int *logflagsp);

static inline void
xfs_bmap_add_free(
	struct xfs_trans		*tp,
	xfs_fsblock_t			bno,
	xfs_filblks_t			len,
	const struct xfs_owner_info	*oinfo)
{
	__xfs_bmap_add_free(tp, bno, len, oinfo, false);
}

enum xfs_bmap_intent_type {
	XFS_BMAP_MAP = 1,
	XFS_BMAP_UNMAP,
Loading