Skip to content

Commit 06e4e94

Browse files
author
Chandan Babu R
committed
Merge tag 'extfree-intent-cleanups-6.11_2024-07-02' of https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux into xfs-6.11-mergeB
xfs: extent free log intent cleanups This series cleans up some warts in the extent freeing log intent code. We start by acknowledging that this mechanism does not have anything to do with the bmap code by moving it to xfs_alloc.c and giving the function a more descriptive name. Then we clean up the tracepoints and the _finish_one call paths to pass the intent structure around. This reduces the overhead when the tracepoints are disabled and will make things much cleaner when we start adding realtime support in the next patch. I also incorporated a bunch of cleanups from Christoph Hellwig. Signed-off-by: Darrick J. Wong <[email protected]> Signed-off-by: Chandan Babu R <[email protected]> * tag 'extfree-intent-cleanups-6.11_2024-07-02' of https://git.kernel.org/pub/scm/linux/kernel/git/djwong/xfs-linux: xfs: move xfs_extent_free_defer_add to xfs_extfree_item.c xfs: remove xfs_defer_agfl_block xfs: remove duplicate asserts in xfs_defer_extent_free xfs: factor out a xfs_efd_add_extent helper xfs: reuse xfs_extent_free_cancel_item xfs: add a xefi_entry helper xfs: pass the fsbno to xfs_perag_intent_get xfs: convert "skip_discard" to a proper flags bitset xfs: clean up extent free log intent item tracepoint callsites
2 parents 2f6ebd4 + 84a3c15 commit 06e4e94

20 files changed

+141
-192
lines changed

fs/xfs/libxfs/xfs_ag.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1008,7 +1008,7 @@ xfs_ag_shrink_space(
10081008
goto resv_err;
10091009

10101010
err2 = xfs_free_extent_later(*tpp, args.fsbno, delta, NULL,
1011-
XFS_AG_RESV_NONE, true);
1011+
XFS_AG_RESV_NONE, XFS_FREE_EXTENT_SKIP_DISCARD);
10121012
if (err2)
10131013
goto resv_err;
10141014

fs/xfs/libxfs/xfs_alloc.c

Lines changed: 24 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "xfs_ag_resv.h"
2828
#include "xfs_bmap.h"
2929
#include "xfs_health.h"
30+
#include "xfs_extfree_item.h"
3031

3132
struct kmem_cache *xfs_extfree_item_cache;
3233

@@ -2509,48 +2510,6 @@ xfs_agfl_reset(
25092510
clear_bit(XFS_AGSTATE_AGFL_NEEDS_RESET, &pag->pag_opstate);
25102511
}
25112512

