@@ -2426,49 +2426,59 @@ static void update_segment_mtime(struct f2fs_sb_info *sbi, block_t blkaddr,
2426
2426
SIT_I (sbi )-> max_mtime = ctime ;
2427
2427
}
2428
2428
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
+ */
2429
2433
static int update_sit_entry_for_release (struct f2fs_sb_info * sbi , struct seg_entry * se ,
2430
2434
block_t blkaddr , unsigned int offset , int del )
2431
2435
{
2432
2436
bool exist ;
2433
2437
#ifdef CONFIG_F2FS_CHECK_FS
2434
2438
bool mir_exist ;
2435
2439
#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 ));
2436
2444
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 );
2438
2447
#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
+ }
2446
2455
#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
+ }
2463
2473
}
2464
- }
2465
2474
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 ++ ;
2469
2478
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
+ }
2472
2482
2473
2483
return del ;
2474
2484
}
@@ -2517,6 +2527,11 @@ static int update_sit_entry_for_alloc(struct f2fs_sb_info *sbi, struct seg_entry
2517
2527
return del ;
2518
2528
}
2519
2529
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
+ */
2520
2535
static void update_sit_entry (struct f2fs_sb_info * sbi , block_t blkaddr , int del )
2521
2536
{
2522
2537
struct seg_entry * se ;
0 commit comments