@@ -6367,19 +6367,17 @@ static void ext4_mb_clear_bb(handle_t *handle, struct inode *inode,
63676367 ext4_fsblk_t block , unsigned long count ,
63686368 int flags )
63696369{
6370- struct buffer_head * bitmap_bh = NULL ;
63716370 struct super_block * sb = inode -> i_sb ;
6372- struct ext4_group_desc * gdp ;
63736371 struct ext4_group_info * grp ;
63746372 unsigned int overflow ;
63756373 ext4_grpblk_t bit ;
6376- struct buffer_head * gd_bh ;
63776374 ext4_group_t block_group ;
63786375 struct ext4_sb_info * sbi ;
63796376 struct ext4_buddy e4b ;
63806377 unsigned int count_clusters ;
63816378 int err = 0 ;
6382- int ret ;
6379+ int mark_flags = 0 ;
6380+ ext4_grpblk_t changed ;
63836381
63846382 sbi = EXT4_SB (sb );
63856383
@@ -6428,64 +6426,19 @@ static void ext4_mb_clear_bb(handle_t *handle, struct inode *inode,
64286426 goto error_clean ;
64296427 }
64306428
6431- bitmap_bh = ext4_read_block_bitmap (sb , block_group );
6432- if (IS_ERR (bitmap_bh )) {
6433- err = PTR_ERR (bitmap_bh );
6434- bitmap_bh = NULL ;
6435- goto error_clean ;
6436- }
6437- gdp = ext4_get_group_desc (sb , block_group , & gd_bh );
6438- if (!gdp ) {
6439- err = - EIO ;
6440- goto error_clean ;
6441- }
6442-
6443- BUFFER_TRACE (bitmap_bh , "getting write access" );
6444- err = ext4_journal_get_write_access (handle , sb , bitmap_bh ,
6445- EXT4_JTR_NONE );
6446- if (err )
6447- goto error_clean ;
6448-
6449- /*
6450- * We are about to modify some metadata. Call the journal APIs
6451- * to unshare ->b_data if a currently-committing transaction is
6452- * using it
6453- */
6454- BUFFER_TRACE (gd_bh , "get_write_access" );
6455- err = ext4_journal_get_write_access (handle , sb , gd_bh , EXT4_JTR_NONE );
6456- if (err )
6457- goto error_clean ;
64586429#ifdef AGGRESSIVE_CHECK
6459- {
6460- int i ;
6461- for (i = 0 ; i < count_clusters ; i ++ )
6462- BUG_ON (!mb_test_bit (bit + i , bitmap_bh -> b_data ));
6463- }
6430+ mark_flags |= EXT4_MB_BITMAP_MARKED_CHECK ;
64646431#endif
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 );
6432+ err = ext4_mb_mark_context (handle , sb , false, block_group , bit ,
6433+ count_clusters , mark_flags , & changed );
64726434
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- }
64796435
6480- /* We dirtied the bitmap block */
6481- BUFFER_TRACE (bitmap_bh , "dirtied bitmap block" );
6482- err = ext4_handle_dirty_metadata (handle , NULL , bitmap_bh );
6436+ if (err && changed == 0 )
6437+ goto error_clean ;
64836438
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 ;
6439+ #ifdef AGGRESSIVE_CHECK
6440+ BUG_ON (changed != count_clusters );
6441+ #endif
64896442
64906443 /*
64916444 * We need to make sure we don't reuse the freed block until after the
@@ -6544,15 +6497,13 @@ static void ext4_mb_clear_bb(handle_t *handle, struct inode *inode,
65446497 block += count ;
65456498 count = overflow ;
65466499 ext4_mb_unload_buddy (& e4b );
6547- put_bh (bitmap_bh );
65486500 /* The range changed so it's no longer validated */
65496501 flags &= ~EXT4_FREE_BLOCKS_VALIDATED ;
65506502 goto do_more ;
65516503 }
65526504
65536505error_clean :
65546506 ext4_mb_unload_buddy (& e4b );
6555- brelse (bitmap_bh );
65566507error_out :
65576508 ext4_std_error (sb , err );
65586509}
0 commit comments