2512-
/*
2513-
* Defer an AGFL block free. This is effectively equivalent to
2514-
* xfs_free_extent_later() with some special handling particular to AGFL blocks.
2515-
*
2516-
* Deferring AGFL frees helps prevent log reservation overruns due to too many
2517-
* allocation operations in a transaction. AGFL frees are prone to this problem
2518-
* because for one they are always freed one at a time. Further, an immediate
2519-
* AGFL block free can cause a btree join and require another block free before
2520-
* the real allocation can proceed. Deferring the free disconnects freeing up
2521-
* the AGFL slot from freeing the block.
2522-
*/
2523-
static int
2524-
xfs_defer_agfl_block(
2525-
struct xfs_trans *tp,
2526-
xfs_agnumber_t agno,
2527-
xfs_agblock_t agbno,
2528-
struct xfs_owner_info *oinfo)
2529-
{
2530-
struct xfs_mount *mp = tp->t_mountp;
2531-
struct xfs_extent_free_item *xefi;
2532-
xfs_fsblock_t fsbno = XFS_AGB_TO_FSB(mp, agno, agbno);
2533-
2534-
ASSERT(xfs_extfree_item_cache != NULL);
2535-
ASSERT(oinfo != NULL);
2536-
2537-
if (XFS_IS_CORRUPT(mp, !xfs_verify_fsbno(mp, fsbno)))
2538-
return -EFSCORRUPTED;
2539-
2540-
xefi = kmem_cache_zalloc(xfs_extfree_item_cache,
2541-
GFP_KERNEL | __GFP_NOFAIL);
2542-
xefi->xefi_startblock = fsbno;
2543-
xefi->xefi_blockcount = 1;
2544-
xefi->xefi_owner = oinfo->oi_owner;
2545-
xefi->xefi_agresv = XFS_AG_RESV_AGFL;
2546-
2547-
trace_xfs_agfl_free_defer(mp, agno, 0, agbno, 1);
2548-
2549-
xfs_extent_free_get_group(mp, xefi);
2550-
xfs_defer_add(tp, &xefi->xefi_list, &xfs_agfl_free_defer_type);
2551-
return 0;
2552-
}
2553-
25542513
/*
25552514
* Add the extent to the list of extents to be free at transaction end.
25562515
* The list is maintained sorted (by block number).
@@ -2562,28 +2521,15 @@ xfs_defer_extent_free(
25622521
xfs_filblks_t len,
25632522
const struct xfs_owner_info *oinfo,
25642523
enum xfs_ag_resv_type type,
2565-
bool skip_discard,
2524+
unsigned int free_flags,
25662525
struct xfs_defer_pending **dfpp)
25672526
{
25682527
struct xfs_extent_free_item *xefi;
25692528
struct xfs_mount *mp = tp->t_mountp;
2570-
#ifdef DEBUG
2571-
xfs_agnumber_t agno;
2572-
xfs_agblock_t agbno;
25732529

2574-
ASSERT(bno != NULLFSBLOCK);
2575-
ASSERT(len > 0);
25762530
ASSERT(len <= XFS_MAX_BMBT_EXTLEN);
25772531
ASSERT(!isnullstartblock(bno));
2578-
agno = XFS_FSB_TO_AGNO(mp, bno);
2579-
agbno = XFS_FSB_TO_AGBNO(mp, bno);
2580-
ASSERT(agno < mp->m_sb.sb_agcount);
2581-
ASSERT(agbno < mp->m_sb.sb_agblocks);
2582-
ASSERT(len < mp->m_sb.sb_agblocks);
2583-
ASSERT(agbno + len <= mp->m_sb.sb_agblocks);
2584-
#endif
2585-
ASSERT(xfs_extfree_item_cache != NULL);
2586-
ASSERT(type != XFS_AG_RESV_AGFL);
2532+
ASSERT(!(free_flags & ~XFS_FREE_EXTENT_ALL_FLAGS));
25872533

25882534
if (XFS_IS_CORRUPT(mp, !xfs_verify_fsbext(mp, bno, len)))
25892535
return -EFSCORRUPTED;
@@ -2593,7 +2539,7 @@ xfs_defer_extent_free(
25932539
xefi->xefi_startblock = bno;
25942540
xefi->xefi_blockcount = (xfs_extlen_t)len;
25952541
xefi->xefi_agresv = type;
2596-
if (skip_discard)
2542+
if (free_flags & XFS_FREE_EXTENT_SKIP_DISCARD)
25972543
xefi->xefi_flags |= XFS_EFI_SKIP_DISCARD;
25982544
if (oinfo) {
25992545
ASSERT(oinfo->oi_offset == 0);
@@ -2606,12 +2552,8 @@ xfs_defer_extent_free(
26062552
} else {
26072553
xefi->xefi_owner = XFS_RMAP_OWN_NULL;
26082554
}
2609-
trace_xfs_bmap_free_defer(mp,
2610-
XFS_FSB_TO_AGNO(tp->t_mountp, bno), 0,
2611-
XFS_FSB_TO_AGBNO(tp->t_mountp, bno), len);
26122555

2613-
xfs_extent_free_get_group(mp, xefi);
2614-
*dfpp = xfs_defer_add(tp, &xefi->xefi_list, &xfs_extent_free_defer_type);
2556+
xfs_extent_free_defer_add(tp, xefi, dfpp);
26152557
return 0;
26162558
}
26172559

@@ -2622,11 +2564,11 @@ xfs_free_extent_later(
26222564
xfs_filblks_t len,
26232565
const struct xfs_owner_info *oinfo,
26242566
enum xfs_ag_resv_type type,
2625-
bool skip_discard)
2567+
unsigned int free_flags)
26262568
{
26272569
struct xfs_defer_pending *dontcare = NULL;
26282570

2629-
return xfs_defer_extent_free(tp, bno, len, oinfo, type, skip_discard,
2571+
return xfs_defer_extent_free(tp, bno, len, oinfo, type, free_flags,
26302572
&dontcare);
26312573
}
26322574

@@ -2651,13 +2593,13 @@ xfs_free_extent_later(
26512593
int
26522594
xfs_alloc_schedule_autoreap(
26532595
const struct xfs_alloc_arg *args,
2654-
bool skip_discard,
2596+
unsigned int free_flags,
26552597
struct xfs_alloc_autoreap *aarp)
26562598
{
26572599
int error;
26582600

26592601
error = xfs_defer_extent_free(args->tp, args->fsbno, args->len,
2660-
&args->oinfo, args->resv, skip_discard, &aarp->dfp);
2602+
&args->oinfo, args->resv, free_flags, &aarp->dfp);
26612603
if (error)
26622604
return error;
26632605

@@ -2869,8 +2811,21 @@ xfs_alloc_fix_freelist(
28692811
if (error)
28702812
goto out_agbp_relse;
28712813

2872-
/* defer agfl frees */
2873-
error = xfs_defer_agfl_block(tp, args->agno, bno, &targs.oinfo);
2814+
/*
2815+
* Defer the AGFL block free.
2816+
*
2817+
* This helps to prevent log reservation overruns due to too
2818+
* many allocation operations in a transaction. AGFL frees are
2819+
* prone to this problem because for one they are always freed
2820+
* one at a time. Further, an immediate AGFL block free can
2821+
* cause a btree join and require another block free before the
2822+
* real allocation can proceed.
2823+
* Deferring the free disconnects freeing up the AGFL slot from
2824+
* freeing the block.
2825+
*/
2826+
error = xfs_free_extent_later(tp,
2827+
XFS_AGB_TO_FSB(mp, args->agno, bno), 1,
2828+
&targs.oinfo, XFS_AG_RESV_AGFL, 0);
28742829
if (error)
28752830
goto out_agbp_relse;
28762831
}

