@@ -3943,6 +3943,80 @@ void ext4_exit_mballoc(void)
3943
3943
ext4_groupinfo_destroy_slabs ();
3944
3944
}
3945
3945
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
+ }
3946
4020
3947
4021
/*
3948
4022
* 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,
4069
4143
void ext4_mb_mark_bb (struct super_block * sb , ext4_fsblk_t block ,
4070
4144
int len , bool state )
4071
4145
{
4072
- struct buffer_head * bitmap_bh = NULL ;
4073
- struct ext4_group_desc * gdp ;
4074
- struct buffer_head * gdp_bh ;
4075
4146
struct ext4_sb_info * sbi = EXT4_SB (sb );
4076
4147
ext4_group_t group ;
4077
4148
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 ;
4081
4151
4082
4152
while (len > 0 ) {
4083
4153
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,
4098
4168
ext4_error (sb , "Marking blocks in system zone - "
4099
4169
"Block = %llu, len = %u" ,
4100
4170
block , thisgrp_len );
4101
- bitmap_bh = NULL ;
4102
4171
break ;
4103
4172
}
4104
4173
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 );
4164
4175
if (err )
4165
4176
break ;
4166
4177
4167
4178
block += thisgrp_len ;
4168
4179
len -= thisgrp_len ;
4169
- brelse (bitmap_bh );
4170
4180
BUG_ON (len < 0 );
4171
4181
}
4172
-
4173
- if (err )
4174
- brelse (bitmap_bh );
4175
4182
}
4176
4183
4177
4184
/*
0 commit comments