Skip to content

Commit

Permalink
xfs: rename xfs_bmap_add_free to xfs_free_extent_later
Browse files Browse the repository at this point in the history
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: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Chandan Babu R <chandan.babu@oracle.com>
  • Loading branch information
Darrick J. Wong committed Oct 22, 2021
1 parent f3c799c commit c201d9c
Show file tree
Hide file tree
Showing 12 changed files with 118 additions and 106 deletions.
2 changes: 1 addition & 1 deletion fs/xfs/libxfs/xfs_ag.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
71 changes: 67 additions & 4 deletions fs/xfs/libxfs/xfs_alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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
Expand All @@ -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;
Expand All @@ -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
Expand Down Expand Up @@ -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 changes: 32 additions & 0 deletions fs/xfs/libxfs/xfs_alloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -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__ */
55 changes: 2 additions & 53 deletions fs/xfs/libxfs/xfs_bmap.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
*/
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
28 changes: 0 additions & 28 deletions fs/xfs/libxfs/xfs_bmap.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*/
Expand Down Expand Up @@ -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

/*
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion fs/xfs/libxfs/xfs_bmap_btree.c
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ xfs_bmbt_free_block(
struct xfs_owner_info oinfo;

xfs_rmap_ino_bmbt_owner(&oinfo, ip->i_ino, cur->bc_ino.whichfork);
xfs_bmap_add_free(cur->bc_tp, fsbno, 1, &oinfo);
xfs_free_extent_later(cur->bc_tp, fsbno, 1, &oinfo);
ip->i_nblocks--;

xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
Expand Down
5 changes: 5 additions & 0 deletions fs/xfs/libxfs/xfs_defer.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "xfs_rmap.h"
#include "xfs_refcount.h"
#include "xfs_bmap.h"
#include "xfs_alloc.h"

static struct kmem_cache *xfs_defer_pending_cache;

Expand Down Expand Up @@ -848,6 +849,9 @@ xfs_defer_init_item_caches(void)
if (error)
goto err;
error = xfs_bmap_intent_init_cache();
if (error)
goto err;
error = xfs_extfree_intent_init_cache();
if (error)
goto err;

Expand All @@ -861,6 +865,7 @@ xfs_defer_init_item_caches(void)
void
xfs_defer_destroy_item_caches(void)
{
xfs_extfree_intent_destroy_cache();
xfs_bmap_intent_destroy_cache();
xfs_refcount_intent_destroy_cache();
xfs_rmap_intent_destroy_cache();
Expand Down
4 changes: 2 additions & 2 deletions fs/xfs/libxfs/xfs_ialloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1827,7 +1827,7 @@ xfs_difree_inode_chunk(

if (!xfs_inobt_issparse(rec->ir_holemask)) {
/* not sparse, calculate extent info directly */
xfs_bmap_add_free(tp, XFS_AGB_TO_FSB(mp, agno, sagbno),
xfs_free_extent_later(tp, XFS_AGB_TO_FSB(mp, agno, sagbno),
M_IGEO(mp)->ialloc_blks,
&XFS_RMAP_OINFO_INODES);
return;
Expand Down Expand Up @@ -1872,7 +1872,7 @@ xfs_difree_inode_chunk(

ASSERT(agbno % mp->m_sb.sb_spino_align == 0);
ASSERT(contigblk % mp->m_sb.sb_spino_align == 0);
xfs_bmap_add_free(tp, XFS_AGB_TO_FSB(mp, agno, agbno),
xfs_free_extent_later(tp, XFS_AGB_TO_FSB(mp, agno, agbno),
contigblk, &XFS_RMAP_OINFO_INODES);

/* reset range to current bit and carry on... */
Expand Down
6 changes: 3 additions & 3 deletions fs/xfs/libxfs/xfs_refcount.c
Original file line number Diff line number Diff line change
Expand Up @@ -976,7 +976,7 @@ xfs_refcount_adjust_extents(
fsbno = XFS_AGB_TO_FSB(cur->bc_mp,
cur->bc_ag.pag->pag_agno,
tmp.rc_startblock);
xfs_bmap_add_free(cur->bc_tp, fsbno,
xfs_free_extent_later(cur->bc_tp, fsbno,
tmp.rc_blockcount, oinfo);
}

Expand Down Expand Up @@ -1021,7 +1021,7 @@ xfs_refcount_adjust_extents(
fsbno = XFS_AGB_TO_FSB(cur->bc_mp,
cur->bc_ag.pag->pag_agno,
ext.rc_startblock);
xfs_bmap_add_free(cur->bc_tp, fsbno, ext.rc_blockcount,
xfs_free_extent_later(cur->bc_tp, fsbno, ext.rc_blockcount,
oinfo);
}

Expand Down Expand Up @@ -1744,7 +1744,7 @@ xfs_refcount_recover_cow_leftovers(
rr->rr_rrec.rc_blockcount);

/* Free the block. */
xfs_bmap_add_free(tp, fsb, rr->rr_rrec.rc_blockcount, NULL);
xfs_free_extent_later(tp, fsb, rr->rr_rrec.rc_blockcount, NULL);

error = xfs_trans_commit(tp);
if (error)
Expand Down
6 changes: 3 additions & 3 deletions fs/xfs/xfs_extfree_item.c
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,7 @@ xfs_extent_free_finish_item(
free->xefi_startblock,
free->xefi_blockcount,
&free->xefi_oinfo, free->xefi_skip_discard);
kmem_cache_free(xfs_bmap_free_item_cache, free);
kmem_cache_free(xfs_extfree_item_cache, free);
return error;
}

Expand All @@ -502,7 +502,7 @@ xfs_extent_free_cancel_item(
struct xfs_extent_free_item *free;

free = container_of(item, struct xfs_extent_free_item, xefi_list);
kmem_cache_free(xfs_bmap_free_item_cache, free);
kmem_cache_free(xfs_extfree_item_cache, free);
}

const struct xfs_defer_op_type xfs_extent_free_defer_type = {
Expand Down Expand Up @@ -564,7 +564,7 @@ xfs_agfl_free_finish_item(
extp->ext_len = free->xefi_blockcount;
efdp->efd_next_extent++;

kmem_cache_free(xfs_bmap_free_item_cache, free);
kmem_cache_free(xfs_extfree_item_cache, free);
return error;
}

Expand Down
Loading

0 comments on commit c201d9c

Please sign in to comment.