Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fcea9e00 authored by Yunlei He's avatar Yunlei He Committed by Jaegeuk Kim
Browse files

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: default avatarYunlei He <heyunlei@huawei.com>
Reviewed-by: default avatarChao Yu <yuchao0@huawei.com>
Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
parent 2c217b07
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -68,6 +68,7 @@ static struct page *__get_meta_page(struct f2fs_sb_info *sbi, pgoff_t index,
		.old_blkaddr = index,
		.new_blkaddr = index,
		.encrypted_page = NULL,
		.is_meta = is_meta,
	};

	if (unlikely(!is_meta))
@@ -162,6 +163,7 @@ int ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages,
		.op_flags = sync ? (REQ_META | REQ_PRIO) : REQ_RAHEAD,
		.encrypted_page = NULL,
		.in_list = false,
		.is_meta = (type != META_POR),
	};
	struct blk_plug plug;

+3 −2
Original line number Diff line number Diff line
@@ -383,6 +383,7 @@ int f2fs_submit_page_bio(struct f2fs_io_info *fio)
	struct page *page = fio->encrypted_page ?
			fio->encrypted_page : fio->page;

	verify_block_addr(fio, fio->new_blkaddr);
	trace_f2fs_submit_page_bio(page, fio);
	f2fs_trace_ios(fio, 0);

@@ -428,8 +429,8 @@ int f2fs_submit_page_write(struct f2fs_io_info *fio)
	}

	if (fio->old_blkaddr != NEW_ADDR)
		verify_block_addr(sbi, fio->old_blkaddr);
	verify_block_addr(sbi, fio->new_blkaddr);
		verify_block_addr(fio, fio->old_blkaddr);
	verify_block_addr(fio, fio->new_blkaddr);

	bio_page = fio->encrypted_page ? fio->encrypted_page : fio->page;

+1 −0
Original line number Diff line number Diff line
@@ -1001,6 +1001,7 @@ struct f2fs_io_info {
	bool submitted;		/* indicate IO submission */
	int need_lock;		/* indicate we need to lock cp_rwsem */
	bool in_list;		/* indicate fio is in io_list */
	bool is_meta;		/* indicate borrow meta inode mapping or not */
	enum iostat_type io_type;	/* io type */
	struct writeback_control *io_wbc; /* writeback control */
};
+19 −6
Original line number Diff line number Diff line
@@ -53,13 +53,19 @@
	 ((secno) == CURSEG_I(sbi, CURSEG_COLD_NODE)->segno /		\
	  (sbi)->segs_per_sec))	\

#define MAIN_BLKADDR(sbi)	(SM_I(sbi)->main_blkaddr)
#define SEG0_BLKADDR(sbi)	(SM_I(sbi)->seg0_blkaddr)
#define MAIN_BLKADDR(sbi)						\
	(SM_I(sbi) ? SM_I(sbi)->main_blkaddr : 				\
		le32_to_cpu(F2FS_RAW_SUPER(sbi)->main_blkaddr))
#define SEG0_BLKADDR(sbi)						\
	(SM_I(sbi) ? SM_I(sbi)->seg0_blkaddr : 				\
		le32_to_cpu(F2FS_RAW_SUPER(sbi)->segment0_blkaddr))

#define MAIN_SEGS(sbi)	(SM_I(sbi)->main_segments)
#define MAIN_SECS(sbi)	((sbi)->total_sections)

#define TOTAL_SEGS(sbi)	(SM_I(sbi)->segment_count)
#define TOTAL_SEGS(sbi)							\
	(SM_I(sbi) ? SM_I(sbi)->segment_count : 				\
		le32_to_cpu(F2FS_RAW_SUPER(sbi)->segment_count))
#define TOTAL_BLKS(sbi)	(TOTAL_SEGS(sbi) << (sbi)->log_blocks_per_seg)

#define MAX_BLKADDR(sbi)	(SEG0_BLKADDR(sbi) + TOTAL_BLKS(sbi))
@@ -632,10 +638,17 @@ static inline void check_seg_range(struct f2fs_sb_info *sbi, unsigned int segno)
	f2fs_bug_on(sbi, segno > TOTAL_SEGS(sbi) - 1);
}

static inline void verify_block_addr(struct f2fs_sb_info *sbi, block_t blk_addr)
static inline void verify_block_addr(struct f2fs_io_info *fio, block_t blk_addr)
{
	BUG_ON(blk_addr < SEG0_BLKADDR(sbi)
			|| blk_addr >= MAX_BLKADDR(sbi));
	struct f2fs_sb_info *sbi = fio->sbi;

	if (PAGE_TYPE_OF_BIO(fio->type) == META &&
				(!is_read_io(fio->op) || fio->is_meta))
		BUG_ON(blk_addr < SEG0_BLKADDR(sbi) ||
				blk_addr >= MAIN_BLKADDR(sbi));
	else
		BUG_ON(blk_addr < MAIN_BLKADDR(sbi) ||
				blk_addr >= MAX_BLKADDR(sbi));
}

/*