linux-f2fs-devel.lists.sourceforge.net archive mirror
 help / color / mirror / Atom feed
From: Chao Yu via Linux-f2fs-devel <linux-f2fs-devel@lists.sourceforge.net>
To: Sheng Yong <shengyong2021@gmail.com>, jaegeuk@kernel.org
Cc: shengyong1@xiaomi.com, linux-f2fs-devel@lists.sourceforge.net
Subject: Re: [f2fs-dev] [PATCH v3 10/13] inject.f2fs: add members in inject_cp
Date: Sat, 23 Aug 2025 16:28:23 +0800	[thread overview]
Message-ID: <0521479a-4173-4bf8-b0a8-47de61982d44@kernel.org> (raw)
In-Reply-To: <20250820124238.3785621-11-shengyong1@xiaomi.com>

On 8/20/2025 8:42 PM, Sheng Yong wrote:
> From: Sheng Yong <shengyong1@xiaomi.com>
> 
> The following members are added to inject more fields in cp:
> 
> * next_blkaddr: inject fsync dnodes
> 
>    An error is returned if no fsync dnode is found.
>    Furthermore, the injection is not supported on a zoned device. This
>    is because fsync dnodes must remains at the end of current warm node
>    segment, any dnode change causes all previous dnodes in the chain to
>    be updated out-of-place, and there may not have enough space left in
>    the curseg. To simplify the injection, it returns an error on the
>    zoned device.
>    An example of dnode chain shows:
>      [inject_cp: 608] [   0] blkaddr:0x1204
>      [inject_cp: 608] [   1] blkaddr:0x1205
>      [inject_cp: 608] [   2] blkaddr:0x1206
>      [inject_cp: 608] [   3] blkaddr:0x1207
>      [inject_cp: 608] [   4] blkaddr:0x1208
>      [inject_cp: 608] [   5] blkaddr:0x1209
>      [inject_cp: 608] [   6] blkaddr:0x120a
>      [inject_cp: 608] [   7] blkaddr:0x120b
>      [inject_cp: 608] [   8] blkaddr:0x120c
>      [inject_cp: 608] [   9] blkaddr:0x120d
>    where `0' indicates next free blkaddr of warm node curseg, thus
>    start blkaddr + next_blkoff of warm node curseg, which cannot be
>    injected. `1~9` indicate next_blkaddr in node_footer of dnodes in
>    the chain, which can be injected.
> 
> * alloc_type: inject curseg's alloc type
> * crc: inject cp's checksum
> * elapsed_time: inject cp's mount elapsed time
> 
> Signed-off-by: Sheng Yong <shengyong1@xiaomi.com>
> ---
> v3: * update commit message to show dnode chain and the injectable range
>      * free(node) before return
> ---
>   fsck/fsck.h       |  4 ++-
>   fsck/inject.c     | 86 ++++++++++++++++++++++++++++++++++++++++++++++-
>   fsck/mount.c      | 18 +++++-----
>   man/inject.f2fs.8 | 11 +++++-
>   4 files changed, 108 insertions(+), 11 deletions(-)
> 
> diff --git a/fsck/fsck.h b/fsck/fsck.h
> index 40cb6d9a6417..05daa2de9531 100644
> --- a/fsck/fsck.h
> +++ b/fsck/fsck.h
> @@ -223,6 +223,8 @@ extern int f2fs_ra_meta_pages(struct f2fs_sb_info *, block_t, int, int);
>   extern int f2fs_do_mount(struct f2fs_sb_info *);
>   extern void f2fs_do_umount(struct f2fs_sb_info *);
>   extern int f2fs_sparse_initialize_meta(struct f2fs_sb_info *);
> +extern int f2fs_find_fsync_inode(struct f2fs_sb_info *, struct list_head *);
> +extern void f2fs_destroy_fsync_dnodes(struct list_head *);
>   
>   extern void flush_journal_entries(struct f2fs_sb_info *);
>   extern void update_curseg_info(struct f2fs_sb_info *, int);
> @@ -239,7 +241,7 @@ extern void duplicate_checkpoint(struct f2fs_sb_info *);
>   extern void write_checkpoint(struct f2fs_sb_info *);
>   extern void write_checkpoints(struct f2fs_sb_info *);
>   extern void write_raw_cp_blocks(struct f2fs_sb_info *sbi,
> -			struct f2fs_checkpoint *cp, int which);
> +			struct f2fs_checkpoint *cp, int which, bool update_crc);
>   extern void update_superblock(struct f2fs_super_block *, int);
>   extern void update_data_blkaddr(struct f2fs_sb_info *, nid_t, u16, block_t,
>   			struct f2fs_node *);
> diff --git a/fsck/inject.c b/fsck/inject.c
> index 5ca105b60f8e..272a4a64dc05 100644
> --- a/fsck/inject.c
> +++ b/fsck/inject.c
> @@ -151,6 +151,10 @@ static void inject_cp_usage(void)
>   	MSG(0, "  cur_node_blkoff: inject cur_node_blkoff array selected by --idx <index>\n");
>   	MSG(0, "  cur_data_segno: inject cur_data_segno array selected by --idx <index>\n");
>   	MSG(0, "  cur_data_blkoff: inject cur_data_blkoff array selected by --idx <index>\n");
> +	MSG(0, "  alloc_type: inject alloc_type array selected by --idx <index>\n");
> +	MSG(0, "  next_blkaddr: inject next_blkaddr of fsync dnodes selected by --idx <index>\n");
> +	MSG(0, "  crc: inject crc checksum\n");
> +	MSG(0, "  elapsed_time: inject elapsed_time\n");
>   }
>   
>   static void inject_nat_usage(void)
> @@ -456,6 +460,7 @@ out:
>   static int inject_cp(struct f2fs_sb_info *sbi, struct inject_option *opt)
>   {
>   	struct f2fs_checkpoint *cp, *cur_cp = F2FS_CKPT(sbi);
> +	bool update_crc = true;
>   	char *buf = NULL;
>   	int ret = 0;
>   
> @@ -534,6 +539,85 @@ static int inject_cp(struct f2fs_sb_info *sbi, struct inject_option *opt)
>   		    opt->idx, opt->cp, get_cp(cur_data_blkoff[opt->idx]),
>   		    (u16)opt->val);
>   		set_cp(cur_data_blkoff[opt->idx], (u16)opt->val);
> +	} else if (!strcmp(opt->mb, "alloc_type")) {
> +		if (opt->idx >= MAX_ACTIVE_LOGS) {
> +			ERR_MSG("invalid index %u of cp->alloc_type[]\n",
> +				opt->idx);
> +			ret = -EINVAL;
> +			goto out;
> +		}
> +		MSG(0, "Info: inject alloc_type[%d] of cp %d: 0x%x -> 0x%x\n",
> +		    opt->idx, opt->cp, cp->alloc_type[opt->idx],
> +		    (unsigned char)opt->val);
> +		cp->alloc_type[opt->idx] = (unsigned char)opt->val;
> +	} else if (!strcmp(opt->mb, "next_blkaddr")) {
> +		struct fsync_inode_entry *entry;
> +		struct list_head inode_list = LIST_HEAD_INIT(inode_list);
> +		struct f2fs_node *node;
> +		block_t blkaddr;
> +		int i = 0;
> +
> +		if (c.zoned_model == F2FS_ZONED_HM) {
> +			ERR_MSG("inject fsync dnodes not supported in "
> +				"zoned device\n");
> +			ret = -EOPNOTSUPP;
> +			goto out;
> +		}
> +
> +		if (!need_fsync_data_record(sbi)) {
> +			ERR_MSG("no need to recover fsync dnodes\n");
> +			ret = -EINVAL;
> +			goto out;
> +		}
> +
> +		ret = f2fs_find_fsync_inode(sbi, &inode_list);
> +		if (ret) {
> +			ERR_MSG("failed to find fsync inodes: %d\n", ret);
> +			goto out;
> +		}
> +
> +		list_for_each_entry(entry, &inode_list, list) {
> +			if (i == opt->idx)
> +				blkaddr = entry->blkaddr;
> +			DBG(0, "[%4d] blkaddr:0x%x\n", i++, entry->blkaddr);
> +		}
> +
> +		f2fs_destroy_fsync_dnodes(&inode_list);
> +
> +		if (opt->idx == 0 || opt->idx >= i) {
> +			ERR_MSG("invalid index %u of fsync dnodes range [1, %u]\n",
> +				opt->idx, i);
> +			ret = -EINVAL;
> +			goto out;
> +		}
> +
> +		MSG(0, "Info: inject next_blkaddr[%d] of cp %d: 0x%x -> 0x%x\n",
> +		    opt->idx, opt->cp, blkaddr, (u32)opt->val);
> +
> +		node = malloc(F2FS_BLKSIZE);
> +		ASSERT(node);
> +		ret = dev_read_block(node, blkaddr);
> +		ASSERT(ret >= 0);
> +		F2FS_NODE_FOOTER(node)->next_blkaddr = cpu_to_le32((u32)opt->val);
> +		if (IS_INODE(node))
> +			ret = update_inode(sbi, node, &blkaddr);
> +		else
> +			ret = update_block(sbi, node, &blkaddr, NULL);
> +		free(node);
> +		ASSERT(ret >= 0);
> +		goto out;
> +	} else if (!strcmp(opt->mb, "crc")) {
> +		__le32 *crc = (__le32 *)((unsigned char *)cp +
> +						get_cp(checksum_offset));
> +
> +		MSG(0, "Info: inject crc of cp %d: 0x%x -> 0x%x\n",
> +		    opt->cp, le32_to_cpu(*crc), (u32)opt->val);
> +		*crc = cpu_to_le32((u32)opt->val);
> +		update_crc = false;
> +	} else if (!strcmp(opt->mb, "elapsed_time")) {
> +		MSG(0, "Info: inject elapsed_time of cp %d: %llu -> %"PRIu64"\n",
> +		    opt->cp, get_cp(elapsed_time), (u64)opt->val);
> +		set_cp(elapsed_time, (u64)opt->val);
>   	} else {
>   		ERR_MSG("unknown or unsupported member \"%s\"\n", opt->mb);
>   		ret = -EINVAL;
> @@ -541,7 +625,7 @@ static int inject_cp(struct f2fs_sb_info *sbi, struct inject_option *opt)
>   	}
>   
>   	print_ckpt_info(sbi);
> -	write_raw_cp_blocks(sbi, cp, opt->cp);
> +	write_raw_cp_blocks(sbi, cp, opt->cp, update_crc);
>   
>   out:
>   	free(buf);
> diff --git a/fsck/mount.c b/fsck/mount.c
> index f9f780d4aff6..f03fa2d6861a 100644
> --- a/fsck/mount.c
> +++ b/fsck/mount.c
> @@ -3510,17 +3510,19 @@ void write_checkpoints(struct f2fs_sb_info *sbi)
>   	write_checkpoint(sbi);
>   }
>   
> -void write_raw_cp_blocks(struct f2fs_sb_info *sbi,
> -			 struct f2fs_checkpoint *cp, int which)
> +void write_raw_cp_blocks(struct f2fs_sb_info *sbi, struct f2fs_checkpoint *cp,
> +			 int which, bool update_crc)
>   {
>   	struct f2fs_super_block *sb = F2FS_RAW_SUPER(sbi);
>   	uint32_t crc;
>   	block_t cp_blkaddr;
>   	int ret;
>   
> -	crc = f2fs_checkpoint_chksum(cp);
> -	*((__le32 *)((unsigned char *)cp + get_cp(checksum_offset))) =
> +	if (update_crc) {
> +		crc = f2fs_checkpoint_chksum(cp);
> +		*((__le32 *)((unsigned char *)cp + get_cp(checksum_offset))) =
>   							cpu_to_le32(crc);
> +	}
>   
>   	cp_blkaddr = get_sb(cp_blkaddr);
>   	if (which == 2)
> @@ -3754,7 +3756,7 @@ static void del_fsync_inode(struct fsync_inode_entry *entry)
>   	free(entry);
>   }
>   
> -static void destroy_fsync_dnodes(struct list_head *head)
> +void f2fs_destroy_fsync_dnodes(struct list_head *head)
>   {
>   	struct fsync_inode_entry *entry, *tmp;
>   
> @@ -3860,7 +3862,7 @@ static int sanity_check_node_chain(struct f2fs_sb_info *sbi,
>   	return 0;
>   }
>   
> -static int find_fsync_inode(struct f2fs_sb_info *sbi, struct list_head *head)
> +int f2fs_find_fsync_inode(struct f2fs_sb_info *sbi, struct list_head *head)
>   {
>   	struct curseg_info *curseg;
>   	struct f2fs_node *node_blk, *node_blk_fast;
> @@ -4056,7 +4058,7 @@ static int record_fsync_data(struct f2fs_sb_info *sbi)
>   	if (!need_fsync_data_record(sbi))
>   		return 0;
>   
> -	ret = find_fsync_inode(sbi, &inode_list);
> +	ret = f2fs_find_fsync_inode(sbi, &inode_list);
>   	if (ret)
>   		goto out;
>   
> @@ -4071,7 +4073,7 @@ static int record_fsync_data(struct f2fs_sb_info *sbi)
>   
>   	ret = traverse_dnodes(sbi, &inode_list);
>   out:
> -	destroy_fsync_dnodes(&inode_list);
> +	f2fs_destroy_fsync_dnodes(&inode_list);
>   	return ret;
>   }
>   
> diff --git a/man/inject.f2fs.8 b/man/inject.f2fs.8
> index 65ac658a129b..0e7cd5065a15 100644
> --- a/man/inject.f2fs.8
> +++ b/man/inject.f2fs.8
> @@ -45,7 +45,7 @@ The available \fImb\fP of \fIsb\fP are:
>   .RS 1.2i
>   .TP
>   .BI magic
> -magic numbe.
> +magic number.
>   .TP
>   .BI s_stop_reason
>   s_stop_reason array.
> @@ -79,6 +79,15 @@ cur_data_segno array.
>   .TP
>   .BI cur_data_blkoff
>   cur_data_blkoff array.

alloc_type entry.

Thanks,

> +.TP
> +.BI next_blkaddr
> +fsync dnodes.
> +.TP
> +.BI crc
> +crc checksum.
> +.TP
> +.BI elapsed_time
> +elapsed mount time.
>   .RE
>   .TP
>   .BI \-\-nat " 0 or 1 or 2"



_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

  reply	other threads:[~2025-08-23  8:28 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-08-20 12:42 [f2fs-dev] [PATCH v3 00/13] f2fs-tools & inject.f2fs: bugfix and new injections Sheng Yong
2025-08-20 12:42 ` [f2fs-dev] [PATCH v3 01/13] fsck.f2fs: do not finish/reset zone if dry-run is true Sheng Yong
2025-08-20 12:42 ` [f2fs-dev] [PATCH v3 02/13] f2fs-tools: add option N to answer no for all questions Sheng Yong
2025-08-20 12:42 ` [f2fs-dev] [PATCH v3 03/13] f2fs-tools: cleanup {nid|segno}_in_journal Sheng Yong
2025-08-20 12:42 ` [f2fs-dev] [PATCH v3 04/13] fsck.f2fs: fix invalidate checkpoint Sheng Yong
2025-08-20 12:42 ` [f2fs-dev] [PATCH v3 05/13] dump.f2fs: print more info Sheng Yong
2025-08-20 12:42 ` [f2fs-dev] [PATCH v3 06/13] f2fs-tools: add and export lookup_sit_in_journal Sheng Yong
2025-08-20 12:42 ` [f2fs-dev] [PATCH v3 07/13] inject.f2fs: fix injecting sit/nat in journal Sheng Yong
2025-08-20 12:42 ` [f2fs-dev] [PATCH v3 08/13] inject.f2fs: fix injection on zoned device Sheng Yong
2025-08-20 12:42 ` [f2fs-dev] [PATCH v3 09/13] inject.f2fs: fix and cleanup parsing numeric options Sheng Yong
2025-08-20 12:42 ` [f2fs-dev] [PATCH v3 10/13] inject.f2fs: add members in inject_cp Sheng Yong
2025-08-23  8:28   ` Chao Yu via Linux-f2fs-devel [this message]
2025-08-20 12:42 ` [f2fs-dev] [PATCH v3 11/13] inject.f2fs: add member `feature' in inject_sb Sheng Yong
2025-08-20 12:42 ` [f2fs-dev] [PATCH v3 12/13] inject.f2fs: add members in inject_node Sheng Yong
2025-08-20 12:42 ` [f2fs-dev] [PATCH v3 13/13] inject.f2fs: add member `filename' in inject_dentry Sheng Yong
2025-08-23  8:34 ` [f2fs-dev] [PATCH v3 00/13] f2fs-tools & inject.f2fs: bugfix and new injections Chao Yu via Linux-f2fs-devel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=0521479a-4173-4bf8-b0a8-47de61982d44@kernel.org \
    --to=linux-f2fs-devel@lists.sourceforge.net \
    --cc=chao@kernel.org \
    --cc=jaegeuk@kernel.org \
    --cc=shengyong1@xiaomi.com \
    --cc=shengyong2021@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).