* [f2fs-dev] [PATCH v2 1/1] f2fs-tools: Check and clear invalid dent flag flags during recovery
@ 2026-01-12 6:11 liujinbao1
2026-01-12 7:53 ` Chao Yu via Linux-f2fs-devel
0 siblings, 1 reply; 2+ messages in thread
From: liujinbao1 @ 2026-01-12 6:11 UTC (permalink / raw)
To: jaegeuk, jinbaoliu365
Cc: Yongpeng Yang, Sheng Yong, liujinbao1, linux-f2fs-devel
From: liujinbao1 <liujinbao1@xiaomi.com>
During SPO tests, when mounting F2FS, an -EINVAL error was returned.
The issue originates from the f2fs_recover_inode_page function's
check, where old_ni.blk_addr != NULL_ADDR under the conditions of
IS_INODE(folio) && is_dent_dnode(folio).
Add detection and repair for this scenario in fsck.
Signed-off-by: Sheng Yong <shengyong1@xiaomi.com>
Signed-off-by: Yongpeng Yang <yangyongpeng@xiaomi.com>
Signed-off-by: Jinbao Liu <liujinbao1@xiaomi.com>
---
v2:
- Clear the node_blk dent flag, proceed with recovery
of this and subsequent data.
---
v1:
- Clear the node_blk fsync flag, set next_blkaddr=NULL,
skip recovery of this and later data.
---
fsck/mount.c | 21 ++++++++++++++++++++-
fsck/node.h | 13 +++++++++++++
2 files changed, 33 insertions(+), 1 deletion(-)
diff --git a/fsck/mount.c b/fsck/mount.c
index 6f640a0..8254644 100644
--- a/fsck/mount.c
+++ b/fsck/mount.c
@@ -3878,6 +3878,7 @@ int f2fs_find_fsync_inode(struct f2fs_sb_info *sbi, struct list_head *head)
while (1) {
struct fsync_inode_entry *entry;
+ struct f2fs_nat_entry nat_entry;
if (!f2fs_is_valid_blkaddr(sbi, blkaddr, META_POR))
break;
@@ -3902,8 +3903,26 @@ int f2fs_find_fsync_inode(struct f2fs_sb_info *sbi, struct list_head *head)
}
entry->blkaddr = blkaddr;
- if (IS_INODE(node_blk) && is_dent_dnode(node_blk))
+ if (IS_INODE(node_blk) && is_dent_dnode(node_blk)) {
+ get_nat_entry(sbi, ino_of_node(node_blk), &nat_entry);
+ if (is_valid_data_blkaddr(nat_entry.block_addr)) {
+ ASSERT_MSG("Invalid dent flag: blkaddr = %#x, "
+ "ino: %u, is_dent:%d, nat entry blkaddr is %#X\n",
+ blkaddr, ino_of_node(node_blk), is_dent_dnode(node_blk),
+ nat_entry.block_addr);
+ if (c.fix_on && f2fs_dev_is_writable()) {
+ int ret = 0;
+
+ FIX_MSG("Clear dent flag: blkaddr:%#x, ino: %u\n",
+ blkaddr, ino_of_node(node_blk));
+ set_dentry_mark(node_blk, 0);
+ ret = update_inode(sbi, node_blk, blkaddr);
+ ASSERT(ret >= 0);
+ goto next;
+ }
+ }
entry->last_dentry = blkaddr;
+ }
next:
blkaddr = next_blkaddr_of_node(node_blk);
diff --git a/fsck/node.h b/fsck/node.h
index 19f1e57..f3e2c46 100644
--- a/fsck/node.h
+++ b/fsck/node.h
@@ -173,6 +173,19 @@ static inline void set_cold_node(struct f2fs_node *rn, bool is_dir)
F2FS_NODE_FOOTER(rn)->flag = cpu_to_le32(flag);
}
+static inline void set_mark(struct f2fs_node *rn, int mark, int type)
+{
+ unsigned int flag = le32_to_cpu(F2FS_NODE_FOOTER(rn)->flag);
+
+ if (mark)
+ flag |= (1 << type);
+ else
+ flag &= ~(1 << type);
+ F2FS_NODE_FOOTER(rn)->flag = cpu_to_le32(flag);
+}
+
+#define set_dentry_mark(page, mark) set_mark(page, mark, DENT_BIT_SHIFT)
+
#define is_fsync_dnode(node_blk) is_node(node_blk, FSYNC_BIT_SHIFT)
#define is_dent_dnode(node_blk) is_node(node_blk, DENT_BIT_SHIFT)
--
2.25.1
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [f2fs-dev] [PATCH v2 1/1] f2fs-tools: Check and clear invalid dent flag flags during recovery
2026-01-12 6:11 [f2fs-dev] [PATCH v2 1/1] f2fs-tools: Check and clear invalid dent flag flags during recovery liujinbao1
@ 2026-01-12 7:53 ` Chao Yu via Linux-f2fs-devel
0 siblings, 0 replies; 2+ messages in thread
From: Chao Yu via Linux-f2fs-devel @ 2026-01-12 7:53 UTC (permalink / raw)
To: liujinbao1, jaegeuk
Cc: Yongpeng Yang, Sheng Yong, liujinbao1, linux-f2fs-devel
Jinbao,
On 1/12/2026 2:11 PM, liujinbao1 wrote:
> From: liujinbao1 <liujinbao1@xiaomi.com>
>
> During SPO tests, when mounting F2FS, an -EINVAL error was returned.
> The issue originates from the f2fs_recover_inode_page function's
> check, where old_ni.blk_addr != NULL_ADDR under the conditions of
> IS_INODE(folio) && is_dent_dnode(folio).
> Add detection and repair for this scenario in fsck.
>
> Signed-off-by: Sheng Yong <shengyong1@xiaomi.com>
> Signed-off-by: Yongpeng Yang <yangyongpeng@xiaomi.com>
> Signed-off-by: Jinbao Liu <liujinbao1@xiaomi.com>
> ---
> v2:
> - Clear the node_blk dent flag, proceed with recovery
> of this and subsequent data.
> ---
> v1:
> - Clear the node_blk fsync flag, set next_blkaddr=NULL,
> skip recovery of this and later data.
> ---
> fsck/mount.c | 21 ++++++++++++++++++++-
> fsck/node.h | 13 +++++++++++++
> 2 files changed, 33 insertions(+), 1 deletion(-)
>
> diff --git a/fsck/mount.c b/fsck/mount.c
> index 6f640a0..8254644 100644
> --- a/fsck/mount.c
> +++ b/fsck/mount.c
> @@ -3878,6 +3878,7 @@ int f2fs_find_fsync_inode(struct f2fs_sb_info *sbi, struct list_head *head)
>
> while (1) {
> struct fsync_inode_entry *entry;
> + struct f2fs_nat_entry nat_entry;
>
> if (!f2fs_is_valid_blkaddr(sbi, blkaddr, META_POR))
> break;
> @@ -3902,8 +3903,26 @@ int f2fs_find_fsync_inode(struct f2fs_sb_info *sbi, struct list_head *head)
> }
> entry->blkaddr = blkaddr;
>
> - if (IS_INODE(node_blk) && is_dent_dnode(node_blk))
> + if (IS_INODE(node_blk) && is_dent_dnode(node_blk)) {
> + get_nat_entry(sbi, ino_of_node(node_blk), &nat_entry);
> + if (is_valid_data_blkaddr(nat_entry.block_addr)) {
> + ASSERT_MSG("Invalid dent flag: blkaddr = %#x, "
> + "ino: %u, is_dent:%d, nat entry blkaddr is %#X\n",
> + blkaddr, ino_of_node(node_blk), is_dent_dnode(node_blk),
> + nat_entry.block_addr);
> + if (c.fix_on && f2fs_dev_is_writable()) {
> + int ret = 0;
int ret;
No need to initialize ret variable.
BTW, can you please use inject.f2fs to simulate such inconsistent image,
and use the image to test this fix? it will be better to include the
testcase and result in commit message. What do you think?
Thanks,
> +
> + FIX_MSG("Clear dent flag: blkaddr:%#x, ino: %u\n",
> + blkaddr, ino_of_node(node_blk));
> + set_dentry_mark(node_blk, 0);
> + ret = update_inode(sbi, node_blk, blkaddr);
> + ASSERT(ret >= 0);
> + goto next;
> + }
> + }
> entry->last_dentry = blkaddr;
> + }
> next:
> blkaddr = next_blkaddr_of_node(node_blk);
>
> diff --git a/fsck/node.h b/fsck/node.h
> index 19f1e57..f3e2c46 100644
> --- a/fsck/node.h
> +++ b/fsck/node.h
> @@ -173,6 +173,19 @@ static inline void set_cold_node(struct f2fs_node *rn, bool is_dir)
> F2FS_NODE_FOOTER(rn)->flag = cpu_to_le32(flag);
> }
>
> +static inline void set_mark(struct f2fs_node *rn, int mark, int type)
> +{
> + unsigned int flag = le32_to_cpu(F2FS_NODE_FOOTER(rn)->flag);
> +
> + if (mark)
> + flag |= (1 << type);
> + else
> + flag &= ~(1 << type);
> + F2FS_NODE_FOOTER(rn)->flag = cpu_to_le32(flag);
> +}
> +
> +#define set_dentry_mark(page, mark) set_mark(page, mark, DENT_BIT_SHIFT)
> +
> #define is_fsync_dnode(node_blk) is_node(node_blk, FSYNC_BIT_SHIFT)
> #define is_dent_dnode(node_blk) is_node(node_blk, DENT_BIT_SHIFT)
>
_______________________________________________
Linux-f2fs-devel mailing list
Linux-f2fs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-01-12 7:53 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-01-12 6:11 [f2fs-dev] [PATCH v2 1/1] f2fs-tools: Check and clear invalid dent flag flags during recovery liujinbao1
2026-01-12 7:53 ` Chao Yu via Linux-f2fs-devel
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox