@@ -6388,7 +6388,7 @@ static void ext4_mb_clear_bb(handle_t *handle, struct inode *inode,
6388
6388
ext4_error (sb , "Freeing blocks in system zone - "
6389
6389
"Block = %llu, count = %lu" , block , count );
6390
6390
/* err = 0. ext4_std_error should be a no op */
6391
- goto error_return ;
6391
+ goto error_out ;
6392
6392
}
6393
6393
flags |= EXT4_FREE_BLOCKS_VALIDATED ;
6394
6394
@@ -6412,31 +6412,39 @@ static void ext4_mb_clear_bb(handle_t *handle, struct inode *inode,
6412
6412
flags &= ~EXT4_FREE_BLOCKS_VALIDATED ;
6413
6413
}
6414
6414
count_clusters = EXT4_NUM_B2C (sbi , count );
6415
+ trace_ext4_mballoc_free (sb , inode , block_group , bit , count_clusters );
6416
+
6417
+ /* __GFP_NOFAIL: retry infinitely, ignore TIF_MEMDIE and memcg limit. */
6418
+ err = ext4_mb_load_buddy_gfp (sb , block_group , & e4b ,
6419
+ GFP_NOFS |__GFP_NOFAIL );
6420
+ if (err )
6421
+ goto error_out ;
6422
+
6423
+ if (!(flags & EXT4_FREE_BLOCKS_VALIDATED ) &&
6424
+ !ext4_inode_block_valid (inode , block , count )) {
6425
+ ext4_error (sb , "Freeing blocks in system zone - "
6426
+ "Block = %llu, count = %lu" , block , count );
6427
+ /* err = 0. ext4_std_error should be a no op */
6428
+ goto error_clean ;
6429
+ }
6430
+
6415
6431
bitmap_bh = ext4_read_block_bitmap (sb , block_group );
6416
6432
if (IS_ERR (bitmap_bh )) {
6417
6433
err = PTR_ERR (bitmap_bh );
6418
6434
bitmap_bh = NULL ;
6419
- goto error_return ;
6435
+ goto error_clean ;
6420
6436
}
6421
6437
gdp = ext4_get_group_desc (sb , block_group , & gd_bh );
6422
6438
if (!gdp ) {
6423
6439
err = - EIO ;
6424
- goto error_return ;
6425
- }
6426
-
6427
- if (!(flags & EXT4_FREE_BLOCKS_VALIDATED ) &&
6428
- !ext4_inode_block_valid (inode , block , count )) {
6429
- ext4_error (sb , "Freeing blocks in system zone - "
6430
- "Block = %llu, count = %lu" , block , count );
6431
- /* err = 0. ext4_std_error should be a no op */
6432
- goto error_return ;
6440
+ goto error_clean ;
6433
6441
}
6434
6442
6435
6443
BUFFER_TRACE (bitmap_bh , "getting write access" );
6436
6444
err = ext4_journal_get_write_access (handle , sb , bitmap_bh ,
6437
6445
EXT4_JTR_NONE );
6438
6446
if (err )
6439
- goto error_return ;
6447
+ goto error_clean ;
6440
6448
6441
6449
/*
6442
6450
* We are about to modify some metadata. Call the journal APIs
@@ -6446,21 +6454,38 @@ static void ext4_mb_clear_bb(handle_t *handle, struct inode *inode,
6446
6454
BUFFER_TRACE (gd_bh , "get_write_access" );
6447
6455
err = ext4_journal_get_write_access (handle , sb , gd_bh , EXT4_JTR_NONE );
6448
6456
if (err )
6449
- goto error_return ;
6457
+ goto error_clean ;
6450
6458
#ifdef AGGRESSIVE_CHECK
6451
6459
{
6452
6460
int i ;
6453
6461
for (i = 0 ; i < count_clusters ; i ++ )
6454
6462
BUG_ON (!mb_test_bit (bit + i , bitmap_bh -> b_data ));
6455
6463
}
6456
6464
#endif
6457
- trace_ext4_mballoc_free (sb , inode , block_group , bit , count_clusters );
6465
+ ext4_lock_group (sb , block_group );
6466
+ mb_clear_bits (bitmap_bh -> b_data , bit , count_clusters );
6467
+ ret = ext4_free_group_clusters (sb , gdp ) + count_clusters ;
6468
+ ext4_free_group_clusters_set (sb , gdp , ret );
6469
+ ext4_block_bitmap_csum_set (sb , gdp , bitmap_bh );
6470
+ ext4_group_desc_csum_set (sb , block_group , gdp );
6471
+ ext4_unlock_group (sb , block_group );
6458
6472
6459
- /* __GFP_NOFAIL: retry infinitely, ignore TIF_MEMDIE and memcg limit. */
6460
- err = ext4_mb_load_buddy_gfp (sb , block_group , & e4b ,
6461
- GFP_NOFS |__GFP_NOFAIL );
6462
- if (err )
6463
- goto error_return ;
6473
+ if (sbi -> s_log_groups_per_flex ) {
6474
+ ext4_group_t flex_group = ext4_flex_group (sbi , block_group );
6475
+ atomic64_add (count_clusters ,
6476
+ & sbi_array_rcu_deref (sbi , s_flex_groups ,
6477
+ flex_group )-> free_clusters );
6478
+ }
6479
+
6480
+ /* We dirtied the bitmap block */
6481
+ BUFFER_TRACE (bitmap_bh , "dirtied bitmap block" );
6482
+ err = ext4_handle_dirty_metadata (handle , NULL , bitmap_bh );
6483
+
6484
+ /* And the group descriptor block */
6485
+ BUFFER_TRACE (gd_bh , "dirtied group descriptor block" );
6486
+ ret = ext4_handle_dirty_metadata (handle , NULL , gd_bh );
6487
+ if (!err )
6488
+ err = ret ;
6464
6489
6465
6490
/*
6466
6491
* We need to make sure we don't reuse the freed block until after the
@@ -6484,13 +6509,8 @@ static void ext4_mb_clear_bb(handle_t *handle, struct inode *inode,
6484
6509
new_entry -> efd_tid = handle -> h_transaction -> t_tid ;
6485
6510
6486
6511
ext4_lock_group (sb , block_group );
6487
- mb_clear_bits (bitmap_bh -> b_data , bit , count_clusters );
6488
6512
ext4_mb_free_metadata (handle , & e4b , new_entry );
6489
6513
} else {
6490
- /* need to update group_info->bb_free and bitmap
6491
- * with group lock held. generate_buddy look at
6492
- * them with group lock_held
6493
- */
6494
6514
if (test_opt (sb , DISCARD )) {
6495
6515
err = ext4_issue_discard (sb , block_group , bit ,
6496
6516
count_clusters , NULL );
@@ -6503,23 +6523,11 @@ static void ext4_mb_clear_bb(handle_t *handle, struct inode *inode,
6503
6523
EXT4_MB_GRP_CLEAR_TRIMMED (e4b .bd_info );
6504
6524
6505
6525
ext4_lock_group (sb , block_group );
6506
- mb_clear_bits (bitmap_bh -> b_data , bit , count_clusters );
6507
6526
mb_free_blocks (inode , & e4b , bit , count_clusters );
6508
6527
}
6509
6528
6510
- ret = ext4_free_group_clusters (sb , gdp ) + count_clusters ;
6511
- ext4_free_group_clusters_set (sb , gdp , ret );
6512
- ext4_block_bitmap_csum_set (sb , gdp , bitmap_bh );
6513
- ext4_group_desc_csum_set (sb , block_group , gdp );
6514
6529
ext4_unlock_group (sb , block_group );
6515
6530
6516
- if (sbi -> s_log_groups_per_flex ) {
6517
- ext4_group_t flex_group = ext4_flex_group (sbi , block_group );
6518
- atomic64_add (count_clusters ,
6519
- & sbi_array_rcu_deref (sbi , s_flex_groups ,
6520
- flex_group )-> free_clusters );
6521
- }
6522
-
6523
6531
/*
6524
6532
* on a bigalloc file system, defer the s_freeclusters_counter
6525
6533
* update to the caller (ext4_remove_space and friends) so they
@@ -6532,28 +6540,20 @@ static void ext4_mb_clear_bb(handle_t *handle, struct inode *inode,
6532
6540
count_clusters );
6533
6541
}
6534
6542
6535
- ext4_mb_unload_buddy (& e4b );
6536
-
6537
- /* We dirtied the bitmap block */
6538
- BUFFER_TRACE (bitmap_bh , "dirtied bitmap block" );
6539
- err = ext4_handle_dirty_metadata (handle , NULL , bitmap_bh );
6540
-
6541
- /* And the group descriptor block */
6542
- BUFFER_TRACE (gd_bh , "dirtied group descriptor block" );
6543
- ret = ext4_handle_dirty_metadata (handle , NULL , gd_bh );
6544
- if (!err )
6545
- err = ret ;
6546
-
6547
6543
if (overflow && !err ) {
6548
6544
block += count ;
6549
6545
count = overflow ;
6546
+ ext4_mb_unload_buddy (& e4b );
6550
6547
put_bh (bitmap_bh );
6551
6548
/* The range changed so it's no longer validated */
6552
6549
flags &= ~EXT4_FREE_BLOCKS_VALIDATED ;
6553
6550
goto do_more ;
6554
6551
}
6555
- error_return :
6552
+
6553
+ error_clean :
6554
+ ext4_mb_unload_buddy (& e4b );
6556
6555
brelse (bitmap_bh );
6556
+ error_out :
6557
6557
ext4_std_error (sb , err );
6558
6558
}
6559
6559
0 commit comments