fs/xfs/libxfs/xfs_alloc.h

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,12 @@ xfs_buf_to_agfl_bno(
235235

236236
int xfs_free_extent_later(struct xfs_trans *tp, xfs_fsblock_t bno,
237237
xfs_filblks_t len, const struct xfs_owner_info *oinfo,
238-
enum xfs_ag_resv_type type, bool skip_discard);
238+
enum xfs_ag_resv_type type, unsigned int free_flags);
239+
240+
/* Don't issue a discard for the blocks freed. */
241+
#define XFS_FREE_EXTENT_SKIP_DISCARD (1U << 0)
242+
243+
#define XFS_FREE_EXTENT_ALL_FLAGS (XFS_FREE_EXTENT_SKIP_DISCARD)
239244

240245
/*
241246
* List of extents to be free "later".
@@ -251,9 +256,6 @@ struct xfs_extent_free_item {
251256
enum xfs_ag_resv_type xefi_agresv;
252257
};
253258

254-
void xfs_extent_free_get_group(struct xfs_mount *mp,
255-
struct xfs_extent_free_item *xefi);
256-
257259
#define XFS_EFI_SKIP_DISCARD (1U << 0) /* don't issue discard */
258260
#define XFS_EFI_ATTR_FORK (1U << 1) /* freeing attr fork block */
259261
#define XFS_EFI_BMBT_BLOCK (1U << 2) /* freeing bmap btree block */
@@ -264,7 +266,7 @@ struct xfs_alloc_autoreap {
264266
};
265267

266268
int xfs_alloc_schedule_autoreap(const struct xfs_alloc_arg *args,
267-
bool skip_discard, struct xfs_alloc_autoreap *aarp);
269+
unsigned int free_flags, struct xfs_alloc_autoreap *aarp);
268270
void xfs_alloc_cancel_autoreap(struct xfs_trans *tp,
269271
struct xfs_alloc_autoreap *aarp);
270272
void xfs_alloc_commit_autoreap(struct xfs_trans *tp,

fs/xfs/libxfs/xfs_bmap.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -605,7 +605,7 @@ xfs_bmap_btree_to_extents(
605605

606606
xfs_rmap_ino_bmbt_owner(&oinfo, ip->i_ino, whichfork);
607607
error = xfs_free_extent_later(cur->bc_tp, cbno, 1, &oinfo,
608-
XFS_AG_RESV_NONE, false);
608+
XFS_AG_RESV_NONE, 0);
609609
if (error)
610610
return error;
611611

@@ -5381,11 +5381,15 @@ xfs_bmap_del_extent_real(
53815381
error = xfs_rtfree_blocks(tp, del->br_startblock,
53825382
del->br_blockcount);
53835383
} else {
5384+
unsigned int efi_flags = 0;
5385+
5386+
if ((bflags & XFS_BMAPI_NODISCARD) ||
5387+
del->br_state == XFS_EXT_UNWRITTEN)
5388+
efi_flags |= XFS_FREE_EXTENT_SKIP_DISCARD;
5389+
53845390
error = xfs_free_extent_later(tp, del->br_startblock,
53855391
del->br_blockcount, NULL,
5386-
XFS_AG_RESV_NONE,
5387-
((bflags & XFS_BMAPI_NODISCARD) ||
5388-
del->br_state == XFS_EXT_UNWRITTEN));
5392+
XFS_AG_RESV_NONE, efi_flags);
53895393
}
53905394
if (error)
53915395
return error;

fs/xfs/libxfs/xfs_bmap_btree.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ xfs_bmbt_free_block(
282282

283283
xfs_rmap_ino_bmbt_owner(&oinfo, ip->i_ino, cur->bc_ino.whichfork);
284284
error = xfs_free_extent_later(cur->bc_tp, fsbno, 1, &oinfo,
285-
XFS_AG_RESV_NONE, false);
285+
XFS_AG_RESV_NONE, 0);
286286
if (error)
287287
return error;
288288

