@@ -3943,6 +3943,80 @@ void ext4_exit_mballoc(void)
39433943 ext4_groupinfo_destroy_slabs ();
39443944}
39453945
3946+ static int
3947+ ext4_mb_mark_context (struct super_block * sb , bool state , ext4_group_t group ,
3948+ ext4_grpblk_t blkoff , ext4_grpblk_t len )
3949+ {
3950+ struct ext4_sb_info * sbi = EXT4_SB (sb );
3951+ struct buffer_head * bitmap_bh = NULL ;
3952+ struct ext4_group_desc * gdp ;
3953+ struct buffer_head * gdp_bh ;
3954+ int err ;
3955+ unsigned int i , already , changed ;
3956+
3957+ bitmap_bh = ext4_read_block_bitmap (sb , group );
3958+ if (IS_ERR (bitmap_bh ))
3959+ return PTR_ERR (bitmap_bh );
3960+
3961+ err = - EIO ;
3962+ gdp = ext4_get_group_desc (sb , group , & gdp_bh );
3963+ if (!gdp )
3964+ goto out_err ;
3965+
3966+ ext4_lock_group (sb , group );
3967+ if (ext4_has_group_desc_csum (sb ) &&
3968+ (gdp -> bg_flags & cpu_to_le16 (EXT4_BG_BLOCK_UNINIT ))) {
3969+ gdp -> bg_flags &= cpu_to_le16 (~EXT4_BG_BLOCK_UNINIT );
3970+ ext4_free_group_clusters_set (sb , gdp ,
3971+ ext4_free_clusters_after_init (sb , group , gdp ));
3972+ }
3973+
3974+ already = 0 ;
3975+ for (i = 0 ; i < len ; i ++ )
3976+ if (mb_test_bit (blkoff + i , bitmap_bh -> b_data ) ==
3977+ state )
3978+ already ++ ;
3979+ changed = len - already ;
3980+
3981+ if (state ) {
3982+ mb_set_bits (bitmap_bh -> b_data , blkoff , len );
3983+ ext4_free_group_clusters_set (sb , gdp ,
3984+ ext4_free_group_clusters (sb , gdp ) - changed );
3985+ } else {
3986+ mb_clear_bits (bitmap_bh -> b_data , blkoff , len );
3987+ ext4_free_group_clusters_set (sb , gdp ,
3988+ ext4_free_group_clusters (sb , gdp ) + changed );
3989+ }
3990+
3991+ ext4_block_bitmap_csum_set (sb , gdp , bitmap_bh );
3992+ ext4_group_desc_csum_set (sb , group , gdp );
3993+ ext4_unlock_group (sb , group );
3994+
3995+ if (sbi -> s_log_groups_per_flex ) {
3996+ ext4_group_t flex_group = ext4_flex_group (sbi , group );
3997+ struct flex_groups * fg = sbi_array_rcu_deref (sbi ,
3998+ s_flex_groups , flex_group );
3999+
4000+ if (state )
4001+ atomic64_sub (changed , & fg -> free_clusters );
4002+ else
4003+ atomic64_add (changed , & fg -> free_clusters );
4004+ }
4005+
4006+ err = ext4_handle_dirty_metadata (NULL , NULL , bitmap_bh );
4007+ if (err )
4008+ goto out_err ;
4009+ err = ext4_handle_dirty_metadata (NULL , NULL , gdp_bh );
4010+ if (err )
4011+ goto out_err ;
4012+
4013+ sync_dirty_buffer (bitmap_bh );
4014+ sync_dirty_buffer (gdp_bh );
4015+
4016+ out_err :
4017+ brelse (bitmap_bh );
4018+ return err ;
4019+ }
39464020
39474021/*
39484022 * Check quota and mark chosen space (ac->ac_b_ex) non-free in bitmaps
@@ -4069,15 +4143,11 @@ ext4_mb_mark_diskspace_used(struct ext4_allocation_context *ac,
40694143void ext4_mb_mark_bb (struct super_block * sb , ext4_fsblk_t block ,
40704144 int len , bool state )
40714145{
4072- struct buffer_head * bitmap_bh = NULL ;
4073- struct ext4_group_desc * gdp ;
4074- struct buffer_head * gdp_bh ;
40754146 struct ext4_sb_info * sbi = EXT4_SB (sb );
40764147 ext4_group_t group ;
40774148 ext4_grpblk_t blkoff ;
4078- int i , err = 0 ;
4079- int already ;
4080- unsigned int clen , clen_changed , thisgrp_len ;
4149+ int err = 0 ;
4150+ unsigned int clen , thisgrp_len ;
40814151
40824152 while (len > 0 ) {
40834153 ext4_get_group_no_and_offset (sb , block , & group , & blkoff );
@@ -4098,80 +4168,17 @@ void ext4_mb_mark_bb(struct super_block *sb, ext4_fsblk_t block,
40984168 ext4_error (sb , "Marking blocks in system zone - "
40994169 "Block = %llu, len = %u" ,
41004170 block , thisgrp_len );
4101- bitmap_bh = NULL ;
41024171 break ;
41034172 }
41044173
4105- bitmap_bh = ext4_read_block_bitmap (sb , group );
4106- if (IS_ERR (bitmap_bh )) {
4107- err = PTR_ERR (bitmap_bh );
4108- bitmap_bh = NULL ;
4109- break ;
4110- }
4111-
4112- err = - EIO ;
4113- gdp = ext4_get_group_desc (sb , group , & gdp_bh );
4114- if (!gdp )
4115- break ;
4116-
4117- ext4_lock_group (sb , group );
4118- already = 0 ;
4119- for (i = 0 ; i < clen ; i ++ )
4120- if (!mb_test_bit (blkoff + i , bitmap_bh -> b_data ) ==
4121- !state )
4122- already ++ ;
4123-
4124- clen_changed = clen - already ;
4125- if (state )
4126- mb_set_bits (bitmap_bh -> b_data , blkoff , clen );
4127- else
4128- mb_clear_bits (bitmap_bh -> b_data , blkoff , clen );
4129- if (ext4_has_group_desc_csum (sb ) &&
4130- (gdp -> bg_flags & cpu_to_le16 (EXT4_BG_BLOCK_UNINIT ))) {
4131- gdp -> bg_flags &= cpu_to_le16 (~EXT4_BG_BLOCK_UNINIT );
4132- ext4_free_group_clusters_set (sb , gdp ,
4133- ext4_free_clusters_after_init (sb , group , gdp ));
4134- }
4135- if (state )
4136- clen = ext4_free_group_clusters (sb , gdp ) - clen_changed ;
4137- else
4138- clen = ext4_free_group_clusters (sb , gdp ) + clen_changed ;
4139-
4140- ext4_free_group_clusters_set (sb , gdp , clen );
4141- ext4_block_bitmap_csum_set (sb , gdp , bitmap_bh );
4142- ext4_group_desc_csum_set (sb , group , gdp );
4143-
4144- ext4_unlock_group (sb , group );
4145-
4146- if (sbi -> s_log_groups_per_flex ) {
4147- ext4_group_t flex_group = ext4_flex_group (sbi , group );
4148- struct flex_groups * fg = sbi_array_rcu_deref (sbi ,
4149- s_flex_groups , flex_group );
4150-
4151- if (state )
4152- atomic64_sub (clen_changed , & fg -> free_clusters );
4153- else
4154- atomic64_add (clen_changed , & fg -> free_clusters );
4155-
4156- }
4157-
4158- err = ext4_handle_dirty_metadata (NULL , NULL , bitmap_bh );
4159- if (err )
4160- break ;
4161- sync_dirty_buffer (bitmap_bh );
4162- err = ext4_handle_dirty_metadata (NULL , NULL , gdp_bh );
4163- sync_dirty_buffer (gdp_bh );
4174+ err = ext4_mb_mark_context (sb , state , group , blkoff , clen );
41644175 if (err )
41654176 break ;
41664177
41674178 block += thisgrp_len ;
41684179 len -= thisgrp_len ;
4169- brelse (bitmap_bh );
41704180 BUG_ON (len < 0 );
41714181 }
4172-
4173- if (err )
4174- brelse (bitmap_bh );
41754182}
41764183
41774184/*
0 commit comments