2727#include "xfs_ag_resv.h"
2828#include "xfs_bmap.h"
2929
30- extern struct kmem_cache * xfs_bmap_free_item_cache ;
30+ struct kmem_cache * xfs_extfree_item_cache ;
3131
3232struct workqueue_struct * xfs_alloc_wq ;
3333
@@ -2440,7 +2440,7 @@ xfs_agfl_reset(
24402440
24412441/*
24422442 * Defer an AGFL block free. This is effectively equivalent to
2443- * xfs_bmap_add_free () with some special handling particular to AGFL blocks.
2443+ * xfs_free_extent_later () with some special handling particular to AGFL blocks.
24442444 *
24452445 * Deferring AGFL frees helps prevent log reservation overruns due to too many
24462446 * allocation operations in a transaction. AGFL frees are prone to this problem
@@ -2459,10 +2459,10 @@ xfs_defer_agfl_block(
24592459 struct xfs_mount * mp = tp -> t_mountp ;
24602460 struct xfs_extent_free_item * new ; /* new element */
24612461
2462- ASSERT (xfs_bmap_free_item_cache != NULL );
2462+ ASSERT (xfs_extfree_item_cache != NULL );
24632463 ASSERT (oinfo != NULL );
24642464
2465- new = kmem_cache_alloc (xfs_bmap_free_item_cache ,
2465+ new = kmem_cache_alloc (xfs_extfree_item_cache ,
24662466 GFP_KERNEL | __GFP_NOFAIL );
24672467 new -> xefi_startblock = XFS_AGB_TO_FSB (mp , agno , agbno );
24682468 new -> xefi_blockcount = 1 ;
@@ -2474,6 +2474,52 @@ xfs_defer_agfl_block(
24742474 xfs_defer_add (tp , XFS_DEFER_OPS_TYPE_AGFL_FREE , & new -> xefi_list );
24752475}
24762476
2477+ /*
2478+ * Add the extent to the list of extents to be free at transaction end.
2479+ * The list is maintained sorted (by block number).
2480+ */
2481+ void
2482+ __xfs_free_extent_later (
2483+ struct xfs_trans * tp ,
2484+ xfs_fsblock_t bno ,
2485+ xfs_filblks_t len ,
2486+ const struct xfs_owner_info * oinfo ,
2487+ bool skip_discard )
2488+ {
2489+ struct xfs_extent_free_item * new ; /* new element */
2490+ #ifdef DEBUG
2491+ struct xfs_mount * mp = tp -> t_mountp ;
2492+ xfs_agnumber_t agno ;
2493+ xfs_agblock_t agbno ;
2494+
2495+ ASSERT (bno != NULLFSBLOCK );
2496+ ASSERT (len > 0 );
2497+ ASSERT (len <= MAXEXTLEN );
2498+ ASSERT (!isnullstartblock (bno ));
2499+ agno = XFS_FSB_TO_AGNO (mp , bno );
2500+ agbno = XFS_FSB_TO_AGBNO (mp , bno );
2501+ ASSERT (agno < mp -> m_sb .sb_agcount );
2502+ ASSERT (agbno < mp -> m_sb .sb_agblocks );
2503+ ASSERT (len < mp -> m_sb .sb_agblocks );
2504+ ASSERT (agbno + len <= mp -> m_sb .sb_agblocks );
2505+ #endif
2506+ ASSERT (xfs_extfree_item_cache != NULL );
2507+
2508+ new = kmem_cache_alloc (xfs_extfree_item_cache ,
2509+ GFP_KERNEL | __GFP_NOFAIL );
2510+ new -> xefi_startblock = bno ;
2511+ new -> xefi_blockcount = (xfs_extlen_t )len ;
2512+ if (oinfo )
2513+ new -> xefi_oinfo = * oinfo ;
2514+ else
2515+ new -> xefi_oinfo = XFS_RMAP_OINFO_SKIP_UPDATE ;
2516+ new -> xefi_skip_discard = skip_discard ;
2517+ trace_xfs_bmap_free_defer (tp -> t_mountp ,
2518+ XFS_FSB_TO_AGNO (tp -> t_mountp , bno ), 0 ,
2519+ XFS_FSB_TO_AGBNO (tp -> t_mountp , bno ), len );
2520+ xfs_defer_add (tp , XFS_DEFER_OPS_TYPE_FREE , & new -> xefi_list );
2521+ }
2522+
24772523#ifdef DEBUG
24782524/*
24792525 * Check if an AGF has a free extent record whose length is equal to
@@ -3499,3 +3545,20 @@ xfs_agfl_walk(
34993545
35003546 return 0 ;
35013547}
3548+
3549+ int __init
3550+ xfs_extfree_intent_init_cache (void )
3551+ {
3552+ xfs_extfree_item_cache = kmem_cache_create ("xfs_extfree_intent" ,
3553+ sizeof (struct xfs_extent_free_item ),
3554+ 0 , 0 , NULL );
3555+
3556+ return xfs_extfree_item_cache != NULL ? 0 : - ENOMEM ;
3557+ }
3558+
3559+ void
3560+ xfs_extfree_intent_destroy_cache (void )
3561+ {
3562+ kmem_cache_destroy (xfs_extfree_item_cache );
3563+ xfs_extfree_item_cache = NULL ;
3564+ }
0 commit comments