Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

f2fs: check blkaddr more accuratly before issue a bio

This patch check blkaddr more accuratly before issue a
write or read bio.

Signed-off-by: Yunlei He <heyunlei@huawei.com>
Reviewed-by: Chao Yu <yuchao0@huawei.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>

authored by

Yunlei He and committed by
Jaegeuk Kim
0833721e 02117b8a

+25 -8
+2
fs/f2fs/checkpoint.c
··· 68 68 .old_blkaddr = index, 69 69 .new_blkaddr = index, 70 70 .encrypted_page = NULL, 71 + .is_meta = is_meta, 71 72 }; 72 73 73 74 if (unlikely(!is_meta)) ··· 163 162 .op_flags = sync ? (REQ_META | REQ_PRIO) : REQ_RAHEAD, 164 163 .encrypted_page = NULL, 165 164 .in_list = false, 165 + .is_meta = (type != META_POR), 166 166 }; 167 167 struct blk_plug plug; 168 168
+3 -2
fs/f2fs/data.c
··· 383 383 struct page *page = fio->encrypted_page ? 384 384 fio->encrypted_page : fio->page; 385 385 386 + verify_block_addr(fio, fio->new_blkaddr); 386 387 trace_f2fs_submit_page_bio(page, fio); 387 388 f2fs_trace_ios(fio, 0); 388 389 ··· 429 428 } 430 429 431 430 if (fio->old_blkaddr != NEW_ADDR) 432 - verify_block_addr(sbi, fio->old_blkaddr); 433 - verify_block_addr(sbi, fio->new_blkaddr); 431 + verify_block_addr(fio, fio->old_blkaddr); 432 + verify_block_addr(fio, fio->new_blkaddr); 434 433 435 434 bio_page = fio->encrypted_page ? fio->encrypted_page : fio->page; 436 435
+1
fs/f2fs/f2fs.h
··· 1001 1001 bool submitted; /* indicate IO submission */ 1002 1002 int need_lock; /* indicate we need to lock cp_rwsem */ 1003 1003 bool in_list; /* indicate fio is in io_list */ 1004 + bool is_meta; /* indicate borrow meta inode mapping or not */ 1004 1005 enum iostat_type io_type; /* io type */ 1005 1006 struct writeback_control *io_wbc; /* writeback control */ 1006 1007 };
+19 -6
fs/f2fs/segment.h
··· 53 53 ((secno) == CURSEG_I(sbi, CURSEG_COLD_NODE)->segno / \ 54 54 (sbi)->segs_per_sec)) \ 55 55 56 - #define MAIN_BLKADDR(sbi) (SM_I(sbi)->main_blkaddr) 57 - #define SEG0_BLKADDR(sbi) (SM_I(sbi)->seg0_blkaddr) 56 + #define MAIN_BLKADDR(sbi) \ 57 + (SM_I(sbi) ? SM_I(sbi)->main_blkaddr : \ 58 + le32_to_cpu(F2FS_RAW_SUPER(sbi)->main_blkaddr)) 59 + #define SEG0_BLKADDR(sbi) \ 60 + (SM_I(sbi) ? SM_I(sbi)->seg0_blkaddr : \ 61 + le32_to_cpu(F2FS_RAW_SUPER(sbi)->segment0_blkaddr)) 58 62 59 63 #define MAIN_SEGS(sbi) (SM_I(sbi)->main_segments) 60 64 #define MAIN_SECS(sbi) ((sbi)->total_sections) 61 65 62 - #define TOTAL_SEGS(sbi) (SM_I(sbi)->segment_count) 66 + #define TOTAL_SEGS(sbi) \ 67 + (SM_I(sbi) ? SM_I(sbi)->segment_count : \ 68 + le32_to_cpu(F2FS_RAW_SUPER(sbi)->segment_count)) 63 69 #define TOTAL_BLKS(sbi) (TOTAL_SEGS(sbi) << (sbi)->log_blocks_per_seg) 64 70 65 71 #define MAX_BLKADDR(sbi) (SEG0_BLKADDR(sbi) + TOTAL_BLKS(sbi)) ··· 638 632 f2fs_bug_on(sbi, segno > TOTAL_SEGS(sbi) - 1); 639 633 } 640 634 641 - static inline void verify_block_addr(struct f2fs_sb_info *sbi, block_t blk_addr) 635 + static inline void verify_block_addr(struct f2fs_io_info *fio, block_t blk_addr) 642 636 { 643 - BUG_ON(blk_addr < SEG0_BLKADDR(sbi) 644 - || blk_addr >= MAX_BLKADDR(sbi)); 637 + struct f2fs_sb_info *sbi = fio->sbi; 638 + 639 + if (PAGE_TYPE_OF_BIO(fio->type) == META && 640 + (!is_read_io(fio->op) || fio->is_meta)) 641 + BUG_ON(blk_addr < SEG0_BLKADDR(sbi) || 642 + blk_addr >= MAIN_BLKADDR(sbi)); 643 + else 644 + BUG_ON(blk_addr < MAIN_BLKADDR(sbi) || 645 + blk_addr >= MAX_BLKADDR(sbi)); 645 646 } 646 647 647 648 /*