@@ -350,10 +350,7 @@ xfs_trans_free_extent(
350
350
struct xfs_owner_info oinfo = { };
351
351
struct xfs_mount * mp = tp -> t_mountp ;
352
352
struct xfs_extent * extp ;
353
- struct xfs_perag * pag ;
354
353
uint next_extent ;
355
- xfs_agnumber_t agno = XFS_FSB_TO_AGNO (mp ,
356
- xefi -> xefi_startblock );
357
354
xfs_agblock_t agbno = XFS_FSB_TO_AGBNO (mp ,
358
355
xefi -> xefi_startblock );
359
356
int error ;
@@ -364,14 +361,12 @@ xfs_trans_free_extent(
364
361
if (xefi -> xefi_flags & XFS_EFI_BMBT_BLOCK )
365
362
oinfo .oi_flags |= XFS_OWNER_INFO_BMBT_BLOCK ;
366
363
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 );
369
366
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 ,
373
369
xefi -> xefi_flags & XFS_EFI_SKIP_DISCARD );
374
- xfs_perag_put (pag );
375
370
376
371
/*
377
372
* Mark the transaction dirty, even on error. This ensures the
@@ -400,14 +395,13 @@ xfs_extent_free_diff_items(
400
395
const struct list_head * a ,
401
396
const struct list_head * b )
402
397
{
403
- struct xfs_mount * mp = priv ;
404
398
struct xfs_extent_free_item * ra ;
405
399
struct xfs_extent_free_item * rb ;
406
400
407
401
ra = container_of (a , struct xfs_extent_free_item , xefi_list );
408
402
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 ;
411
405
}
412
406
413
407
/* Log a free extent to the intent item. */
@@ -466,6 +460,26 @@ xfs_extent_free_create_done(
466
460
return & xfs_trans_get_efd (tp , EFI_ITEM (intent ), count )-> efd_item ;
467
461
}
468
462
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
+
469
483
/* Process a free extent. */
470
484
STATIC int
471
485
xfs_extent_free_finish_item (
@@ -480,6 +494,8 @@ xfs_extent_free_finish_item(
480
494
xefi = container_of (item , struct xfs_extent_free_item , xefi_list );
481
495
482
496
error = xfs_trans_free_extent (tp , EFD_ITEM (done ), xefi );
497
+
498
+ xfs_extent_free_put_group (xefi );
483
499
kmem_cache_free (xfs_extfree_item_cache , xefi );
484
500
return error ;
485
501
}
@@ -500,6 +516,8 @@ xfs_extent_free_cancel_item(
500
516
struct xfs_extent_free_item * xefi ;
501
517
502
518
xefi = container_of (item , struct xfs_extent_free_item , xefi_list );
519
+
520
+ xfs_extent_free_put_group (xefi );
503
521
kmem_cache_free (xfs_extfree_item_cache , xefi );
504
522
}
505
523
@@ -530,24 +548,21 @@ xfs_agfl_free_finish_item(
530
548
struct xfs_extent * extp ;
531
549
struct xfs_buf * agbp ;
532
550
int error ;
533
- xfs_agnumber_t agno ;
534
551
xfs_agblock_t agbno ;
535
552
uint next_extent ;
536
- struct xfs_perag * pag ;
537
553
538
554
xefi = container_of (item , struct xfs_extent_free_item , xefi_list );
539
555
ASSERT (xefi -> xefi_blockcount == 1 );
540
- agno = XFS_FSB_TO_AGNO (mp , xefi -> xefi_startblock );
541
556
agbno = XFS_FSB_TO_AGBNO (mp , xefi -> xefi_startblock );
542
557
oinfo .oi_owner = xefi -> xefi_owner ;
543
558
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 );
545
561
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 );
548
563
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 );
551
566
552
567
/*
553
568
* Mark the transaction dirty, even on error. This ensures the
@@ -566,6 +581,7 @@ xfs_agfl_free_finish_item(
566
581
extp -> ext_len = xefi -> xefi_blockcount ;
567
582
efdp -> efd_next_extent ++ ;
568
583
584
+ xfs_extent_free_put_group (xefi );
569
585
kmem_cache_free (xfs_extfree_item_cache , xefi );
570
586
return error ;
571
587
}
@@ -639,7 +655,9 @@ xfs_efi_item_recover(
639
655
fake .xefi_startblock = extp -> ext_start ;
640
656
fake .xefi_blockcount = extp -> ext_len ;
641
657
658
+ xfs_extent_free_get_group (mp , & fake );
642
659
error = xfs_trans_free_extent (tp , efdp , & fake );
660
+ xfs_extent_free_put_group (& fake );
643
661
if (error == - EFSCORRUPTED )
644
662
XFS_CORRUPTION_ERROR (__func__ , XFS_ERRLEVEL_LOW , mp ,
645
663
extp , sizeof (* extp ));
0 commit comments