fs/xfs/libxfs/xfs_ialloc.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1990,7 +1990,7 @@ xfs_difree_inode_chunk(
19901990
return xfs_free_extent_later(tp,
19911991
XFS_AGB_TO_FSB(mp, agno, sagbno),
19921992
M_IGEO(mp)->ialloc_blks, &XFS_RMAP_OINFO_INODES,
1993-
XFS_AG_RESV_NONE, false);
1993+
XFS_AG_RESV_NONE, 0);
19941994
}
19951995

19961996
/* holemask is only 16-bits (fits in an unsigned long) */
@@ -2036,8 +2036,7 @@ xfs_difree_inode_chunk(
20362036
ASSERT(contigblk % mp->m_sb.sb_spino_align == 0);
20372037
error = xfs_free_extent_later(tp,
20382038
XFS_AGB_TO_FSB(mp, agno, agbno), contigblk,
2039-
&XFS_RMAP_OINFO_INODES, XFS_AG_RESV_NONE,
2040-
false);
2039+
&XFS_RMAP_OINFO_INODES, XFS_AG_RESV_NONE, 0);
20412040
if (error)
20422041
return error;
20432042

fs/xfs/libxfs/xfs_ialloc_btree.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ __xfs_inobt_free_block(
170170
xfs_inobt_mod_blockcount(cur, -1);
171171
fsbno = XFS_DADDR_TO_FSB(cur->bc_mp, xfs_buf_daddr(bp));
172172
return xfs_free_extent_later(cur->bc_tp, fsbno, 1,
173-
&XFS_RMAP_OINFO_INOBT, resv, false);
173+
&XFS_RMAP_OINFO_INOBT, resv, 0);
174174
}
175175

176176
STATIC int

fs/xfs/libxfs/xfs_refcount.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1173,7 +1173,7 @@ xfs_refcount_adjust_extents(
11731173
tmp.rc_startblock);
11741174
error = xfs_free_extent_later(cur->bc_tp, fsbno,
11751175
tmp.rc_blockcount, NULL,
1176-
XFS_AG_RESV_NONE, false);
1176+
XFS_AG_RESV_NONE, 0);
11771177
if (error)
11781178
goto out_error;
11791179
}
@@ -1237,7 +1237,7 @@ xfs_refcount_adjust_extents(
12371237
ext.rc_startblock);
12381238
error = xfs_free_extent_later(cur->bc_tp, fsbno,
12391239
ext.rc_blockcount, NULL,
1240-
XFS_AG_RESV_NONE, false);
1240+
XFS_AG_RESV_NONE, 0);
12411241
if (error)
12421242
goto out_error;
12431243
}
@@ -2022,7 +2022,7 @@ xfs_refcount_recover_cow_leftovers(
20222022
/* Free the block. */
20232023
error = xfs_free_extent_later(tp, fsb,
20242024
rr->rr_rrec.rc_blockcount, NULL,
2025-
XFS_AG_RESV_NONE, false);
2025+
XFS_AG_RESV_NONE, 0);
20262026
if (error)
20272027
goto out_trans;
20282028

fs/xfs/libxfs/xfs_refcount_btree.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ xfs_refcountbt_free_block(
109109
be32_add_cpu(&agf->agf_refcount_blocks, -1);
110110
xfs_alloc_log_agf(cur->bc_tp, agbp, XFS_AGF_REFCOUNT_BLOCKS);
111111
return xfs_free_extent_later(cur->bc_tp, fsbno, 1,
112-
&XFS_RMAP_OINFO_REFC, XFS_AG_RESV_METADATA, false);
112+
&XFS_RMAP_OINFO_REFC, XFS_AG_RESV_METADATA, 0);
113113
}
114114

115115
STATIC int

fs/xfs/scrub/newbt.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,8 @@ xrep_newbt_add_blocks(
160160
if (args->tp) {
161161
ASSERT(xnr->oinfo.oi_offset == 0);
162162

163-
error = xfs_alloc_schedule_autoreap(args, true, &resv->autoreap);
163+
error = xfs_alloc_schedule_autoreap(args,
164+
XFS_FREE_EXTENT_SKIP_DISCARD, &resv->autoreap);
164165
if (error)
165166
goto out_pag;
166167
}
@@ -414,7 +415,7 @@ xrep_newbt_free_extent(
414415
*/
415416
fsbno = XFS_AGB_TO_FSB(sc->mp, resv->pag->pag_agno, free_agbno);
416417
error = xfs_free_extent_later(sc->tp, fsbno, free_aglen, &xnr->oinfo,
417-
xnr->resv, true);
418+
xnr->resv, XFS_FREE_EXTENT_SKIP_DISCARD);
418419
if (error)
419420
return error;
420421

0 commit comments

Comments
 (0)