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

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
...@@ -701,9 +701,9 @@ Description: Support configuring fault injection type, should be ...@@ -701,9 +701,9 @@ Description: Support configuring fault injection type, should be
enabled with fault_injection option, fault type value enabled with fault_injection option, fault type value
is shown below, it supports single or combined type. is shown below, it supports single or combined type.
=================== =========== =========================== ===========
Type_Name Type_Value Type_Name Type_Value
=================== =========== =========================== ===========
FAULT_KMALLOC 0x000000001 FAULT_KMALLOC 0x000000001
FAULT_KVMALLOC 0x000000002 FAULT_KVMALLOC 0x000000002
FAULT_PAGE_ALLOC 0x000000004 FAULT_PAGE_ALLOC 0x000000004
...@@ -722,8 +722,9 @@ Description: Support configuring fault injection type, should be ...@@ -722,8 +722,9 @@ Description: Support configuring fault injection type, should be
FAULT_SLAB_ALLOC 0x000008000 FAULT_SLAB_ALLOC 0x000008000
FAULT_DQUOT_INIT 0x000010000 FAULT_DQUOT_INIT 0x000010000
FAULT_LOCK_OP 0x000020000 FAULT_LOCK_OP 0x000020000
FAULT_BLKADDR 0x000040000 FAULT_BLKADDR_VALIDITY 0x000040000
=================== =========== FAULT_BLKADDR_CONSISTENCE 0x000080000
=========================== ===========
What: /sys/fs/f2fs/<disk>/discard_io_aware_gran What: /sys/fs/f2fs/<disk>/discard_io_aware_gran
Date: January 2023 Date: January 2023
......
...@@ -184,9 +184,9 @@ fault_type=%d Support configuring fault injection type, should be ...@@ -184,9 +184,9 @@ fault_type=%d Support configuring fault injection type, should be
enabled with fault_injection option, fault type value enabled with fault_injection option, fault type value
is shown below, it supports single or combined type. is shown below, it supports single or combined type.
=================== =========== =========================== ===========
Type_Name Type_Value Type_Name Type_Value
=================== =========== =========================== ===========
FAULT_KMALLOC 0x000000001 FAULT_KMALLOC 0x000000001
FAULT_KVMALLOC 0x000000002 FAULT_KVMALLOC 0x000000002
FAULT_PAGE_ALLOC 0x000000004 FAULT_PAGE_ALLOC 0x000000004
...@@ -205,8 +205,9 @@ fault_type=%d Support configuring fault injection type, should be ...@@ -205,8 +205,9 @@ fault_type=%d Support configuring fault injection type, should be
FAULT_SLAB_ALLOC 0x000008000 FAULT_SLAB_ALLOC 0x000008000
FAULT_DQUOT_INIT 0x000010000 FAULT_DQUOT_INIT 0x000010000
FAULT_LOCK_OP 0x000020000 FAULT_LOCK_OP 0x000020000
FAULT_BLKADDR 0x000040000 FAULT_BLKADDR_VALIDITY 0x000040000
=================== =========== FAULT_BLKADDR_CONSISTENCE 0x000080000
=========================== ===========
mode=%s Control block allocation mode which supports "adaptive" mode=%s Control block allocation mode which supports "adaptive"
and "lfs". In "lfs" mode, there should be no random and "lfs". In "lfs" mode, there should be no random
writes towards main area. writes towards main area.
......
...@@ -170,12 +170,9 @@ static bool __is_bitmap_valid(struct f2fs_sb_info *sbi, block_t blkaddr, ...@@ -170,12 +170,9 @@ static bool __is_bitmap_valid(struct f2fs_sb_info *sbi, block_t blkaddr,
return exist; 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) block_t blkaddr, int type)
{ {
if (time_to_inject(sbi, FAULT_BLKADDR))
return false;
switch (type) { switch (type) {
case META_NAT: case META_NAT:
break; break;
...@@ -230,6 +227,20 @@ bool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi, ...@@ -230,6 +227,20 @@ bool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi,
return true; 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 * Readahead CP/NAT/SIT/SSA/POR pages
*/ */
......
...@@ -60,7 +60,8 @@ enum { ...@@ -60,7 +60,8 @@ enum {
FAULT_SLAB_ALLOC, FAULT_SLAB_ALLOC,
FAULT_DQUOT_INIT, FAULT_DQUOT_INIT,
FAULT_LOCK_OP, FAULT_LOCK_OP,
FAULT_BLKADDR, FAULT_BLKADDR_VALIDITY,
FAULT_BLKADDR_CONSISTENCE,
FAULT_MAX, FAULT_MAX,
}; };
...@@ -3768,6 +3769,8 @@ struct page *f2fs_get_meta_page_retry(struct f2fs_sb_info *sbi, pgoff_t index); ...@@ -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); struct page *f2fs_get_tmp_page(struct f2fs_sb_info *sbi, pgoff_t index);
bool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi, bool f2fs_is_valid_blkaddr(struct f2fs_sb_info *sbi,
block_t blkaddr, int type); 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 f2fs_ra_meta_pages(struct f2fs_sb_info *sbi, block_t start, int nrpages,
int type, bool sync); int type, bool sync);
void f2fs_ra_meta_pages_cond(struct f2fs_sb_info *sbi, pgoff_t index, void f2fs_ra_meta_pages_cond(struct f2fs_sb_info *sbi, pgoff_t index,
......
...@@ -590,9 +590,13 @@ void f2fs_truncate_data_blocks_range(struct dnode_of_data *dn, int count) ...@@ -590,9 +590,13 @@ void f2fs_truncate_data_blocks_range(struct dnode_of_data *dn, int count)
f2fs_set_data_blkaddr(dn, NULL_ADDR); f2fs_set_data_blkaddr(dn, NULL_ADDR);
if (__is_valid_data_blkaddr(blkaddr)) { if (__is_valid_data_blkaddr(blkaddr)) {
if (!f2fs_is_valid_blkaddr(sbi, blkaddr, if (time_to_inject(sbi, FAULT_BLKADDR_CONSISTENCE))
DATA_GENERIC_ENHANCE))
continue; continue;
if (!f2fs_is_valid_blkaddr_raw(sbi, blkaddr,
DATA_GENERIC_ENHANCE)) {
f2fs_handle_error(sbi, ERROR_INVALID_BLKADDR);
continue;
}
if (compressed_cluster) if (compressed_cluster)
valid_blocks++; valid_blocks++;
} }
......
...@@ -61,7 +61,8 @@ const char *f2fs_fault_name[FAULT_MAX] = { ...@@ -61,7 +61,8 @@ const char *f2fs_fault_name[FAULT_MAX] = {
[FAULT_SLAB_ALLOC] = "slab alloc", [FAULT_SLAB_ALLOC] = "slab alloc",
[FAULT_DQUOT_INIT] = "dquot initialize", [FAULT_DQUOT_INIT] = "dquot initialize",
[FAULT_LOCK_OP] = "lock_op", [FAULT_LOCK_OP] = "lock_op",
[FAULT_BLKADDR] = "invalid blkaddr", [FAULT_BLKADDR_VALIDITY] = "invalid blkaddr",
[FAULT_BLKADDR_CONSISTENCE] = "inconsistent blkaddr",
}; };
void f2fs_build_fault_attr(struct f2fs_sb_info *sbi, unsigned int rate, void f2fs_build_fault_attr(struct f2fs_sb_info *sbi, unsigned int rate,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment