@@ -6622,23 +6622,19 @@ void ext4_free_blocks(handle_t *handle, struct inode *inode,
66226622int ext4_group_add_blocks (handle_t * handle , struct super_block * sb ,
66236623 ext4_fsblk_t block , unsigned long count )
66246624{
6625- struct buffer_head * bitmap_bh = NULL ;
6626- struct buffer_head * gd_bh ;
66276625 ext4_group_t block_group ;
66286626 ext4_grpblk_t bit ;
6629- unsigned int i ;
6630- struct ext4_group_desc * desc ;
66316627 struct ext4_sb_info * sbi = EXT4_SB (sb );
66326628 struct ext4_buddy e4b ;
6633- int err = 0 , ret , free_clusters_count ;
6634- ext4_grpblk_t clusters_freed ;
6629+ int err = 0 ;
66356630 ext4_fsblk_t first_cluster = EXT4_B2C (sbi , block );
66366631 ext4_fsblk_t last_cluster = EXT4_B2C (sbi , block + count - 1 );
66376632 unsigned long cluster_count = last_cluster - first_cluster + 1 ;
6633+ ext4_grpblk_t changed ;
66386634
66396635 ext4_debug ("Adding block(s) %llu-%llu\n" , block , block + count - 1 );
66406636
6641- if (count == 0 )
6637+ if (cluster_count == 0 )
66426638 return 0 ;
66436639
66446640 ext4_get_group_no_and_offset (sb , block , & block_group , & bit );
@@ -6665,80 +6661,22 @@ int ext4_group_add_blocks(handle_t *handle, struct super_block *sb,
66656661 goto error_clean ;
66666662 }
66676663
6668- bitmap_bh = ext4_read_block_bitmap (sb , block_group );
6669- if (IS_ERR (bitmap_bh )) {
6670- err = PTR_ERR (bitmap_bh );
6671- bitmap_bh = NULL ;
6672- goto error_clean ;
6673- }
6674-
6675- desc = ext4_get_group_desc (sb , block_group , & gd_bh );
6676- if (!desc ) {
6677- err = - EIO ;
6678- goto error_clean ;
6679- }
6680-
6681- BUFFER_TRACE (bitmap_bh , "getting write access" );
6682- err = ext4_journal_get_write_access (handle , sb , bitmap_bh ,
6683- EXT4_JTR_NONE );
6684- if (err )
6685- goto error_clean ;
6686-
6687- /*
6688- * We are about to modify some metadata. Call the journal APIs
6689- * to unshare ->b_data if a currently-committing transaction is
6690- * using it
6691- */
6692- BUFFER_TRACE (gd_bh , "get_write_access" );
6693- err = ext4_journal_get_write_access (handle , sb , gd_bh , EXT4_JTR_NONE );
6694- if (err )
6664+ err = ext4_mb_mark_context (handle , sb , false, block_group , bit ,
6665+ cluster_count , EXT4_MB_BITMAP_MARKED_CHECK ,
6666+ & changed );
6667+ if (err && changed == 0 )
66956668 goto error_clean ;
66966669
6697- for (i = 0 , clusters_freed = 0 ; i < cluster_count ; i ++ ) {
6698- BUFFER_TRACE (bitmap_bh , "clear bit" );
6699- if (!mb_test_bit (bit + i , bitmap_bh -> b_data )) {
6700- ext4_error (sb , "bit already cleared for block %llu" ,
6701- (ext4_fsblk_t )(block + i ));
6702- BUFFER_TRACE (bitmap_bh , "bit already cleared" );
6703- } else {
6704- clusters_freed ++ ;
6705- }
6706- }
6707-
6708- ext4_lock_group (sb , block_group );
6709- mb_clear_bits (bitmap_bh -> b_data , bit , cluster_count );
6710- free_clusters_count = clusters_freed +
6711- ext4_free_group_clusters (sb , desc );
6712- ext4_free_group_clusters_set (sb , desc , free_clusters_count );
6713- ext4_block_bitmap_csum_set (sb , desc , bitmap_bh );
6714- ext4_group_desc_csum_set (sb , block_group , desc );
6715- ext4_unlock_group (sb , block_group );
6716-
6717- if (sbi -> s_log_groups_per_flex ) {
6718- ext4_group_t flex_group = ext4_flex_group (sbi , block_group );
6719- atomic64_add (clusters_freed ,
6720- & sbi_array_rcu_deref (sbi , s_flex_groups ,
6721- flex_group )-> free_clusters );
6722- }
6723-
6724- /* We dirtied the bitmap block */
6725- BUFFER_TRACE (bitmap_bh , "dirtied bitmap block" );
6726- err = ext4_handle_dirty_metadata (handle , NULL , bitmap_bh );
6727-
6728- /* And the group descriptor block */
6729- BUFFER_TRACE (gd_bh , "dirtied group descriptor block" );
6730- ret = ext4_handle_dirty_metadata (handle , NULL , gd_bh );
6731- if (!err )
6732- err = ret ;
6670+ if (changed != cluster_count )
6671+ ext4_error (sb , "bit already cleared in group %u" , block_group );
67336672
67346673 ext4_lock_group (sb , block_group );
67356674 mb_free_blocks (NULL , & e4b , bit , cluster_count );
67366675 ext4_unlock_group (sb , block_group );
67376676 percpu_counter_add (& sbi -> s_freeclusters_counter ,
6738- clusters_freed );
6677+ changed );
67396678
67406679error_clean :
6741- brelse (bitmap_bh );
67426680 ext4_mb_unload_buddy (& e4b );
67436681error_out :
67446682 ext4_std_error (sb , err );
0 commit comments