@@ -350,10 +350,7 @@ xfs_trans_free_extent(
350350 struct xfs_owner_info oinfo = { };
351351 struct xfs_mount * mp = tp -> t_mountp ;
352352 struct xfs_extent * extp ;
353- struct xfs_perag * pag ;
354353 uint next_extent ;
355- xfs_agnumber_t agno = XFS_FSB_TO_AGNO (mp ,
356- xefi -> xefi_startblock );
357354 xfs_agblock_t agbno = XFS_FSB_TO_AGBNO (mp ,
358355 xefi -> xefi_startblock );
359356 int error ;
@@ -364,14 +361,12 @@ xfs_trans_free_extent(
364361 if (xefi -> xefi_flags & XFS_EFI_BMBT_BLOCK )
365362 oinfo .oi_flags |= XFS_OWNER_INFO_BMBT_BLOCK ;
366363
367- trace_xfs_bmap_free_deferred (tp -> t_mountp , agno , 0 , agbno ,
368- xefi -> xefi_blockcount );
364+ trace_xfs_bmap_free_deferred (tp -> t_mountp , xefi -> xefi_pag -> pag_agno , 0 ,
365+ agbno , xefi -> xefi_blockcount );
369366
370- pag = xfs_perag_get (mp , agno );
371- error = __xfs_free_extent (tp , pag , agbno , xefi -> xefi_blockcount ,
372- & oinfo , xefi -> xefi_agresv ,
367+ error = __xfs_free_extent (tp , xefi -> xefi_pag , agbno ,
368+ xefi -> xefi_blockcount , & oinfo , xefi -> xefi_agresv ,
373369 xefi -> xefi_flags & XFS_EFI_SKIP_DISCARD );
374- xfs_perag_put (pag );
375370
376371 /*
377372 * Mark the transaction dirty, even on error. This ensures the
@@ -400,14 +395,13 @@ xfs_extent_free_diff_items(
400395 const struct list_head * a ,
401396 const struct list_head * b )
402397{
403- struct xfs_mount * mp = priv ;
404398 struct xfs_extent_free_item * ra ;
405399 struct xfs_extent_free_item * rb ;
406400
407401 ra = container_of (a , struct xfs_extent_free_item , xefi_list );
408402 rb = container_of (b , struct xfs_extent_free_item , xefi_list );
409- return XFS_FSB_TO_AGNO ( mp , ra -> xefi_startblock ) -
410- XFS_FSB_TO_AGNO ( mp , rb -> xefi_startblock ) ;
403+
404+ return ra -> xefi_pag -> pag_agno - rb -> xefi_pag -> pag_agno ;
411405}
412406
413407/* Log a free extent to the intent item. */
@@ -466,6 +460,26 @@ xfs_extent_free_create_done(
466460 return & xfs_trans_get_efd (tp , EFI_ITEM (intent ), count )-> efd_item ;
467461}
468462
463+ /* Take a passive ref to the AG containing the space we're freeing. */
464+ void
465+ xfs_extent_free_get_group (
466+ struct xfs_mount * mp ,
467+ struct xfs_extent_free_item * xefi )
468+ {
469+ xfs_agnumber_t agno ;
470+
471+ agno = XFS_FSB_TO_AGNO (mp , xefi -> xefi_startblock );
472+ xefi -> xefi_pag = xfs_perag_get (mp , agno );
473+ }
474+
475+ /* Release a passive AG ref after some freeing work. */
476+ static inline void
477+ xfs_extent_free_put_group (
478+ struct xfs_extent_free_item * xefi )
479+ {
480+ xfs_perag_put (xefi -> xefi_pag );
481+ }
482+
469483/* Process a free extent. */
470484STATIC int
471485xfs_extent_free_finish_item (
@@ -480,6 +494,8 @@ xfs_extent_free_finish_item(
480494 xefi = container_of (item , struct xfs_extent_free_item , xefi_list );
481495
482496 error = xfs_trans_free_extent (tp , EFD_ITEM (done ), xefi );
497+
498+ xfs_extent_free_put_group (xefi );
483499 kmem_cache_free (xfs_extfree_item_cache , xefi );
484500 return error ;
485501}
@@ -500,6 +516,8 @@ xfs_extent_free_cancel_item(
500516 struct xfs_extent_free_item * xefi ;
501517
502518 xefi = container_of (item , struct xfs_extent_free_item , xefi_list );
519+
520+ xfs_extent_free_put_group (xefi );
503521 kmem_cache_free (xfs_extfree_item_cache , xefi );
504522}
505523
@@ -530,24 +548,21 @@ xfs_agfl_free_finish_item(
530548 struct xfs_extent * extp ;
531549 struct xfs_buf * agbp ;
532550 int error ;
533- xfs_agnumber_t agno ;
534551 xfs_agblock_t agbno ;
535552 uint next_extent ;
536- struct xfs_perag * pag ;
537553
538554 xefi = container_of (item , struct xfs_extent_free_item , xefi_list );
539555 ASSERT (xefi -> xefi_blockcount == 1 );
540- agno = XFS_FSB_TO_AGNO (mp , xefi -> xefi_startblock );
541556 agbno = XFS_FSB_TO_AGBNO (mp , xefi -> xefi_startblock );
542557 oinfo .oi_owner = xefi -> xefi_owner ;
543558
544- trace_xfs_agfl_free_deferred (mp , agno , 0 , agbno , xefi -> xefi_blockcount );
559+ trace_xfs_agfl_free_deferred (mp , xefi -> xefi_pag -> pag_agno , 0 , agbno ,
560+ xefi -> xefi_blockcount );
545561
546- pag = xfs_perag_get (mp , agno );
547- error = xfs_alloc_read_agf (pag , tp , 0 , & agbp );
562+ error = xfs_alloc_read_agf (xefi -> xefi_pag , tp , 0 , & agbp );
548563 if (!error )
549- error = xfs_free_agfl_block (tp , agno , agbno , agbp , & oinfo );
550- xfs_perag_put ( pag );
564+ error = xfs_free_agfl_block (tp , xefi -> xefi_pag -> pag_agno ,
565+ agbno , agbp , & oinfo );
551566
552567 /*
553568 * Mark the transaction dirty, even on error. This ensures the
@@ -566,6 +581,7 @@ xfs_agfl_free_finish_item(
566581 extp -> ext_len = xefi -> xefi_blockcount ;
567582 efdp -> efd_next_extent ++ ;
568583
584+ xfs_extent_free_put_group (xefi );
569585 kmem_cache_free (xfs_extfree_item_cache , xefi );
570586 return error ;
571587}
@@ -639,7 +655,9 @@ xfs_efi_item_recover(
639655 fake .xefi_startblock = extp -> ext_start ;
640656 fake .xefi_blockcount = extp -> ext_len ;
641657
658+ xfs_extent_free_get_group (mp , & fake );
642659 error = xfs_trans_free_extent (tp , efdp , & fake );
660+ xfs_extent_free_put_group (& fake );
643661 if (error == - EFSCORRUPTED )
644662 XFS_CORRUPTION_ERROR (__func__ , XFS_ERRLEVEL_LOW , mp ,
645663 extp , sizeof (* extp ));
0 commit comments