Commit c7115e09 authored by Chao Yu's avatar Chao Yu Committed by Jaegeuk Kim
Browse files

f2fs: introduce FAULT_BLKADDR_CONSISTENCE



We will encounter below inconsistent status when FAULT_BLKADDR type
fault injection is on.

Info: checkpoint state = d6 :  nat_bits crc fsck compacted_summary orphan_inodes sudden-power-off
[ASSERT] (fsck_chk_inode_blk:1254)  --> ino: 0x1c100 has i_blocks: 000000c0, but has 191 blocks
[FIX] (fsck_chk_inode_blk:1260)  --> [0x1c100] i_blocks=0x000000c0 -> 0xbf
[FIX] (fsck_chk_inode_blk:1269)  --> [0x1c100] i_compr_blocks=0x00000026 -> 0x27
[ASSERT] (fsck_chk_inode_blk:1254)  --> ino: 0x1cadb has i_blocks: 0000002f, but has 46 blocks
[FIX] (fsck_chk_inode_blk:1260)  --> [0x1cadb] i_blocks=0x0000002f -> 0x2e
[FIX] (fsck_chk_inode_blk:1269)  --> [0x1cadb] i_compr_blocks=0x00000011 -> 0x12
[ASSERT] (fsck_chk_inode_blk:1254)  --> ino: 0x1c62c has i_blocks: 00000002, but has 1 blocks
[FIX] (fsck_chk_inode_blk:1260)  --> [0x1c62c] i_blocks=0x00000002 -> 0x1

After we inject fault into f2fs_is_valid_blkaddr() during truncation,
a) it missed to increase @nr_free or @valid_blocks
b) it can cause in blkaddr leak in truncated dnode
Which may cause inconsistent status.

This patch separates FAULT_BLKADDR_CONSISTENCE from FAULT_BLKADDR,
and rename FAULT_BLKADDR to FAULT_BLKADDR_VALIDITY
so that we can:
a) use FAULT_BLKADDR_CONSISTENCE in f2fs_truncate_data_blocks_range()
to simulate inconsistent issue independently, then it can verify fsck
repair flow.
b) FAULT_BLKADDR_VALIDITY fault will not cause any inconsistent status,
we can just use it to check error path handling in kernel side.

Reviewed-by: default avatarDaeho Jeong <daehojeong@google.com>
Signed-off-by: default avatarChao Yu <chao@kernel.org>
Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
parent b896e302
Loading
Loading
Loading
Loading
+24 −23
Original line number Diff line number Diff line
@@ -701,9 +701,9 @@ Description: Support configuring fault injection type, should be
		enabled with fault_injection option, fault type value
		is shown below, it supports single or combined type.

		===================      ===========
		===========================      ===========
		Type_Name                        Type_Value
		===================      ===========
		===========================      ===========
		FAULT_KMALLOC                    0x000000001
		FAULT_KVMALLOC                   0x000000002
		FAULT_PAGE_ALLOC                 0x000000004
@@ -722,8 +722,9 @@ Description: Support configuring fault injection type, should be
		FAULT_SLAB_ALLOC                 0x000008000
		FAULT_DQUOT_INIT                 0x000010000
		FAULT_LOCK_OP                    0x000020000
		FAULT_BLKADDR            0x000040000
		===================      ===========
		FAULT_BLKADDR_VALIDITY           0x000040000
		FAULT_BLKADDR_CONSISTENCE        0x000080000
		===========================      ===========

What:		/sys/fs/f2fs/<disk>/discard_io_aware_gran
Date:		January 2023
+24 −23
Original line number Diff line number Diff line
@@ -184,9 +184,9 @@ fault_type=%d Support configuring fault injection type, should be
			 enabled with fault_injection option, fault type value
			 is shown below, it supports single or combined type.

			 ===================	  ===========
			 ===========================      ===========
			 Type_Name                        Type_Value
			 ===================	  ===========
			 ===========================      ===========
			 FAULT_KMALLOC                    0x000000001
			 FAULT_KVMALLOC                   0x000000002
			 FAULT_PAGE_ALLOC                 0x000000004
@@ -205,8 +205,9 @@ fault_type=%d Support configuring fault injection type, should be
			 FAULT_SLAB_ALLOC                 0x000008000
			 FAULT_DQUOT_INIT                 0x000010000
			 FAULT_LOCK_OP                    0x000020000
			 FAULT_BLKADDR		  0x000040000
			 ===================	  ===========
			 FAULT_BLKADDR_VALIDITY           0x000040000
			 FAULT_BLKADDR_CONSISTENCE        0x000080000
			 ===========================      ===========
mode=%s			 Control block allocation mode which supports "adaptive"
			 and "lfs". In "lfs" mode, there should be no random
			 writes towards main area.
+15 −4
Original line number Diff line number Diff line
@@ -170,12 +170,9 @@ static bool __is_bitmap_valid(struct f2fs_sb_info *sbi, block_t blkaddr,
	return exist;
}

bool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi,
static bool __f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi,
					block_t blkaddr, int type)
{
	if (time_to_inject(sbi, FAULT_BLKADDR))
		return false;

	switch (type) {
	case META_NAT:
		break;
@@ -230,6 +227,20 @@ bool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi,
	return true;
}

bool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi,
					block_t blkaddr, int type)
{
	if (time_to_inject(sbi, FAULT_BLKADDR_VALIDITY))
		return false;
	return __f2fs_is_valid_blkaddr(sbi, blkaddr, type);
}

bool f2fs_is_valid_blkaddr_raw(struct f2fs_sb_info *sbi,
					block_t blkaddr, int type)
{
	return __f2fs_is_valid_blkaddr(sbi, blkaddr, type);
}

/*
 * Readahead CP/NAT/SIT/SSA/POR pages
 */
+4 −1
Original line number Diff line number Diff line
@@ -60,7 +60,8 @@ enum {
	FAULT_SLAB_ALLOC,
	FAULT_DQUOT_INIT,
	FAULT_LOCK_OP,
	FAULT_BLKADDR,
	FAULT_BLKADDR_VALIDITY,
	FAULT_BLKADDR_CONSISTENCE,
	FAULT_MAX,
};

@@ -3768,6 +3769,8 @@ struct page *f2fs_get_meta_page_retry(struct f2fs_sb_info *sbi, pgoff_t index);
struct page *f2fs_get_tmp_page(struct f2fs_sb_info *sbi, pgoff_t index);
bool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi,
					block_t blkaddr, int type);
bool f2fs_is_valid_blkaddr_raw(struct f2fs_sb_info *sbi,
					block_t blkaddr, int type);
int f2fs_ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages,
			int type, bool sync);
void f2fs_ra_meta_pages_cond(struct f2fs_sb_info *sbi, pgoff_t index,
+6 −2
Original line number Diff line number Diff line
@@ -590,9 +590,13 @@ void f2fs_truncate_data_blocks_range(struct dnode_of_data *dn, int count)
		f2fs_set_data_blkaddr(dn, NULL_ADDR);

		if (__is_valid_data_blkaddr(blkaddr)) {
			if (!f2fs_is_valid_blkaddr(sbi, blkaddr,
					DATA_GENERIC_ENHANCE))
			if (time_to_inject(sbi, FAULT_BLKADDR_CONSISTENCE))
				continue;
			if (!f2fs_is_valid_blkaddr_raw(sbi, blkaddr,
						DATA_GENERIC_ENHANCE)) {
				f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR);
				continue;
			}
			if (compressed_cluster)
				valid_blocks++;
		}
Loading