@@ -2426,49 +2426,59 @@ static void update_segment_mtime(struct f2fs_sb_info *sbi, block_t blkaddr,
24262426 SIT_I (sbi )-> max_mtime = ctime ;
24272427}
24282428
2429+ /*
2430+ * NOTE: when updating multiple blocks at the same time, please ensure
2431+ * that the consecutive input blocks belong to the same segment.
2432+ */
24292433static int update_sit_entry_for_release (struct f2fs_sb_info * sbi , struct seg_entry * se ,
24302434 block_t blkaddr , unsigned int offset , int del )
24312435{
24322436 bool exist ;
24332437#ifdef CONFIG_F2FS_CHECK_FS
24342438 bool mir_exist ;
24352439#endif
2440+ int i ;
2441+ int del_count = - del ;
2442+
2443+ f2fs_bug_on (sbi , GET_SEGNO (sbi , blkaddr ) != GET_SEGNO (sbi , blkaddr + del_count - 1 ));
24362444
2437- exist = f2fs_test_and_clear_bit (offset , se -> cur_valid_map );
2445+ for (i = 0 ; i < del_count ; i ++ ) {
2446+ exist = f2fs_test_and_clear_bit (offset + i , se -> cur_valid_map );
24382447#ifdef CONFIG_F2FS_CHECK_FS
2439- mir_exist = f2fs_test_and_clear_bit (offset ,
2440- se -> cur_valid_map_mir );
2441- if (unlikely (exist != mir_exist )) {
2442- f2fs_err (sbi , "Inconsistent error when clearing bitmap, blk:%u, old bit:%d" ,
2443- blkaddr , exist );
2444- f2fs_bug_on (sbi , 1 );
2445- }
2448+ mir_exist = f2fs_test_and_clear_bit (offset + i ,
2449+ se -> cur_valid_map_mir );
2450+ if (unlikely (exist != mir_exist )) {
2451+ f2fs_err (sbi , "Inconsistent error when clearing bitmap, blk:%u, old bit:%d" ,
2452+ blkaddr + i , exist );
2453+ f2fs_bug_on (sbi , 1 );
2454+ }
24462455#endif
2447- if (unlikely (!exist )) {
2448- f2fs_err (sbi , "Bitmap was wrongly cleared, blk:%u" , blkaddr );
2449- f2fs_bug_on (sbi , 1 );
2450- se -> valid_blocks ++ ;
2451- del = 0 ;
2452- } else if (unlikely (is_sbi_flag_set (sbi , SBI_CP_DISABLED ))) {
2453- /*
2454- * If checkpoints are off, we must not reuse data that
2455- * was used in the previous checkpoint. If it was used
2456- * before, we must track that to know how much space we
2457- * really have.
2458- */
2459- if (f2fs_test_bit (offset , se -> ckpt_valid_map )) {
2460- spin_lock (& sbi -> stat_lock );
2461- sbi -> unusable_block_count ++ ;
2462- spin_unlock (& sbi -> stat_lock );
2456+ if (unlikely (!exist )) {
2457+ f2fs_err (sbi , "Bitmap was wrongly cleared, blk:%u" , blkaddr + i );
2458+ f2fs_bug_on (sbi , 1 );
2459+ se -> valid_blocks ++ ;
2460+ del += 1 ;
2461+ } else if (unlikely (is_sbi_flag_set (sbi , SBI_CP_DISABLED ))) {
2462+ /*
2463+ * If checkpoints are off, we must not reuse data that
2464+ * was used in the previous checkpoint. If it was used
2465+ * before, we must track that to know how much space we
2466+ * really have.
2467+ */
2468+ if (f2fs_test_bit (offset + i , se -> ckpt_valid_map )) {
2469+ spin_lock (& sbi -> stat_lock );
2470+ sbi -> unusable_block_count ++ ;
2471+ spin_unlock (& sbi -> stat_lock );
2472+ }
24632473 }
2464- }
24652474
2466- if (f2fs_block_unit_discard (sbi ) &&
2467- f2fs_test_and_clear_bit (offset , se -> discard_map ))
2468- sbi -> discard_blks ++ ;
2475+ if (f2fs_block_unit_discard (sbi ) &&
2476+ f2fs_test_and_clear_bit (offset + i , se -> discard_map ))
2477+ sbi -> discard_blks ++ ;
24692478
2470- if (!f2fs_test_bit (offset , se -> ckpt_valid_map ))
2471- se -> ckpt_valid_blocks += del ;
2479+ if (!f2fs_test_bit (offset + i , se -> ckpt_valid_map ))
2480+ se -> ckpt_valid_blocks -= 1 ;
2481+ }
24722482
24732483 return del ;
24742484}
@@ -2517,6 +2527,11 @@ static int update_sit_entry_for_alloc(struct f2fs_sb_info *sbi, struct seg_entry
25172527 return del ;
25182528}
25192529
2530+ /*
2531+ * If releasing blocks, this function supports updating multiple consecutive blocks
2532+ * at one time, but please note that these consecutive blocks need to belong to the
2533+ * same segment.
2534+ */
25202535static void update_sit_entry (struct f2fs_sb_info * sbi , block_t blkaddr , int del )
25212536{
25222537 struct seg_entry * se ;
0 commit comments