Skip to content

Commit 1a50ad0

Browse files
chaseyupundiramit
authored andcommitted
f2fs: check in-memory sit version bitmap
commit ae27d62e6befd3cac4ffa702e644cc52019642e8 upstream. This patch adds a mirror for sit version bitmap, and use it to detect in-memory bitmap corruption which may be caused by bit-transition of cache or memory overflow. Signed-off-by: Chao Yu <yuchao0@huawei.com> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
1 parent 2bb1504 commit 1a50ad0

2 files changed

Lines changed: 30 additions & 4 deletions

File tree

fs/f2fs/segment.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2421,7 +2421,7 @@ static int build_sit_info(struct f2fs_sb_info *sbi)
24212421
struct f2fs_super_block *raw_super = F2FS_RAW_SUPER(sbi);
24222422
struct sit_info *sit_i;
24232423
unsigned int sit_segs, start;
2424-
char *src_bitmap, *dst_bitmap;
2424+
char *src_bitmap;
24252425
unsigned int bitmap_size;
24262426

24272427
/* allocate memory for SIT information */
@@ -2483,17 +2483,22 @@ static int build_sit_info(struct f2fs_sb_info *sbi)
24832483
bitmap_size = __bitmap_size(sbi, SIT_BITMAP);
24842484
src_bitmap = __bitmap_ptr(sbi, SIT_BITMAP);
24852485

2486-
dst_bitmap = kmemdup(src_bitmap, bitmap_size, GFP_KERNEL);
2487-
if (!dst_bitmap)
2486+
sit_i->sit_bitmap = kmemdup(src_bitmap, bitmap_size, GFP_KERNEL);
2487+
if (!sit_i->sit_bitmap)
24882488
return -ENOMEM;
24892489

2490+
#ifdef CONFIG_F2FS_CHECK_FS
2491+
sit_i->sit_bitmap_mir = kmemdup(src_bitmap, bitmap_size, GFP_KERNEL);
2492+
if (!sit_i->sit_bitmap_mir)
2493+
return -ENOMEM;
2494+
#endif
2495+
24902496
/* init SIT information */
24912497
sit_i->s_ops = &default_salloc_ops;
24922498

24932499
sit_i->sit_base_addr = le32_to_cpu(raw_super->sit_blkaddr);
24942500
sit_i->sit_blocks = sit_segs << sbi->log_blocks_per_seg;
24952501
sit_i->written_valid_blocks = 0;
2496-
sit_i->sit_bitmap = dst_bitmap;
24972502
sit_i->bitmap_size = bitmap_size;
24982503
sit_i->dirty_sentries = 0;
24992504
sit_i->sents_per_block = SIT_ENTRY_PER_BLOCK;
@@ -2901,6 +2906,9 @@ static void destroy_sit_info(struct f2fs_sb_info *sbi)
29012906

29022907
SM_I(sbi)->sit_info = NULL;
29032908
kfree(sit_i->sit_bitmap);
2909+
#ifdef CONFIG_F2FS_CHECK_FS
2910+
kfree(sit_i->sit_bitmap_mir);
2911+
#endif
29042912
kfree(sit_i);
29052913
}
29062914

fs/f2fs/segment.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,9 @@ struct sit_info {
209209
block_t sit_blocks; /* # of blocks used by SIT area */
210210
block_t written_valid_blocks; /* # of valid blocks in main area */
211211
char *sit_bitmap; /* SIT bitmap pointer */
212+
#ifdef CONFIG_F2FS_CHECK_FS
213+
char *sit_bitmap_mir; /* SIT bitmap mirror */
214+
#endif
212215
unsigned int bitmap_size; /* SIT bitmap size */
213216

214217
unsigned long *tmp_map; /* bitmap for temporal use */
@@ -423,6 +426,12 @@ static inline void get_sit_bitmap(struct f2fs_sb_info *sbi,
423426
void *dst_addr)
424427
{
425428
struct sit_info *sit_i = SIT_I(sbi);
429+
430+
#ifdef CONFIG_F2FS_CHECK_FS
431+
if (memcmp(sit_i->sit_bitmap, sit_i->sit_bitmap_mir,
432+
sit_i->bitmap_size))
433+
f2fs_bug_on(sbi, 1);
434+
#endif
426435
memcpy(dst_addr, sit_i->sit_bitmap, sit_i->bitmap_size);
427436
}
428437

@@ -643,6 +652,12 @@ static inline pgoff_t current_sit_addr(struct f2fs_sb_info *sbi,
643652

644653
check_seg_range(sbi, start);
645654

655+
#ifdef CONFIG_F2FS_CHECK_FS
656+
if (f2fs_test_bit(offset, sit_i->sit_bitmap) !=
657+
f2fs_test_bit(offset, sit_i->sit_bitmap_mir))
658+
f2fs_bug_on(sbi, 1);
659+
#endif
660+
646661
/* calculate sit block address */
647662
if (f2fs_test_bit(offset, sit_i->sit_bitmap))
648663
blk_addr += sit_i->sit_blocks;
@@ -668,6 +683,9 @@ static inline void set_to_next_sit(struct sit_info *sit_i, unsigned int start)
668683
unsigned int block_off = SIT_BLOCK_OFFSET(start);
669684

670685
f2fs_change_bit(block_off, sit_i->sit_bitmap);
686+
#ifdef CONFIG_F2FS_CHECK_FS
687+
f2fs_change_bit(block_off, sit_i->sit_bitmap_mir);
688+
#endif
671689
}
672690

673691
static inline unsigned long long get_mtime(struct f2fs_sb_info *sbi)

0 commit comments

Comments
 (0)