Linux-f2fs-devel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [f2fs-dev] [PATCH v4 1/4] f2fs: refactor f2fs_move_node_folio function
@ 2026-03-17 11:54 Yongpeng Yang
  2026-03-17 11:54 ` [f2fs-dev] [PATCH v4 2/4] f2fs: refactor node footer flag setting related code Yongpeng Yang
                   ` (3 more replies)
  0 siblings, 4 replies; 10+ messages in thread
From: Yongpeng Yang @ 2026-03-17 11:54 UTC (permalink / raw)
  To: Chao Yu, Jaegeuk Kim; +Cc: Yongpeng Yang, Yongpeng Yang, linux-f2fs-devel

From: Yongpeng Yang <yangyongpeng@xiaomi.com>

This patch refactor the f2fs_move_node_folio() function. No logical
changes.

Signed-off-by: Yongpeng Yang <yangyongpeng@xiaomi.com>
---
 fs/f2fs/f2fs.h |  2 ++
 fs/f2fs/node.c | 54 ++++++++++++++++++++++++++++++--------------------
 2 files changed, 34 insertions(+), 22 deletions(-)

diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 660bf88a376f..afb4d10142dd 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -3950,6 +3950,8 @@ int f2fs_sanity_check_node_footer(struct f2fs_sb_info *sbi,
 					enum node_type ntype, bool in_irq);
 struct folio *f2fs_get_inode_folio(struct f2fs_sb_info *sbi, pgoff_t ino);
 struct folio *f2fs_get_xnode_folio(struct f2fs_sb_info *sbi, pgoff_t xnid);
+int f2fs_write_single_node_folio(struct folio *node_folio, int sync_mode,
+			bool mark_dirty, enum iostat_type io_type);
 int f2fs_move_node_folio(struct folio *node_folio, int gc_type);
 void f2fs_flush_inline_data(struct f2fs_sb_info *sbi);
 int f2fs_fsync_node_pages(struct f2fs_sb_info *sbi, struct inode *inode,
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index 17eab01ae8f9..2e74d2882b6f 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -1845,41 +1845,51 @@ static bool __write_node_folio(struct folio *folio, bool atomic, bool *submitted
 	return false;
 }
 
-int f2fs_move_node_folio(struct folio *node_folio, int gc_type)
+int f2fs_write_single_node_folio(struct folio *node_folio, int sync_mode,
+			bool mark_dirty, enum iostat_type io_type)
 {
 	int err = 0;
+	struct writeback_control wbc = {
+		.sync_mode = WB_SYNC_ALL,
+		.nr_to_write = 1,
+	};
 
-	if (gc_type == FG_GC) {
-		struct writeback_control wbc = {
-			.sync_mode = WB_SYNC_ALL,
-			.nr_to_write = 1,
-		};
+	if (!sync_mode) {
+		/* set page dirty and write it */
+		if (mark_dirty && !folio_test_writeback(node_folio))
+			folio_mark_dirty(node_folio);
+		goto out_folio;
+	}
 
-		f2fs_folio_wait_writeback(node_folio, NODE, true, true);
+	f2fs_folio_wait_writeback(node_folio, NODE, true, true);
 
+	if (mark_dirty)
 		folio_mark_dirty(node_folio);
+	else if (!folio_test_dirty(node_folio))
+		goto out_folio;
 
-		if (!folio_clear_dirty_for_io(node_folio)) {
-			err = -EAGAIN;
-			goto out_page;
-		}
-
-		if (!__write_node_folio(node_folio, false, NULL,
-					&wbc, false, FS_GC_NODE_IO, NULL))
-			err = -EAGAIN;
-		goto release_page;
-	} else {
-		/* set page dirty and write it */
-		if (!folio_test_writeback(node_folio))
-			folio_mark_dirty(node_folio);
+	if (!folio_clear_dirty_for_io(node_folio)) {
+		err = -EAGAIN;
+		goto out_folio;
 	}
-out_page:
+
+	if (!__write_node_folio(node_folio, false, NULL,
+				&wbc, false, FS_GC_NODE_IO, NULL))
+		err = -EAGAIN;
+	goto release_folio;
+out_folio:
 	folio_unlock(node_folio);
-release_page:
+release_folio:
 	f2fs_folio_put(node_folio, false);
 	return err;
 }
 
+int f2fs_move_node_folio(struct folio *node_folio, int gc_type)
+{
+	return f2fs_write_single_node_folio(node_folio, gc_type == FG_GC,
+			true, FS_GC_NODE_IO);
+}
+
 int f2fs_fsync_node_pages(struct f2fs_sb_info *sbi, struct inode *inode,
 			struct writeback_control *wbc, bool atomic,
 			unsigned int *seq_id)
-- 
2.43.0



_______________________________________________
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] 10+ messages in thread

* [f2fs-dev] [PATCH v4 2/4] f2fs: refactor node footer flag setting related code
  2026-03-17 11:54 [f2fs-dev] [PATCH v4 1/4] f2fs: refactor f2fs_move_node_folio function Yongpeng Yang
@ 2026-03-17 11:54 ` Yongpeng Yang
  2026-03-18  4:17   ` Chao Yu via Linux-f2fs-devel
  2026-03-17 11:55 ` [f2fs-dev] [PATCH v4 3/4] f2fs: fix fsck inconsistency caused by FGGC of node block Yongpeng Yang
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 10+ messages in thread
From: Yongpeng Yang @ 2026-03-17 11:54 UTC (permalink / raw)
  To: Chao Yu, Jaegeuk Kim; +Cc: Yongpeng Yang, Yongpeng Yang, linux-f2fs-devel

From: Yongpeng Yang <yangyongpeng@xiaomi.com>

This patch refactors the node footer flag setting code to simplify
redundant logic and adjust function parameters and return types. No
logical changes.

Signed-off-by: Yongpeng Yang <yangyongpeng@xiaomi.com>
---
 fs/f2fs/f2fs.h |  2 +-
 fs/f2fs/node.c |  2 +-
 fs/f2fs/node.h | 23 +++++++++++------------
 3 files changed, 13 insertions(+), 14 deletions(-)

diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index afb4d10142dd..3b1fdaac1ef6 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -3928,7 +3928,7 @@ bool f2fs_in_warm_node_list(struct folio *folio);
 void f2fs_init_fsync_node_info(struct f2fs_sb_info *sbi);
 void f2fs_del_fsync_node_entry(struct f2fs_sb_info *sbi, struct folio *folio);
 void f2fs_reset_fsync_node_info(struct f2fs_sb_info *sbi);
-int f2fs_need_dentry_mark(struct f2fs_sb_info *sbi, nid_t nid);
+bool f2fs_need_dentry_mark(struct f2fs_sb_info *sbi, nid_t nid);
 bool f2fs_is_checkpointed_node(struct f2fs_sb_info *sbi, nid_t nid);
 bool f2fs_need_inode_block_update(struct f2fs_sb_info *sbi, nid_t ino);
 int f2fs_get_node_info(struct f2fs_sb_info *sbi, nid_t nid,
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index 2e74d2882b6f..3c862d8ed3d9 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -391,7 +391,7 @@ void f2fs_reset_fsync_node_info(struct f2fs_sb_info *sbi)
 	spin_unlock_irqrestore(&sbi->fsync_node_lock, flags);
 }
 
-int f2fs_need_dentry_mark(struct f2fs_sb_info *sbi, nid_t nid)
+bool f2fs_need_dentry_mark(struct f2fs_sb_info *sbi, nid_t nid)
 {
 	struct f2fs_nm_info *nm_i = NM_I(sbi);
 	struct nat_entry *e;
diff --git a/fs/f2fs/node.h b/fs/f2fs/node.h
index 824ac9f0e6e4..219be30e6a68 100644
--- a/fs/f2fs/node.h
+++ b/fs/f2fs/node.h
@@ -400,27 +400,26 @@ static inline int is_node(const struct folio *folio, int type)
 #define is_fsync_dnode(folio)	is_node(folio, FSYNC_BIT_SHIFT)
 #define is_dent_dnode(folio)	is_node(folio, DENT_BIT_SHIFT)
 
-static inline void set_cold_node(const struct folio *folio, bool is_dir)
+static inline void __set_mark(const struct folio *folio, bool mark, int type)
 {
 	struct f2fs_node *rn = F2FS_NODE(folio);
 	unsigned int flag = le32_to_cpu(rn->footer.flag);
 
-	if (is_dir)
-		flag &= ~BIT(COLD_BIT_SHIFT);
-	else
-		flag |= BIT(COLD_BIT_SHIFT);
-	rn->footer.flag = cpu_to_le32(flag);
-}
-
-static inline void set_mark(struct folio *folio, int mark, int type)
-{
-	struct f2fs_node *rn = F2FS_NODE(folio);
-	unsigned int flag = le32_to_cpu(rn->footer.flag);
 	if (mark)
 		flag |= BIT(type);
 	else
 		flag &= ~BIT(type);
 	rn->footer.flag = cpu_to_le32(flag);
+}
+
+static inline void set_cold_node(const struct folio *folio, bool is_dir)
+{
+	__set_mark(folio, !is_dir, COLD_BIT_SHIFT);
+}
+
+static inline void set_mark(const struct folio *folio, bool mark, int type)
+{
+	__set_mark(folio, mark, type);
 
 #ifdef CONFIG_F2FS_CHECK_FS
 	f2fs_inode_chksum_set(F2FS_F_SB(folio), folio);
-- 
2.43.0



_______________________________________________
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] 10+ messages in thread

* [f2fs-dev] [PATCH v4 3/4] f2fs: fix fsck inconsistency caused by FGGC of node block
  2026-03-17 11:54 [f2fs-dev] [PATCH v4 1/4] f2fs: refactor f2fs_move_node_folio function Yongpeng Yang
  2026-03-17 11:54 ` [f2fs-dev] [PATCH v4 2/4] f2fs: refactor node footer flag setting related code Yongpeng Yang
@ 2026-03-17 11:55 ` Yongpeng Yang
  2026-03-18  4:26   ` Chao Yu via Linux-f2fs-devel
  2026-03-17 11:56 ` [f2fs-dev] [PATCH v4 4/4] f2fs: fix inline data not being written to disk in writeback path Yongpeng Yang
  2026-03-18  4:15 ` [f2fs-dev] [PATCH v4 1/4] f2fs: refactor f2fs_move_node_folio function Chao Yu via Linux-f2fs-devel
  3 siblings, 1 reply; 10+ messages in thread
From: Yongpeng Yang @ 2026-03-17 11:55 UTC (permalink / raw)
  To: Chao Yu, Jaegeuk Kim; +Cc: Yongpeng Yang, Yongpeng Yang, linux-f2fs-devel

From: Yongpeng Yang <yangyongpeng@xiaomi.com>

During FGGC node block migration, fsck may incorrectly treat the
migrated node block as fsync-written data.

The reproduction scenario:
root@vm:/mnt/f2fs# seq 1 2048 | xargs -n 1 ./test_sync // write inline inode and sync
root@vm:/mnt/f2fs# rm -f 1
root@vm:/mnt/f2fs# sync
root@vm:/mnt/f2fs# f2fs_io gc_range // move data block in sync mode and not write CP
  SPO, "fsck --dry-run" find inode has already checkpointed but still
  with DENT_BIT_SHIFT set

The root cause is that GC does not clear the dentry mark and fsync mark
during node block migration, leading fsck to misinterpret them as
user-issued fsync writes.

In BGGC mode, node block migration is handled by f2fs_sync_node_pages(),
which guarantees the dentry and fsync marks are cleared before writing.

This patch move the set/clear of the fsync|dentry marks into
__write_node_folio to make the logic clearer, and ensures the
fsync|dentry mark is cleared in FGGC.

Fixes: da011cc0da8c ("f2fs: move node pages only in victim section during GC")
Signed-off-by: Yongpeng Yang <yangyongpeng@xiaomi.com>
---
v4:
- Move the set/clear of the fsync|dentry marks into __write_node_folio().
v3:
- Clearing fsync|dentry marks in f2fs_write_single_node_folio() for FGGC.
---
 fs/f2fs/node.c | 27 +++++++++++++--------------
 1 file changed, 13 insertions(+), 14 deletions(-)

diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index 3c862d8ed3d9..0151dc4895d6 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -1732,9 +1732,10 @@ static struct folio *last_fsync_dnode(struct f2fs_sb_info *sbi, nid_t ino)
 	return last_folio;
 }
 
-static bool __write_node_folio(struct folio *folio, bool atomic, bool *submitted,
-				struct writeback_control *wbc, bool do_balance,
-				enum iostat_type io_type, unsigned int *seq_id)
+static bool __write_node_folio(struct folio *folio, bool atomic, bool do_fsync,
+				bool *submitted, struct writeback_control *wbc,
+				bool do_balance, enum iostat_type io_type,
+				unsigned int *seq_id)
 {
 	struct f2fs_sb_info *sbi = F2FS_F_SB(folio);
 	nid_t nid;
@@ -1807,6 +1808,8 @@ static bool __write_node_folio(struct folio *folio, bool atomic, bool *submitted
 	if (atomic && !test_opt(sbi, NOBARRIER))
 		fio.op_flags |= REQ_PREFLUSH | REQ_FUA;
 
+	set_dentry_mark(folio, false);
+	set_fsync_mark(folio, do_fsync);
 	if (IS_INODE(folio) && (atomic || is_fsync_dnode(folio)))
 		set_dentry_mark(folio,
 				f2fs_need_dentry_mark(sbi, ino_of_node(folio)));
@@ -1873,7 +1876,7 @@ int f2fs_write_single_node_folio(struct folio *node_folio, int sync_mode,
 		goto out_folio;
 	}
 
-	if (!__write_node_folio(node_folio, false, NULL,
+	if (!__write_node_folio(node_folio, false, false, NULL,
 				&wbc, false, FS_GC_NODE_IO, NULL))
 		err = -EAGAIN;
 	goto release_folio;
@@ -1920,6 +1923,7 @@ int f2fs_fsync_node_pages(struct f2fs_sb_info *sbi, struct inode *inode,
 		for (i = 0; i < nr_folios; i++) {
 			struct folio *folio = fbatch.folios[i];
 			bool submitted = false;
+			bool do_fsync = false;
 
 			if (unlikely(f2fs_cp_error(sbi))) {
 				f2fs_folio_put(last_folio, false);
@@ -1950,11 +1954,8 @@ int f2fs_fsync_node_pages(struct f2fs_sb_info *sbi, struct inode *inode,
 
 			f2fs_folio_wait_writeback(folio, NODE, true, true);
 
-			set_fsync_mark(folio, 0);
-			set_dentry_mark(folio, 0);
-
 			if (!atomic || folio == last_folio) {
-				set_fsync_mark(folio, 1);
+				do_fsync = true;
 				percpu_counter_inc(&sbi->rf_node_block_count);
 				if (IS_INODE(folio)) {
 					if (is_inode_flag_set(inode,
@@ -1971,8 +1972,9 @@ int f2fs_fsync_node_pages(struct f2fs_sb_info *sbi, struct inode *inode,
 
 			if (!__write_node_folio(folio, atomic &&
 						folio == last_folio,
-						&submitted, wbc, true,
-						FS_NODE_IO, seq_id)) {
+						do_fsync, &submitted,
+						wbc, true, FS_NODE_IO,
+						seq_id)) {
 				f2fs_folio_put(last_folio, false);
 				folio_batch_release(&fbatch);
 				ret = -EIO;
@@ -2172,10 +2174,7 @@ int f2fs_sync_node_pages(struct f2fs_sb_info *sbi,
 			if (!folio_clear_dirty_for_io(folio))
 				goto continue_unlock;
 
-			set_fsync_mark(folio, 0);
-			set_dentry_mark(folio, 0);
-
-			if (!__write_node_folio(folio, false, &submitted,
+			if (!__write_node_folio(folio, false, false, &submitted,
 					wbc, do_balance, io_type, NULL)) {
 				folio_batch_release(&fbatch);
 				ret = -EIO;
-- 
2.43.0



_______________________________________________
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] 10+ messages in thread

* [f2fs-dev] [PATCH v4 4/4] f2fs: fix inline data not being written to disk in writeback path
  2026-03-17 11:54 [f2fs-dev] [PATCH v4 1/4] f2fs: refactor f2fs_move_node_folio function Yongpeng Yang
  2026-03-17 11:54 ` [f2fs-dev] [PATCH v4 2/4] f2fs: refactor node footer flag setting related code Yongpeng Yang
  2026-03-17 11:55 ` [f2fs-dev] [PATCH v4 3/4] f2fs: fix fsck inconsistency caused by FGGC of node block Yongpeng Yang
@ 2026-03-17 11:56 ` Yongpeng Yang
  2026-03-18  4:35   ` Chao Yu via Linux-f2fs-devel
  2026-03-18  4:15 ` [f2fs-dev] [PATCH v4 1/4] f2fs: refactor f2fs_move_node_folio function Chao Yu via Linux-f2fs-devel
  3 siblings, 1 reply; 10+ messages in thread
From: Yongpeng Yang @ 2026-03-17 11:56 UTC (permalink / raw)
  To: Chao Yu, Jaegeuk Kim; +Cc: Yongpeng Yang, Yongpeng Yang, linux-f2fs-devel

From: Yongpeng Yang <yangyongpeng@xiaomi.com>

When f2fs_fiemap() is called with `fileinfo->fi_flags` containing the
FIEMAP_FLAG_SYNC flag, it attempts to write data to disk before
retrieving file mappings via filemap_write_and_wait(). However, there is
an issue where the file does not get mapped as expected. The following
scenario can occur:

root@vm:/mnt/f2fs# dd if=/dev/zero of=data.3k bs=3k count=1
root@vm:/mnt/f2fs# xfs_io data.3k -c "fiemap -v 0 4096"
data.3k:
 EXT: FILE-OFFSET      BLOCK-RANGE      TOTAL FLAGS
   0: [0..5]:          0..5                 6 0x307

The root cause of this issue is that f2fs_write_single_data_page() only
calls f2fs_write_inline_data() to copy data from the data folio to the
inode folio, and it clears the dirty flag on the data folio. However, it
does not mark the data folio as writeback. When
__filemap_fdatawait_range() checks for folios with the writeback flag,
it returns early, causing f2fs_fiemap() to report that the file has no
mapping.

To fix this issue, the solution is to call
f2fs_write_single_node_folio() in f2fs_inline_data_fiemap() when
getting fiemap with FIEMAP_FLAG_SYNC flags. This patch ensures that the
inode folio is written back and the writeback process completes before
proceeding.

Fixes: 9ffe0fb5f3bb ("f2fs: handle inline data operations")
Signed-off-by: Yongpeng Yang <yangyongpeng@xiaomi.com>
---
v4:
- Fix the missing return value check for f2fs_get_inode_folio().
v3:
- Call f2fs_write_single_node_folio() instead of f2fs_sync_node_pages()
v2:
- Call f2fs_sync_node_pages() in getting fiemap path rather than
writeback path.
---
 fs/f2fs/inline.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c
index 86d2abbb40ff..62a8a1192a41 100644
--- a/fs/f2fs/inline.c
+++ b/fs/f2fs/inline.c
@@ -814,6 +814,15 @@ int f2fs_inline_data_fiemap(struct inode *inode,
 		goto out;
 	}
 
+	if (fieinfo->fi_flags & FIEMAP_FLAG_SYNC) {
+		err = f2fs_write_single_node_folio(ifolio, true, false, FS_NODE_IO);
+		if (err)
+			return err;
+		ifolio = f2fs_get_inode_folio(F2FS_I_SB(inode), inode->i_ino);
+		if (IS_ERR(ifolio))
+			return PTR_ERR(ifolio);
+		f2fs_folio_wait_writeback(ifolio, NODE, true, true);
+	}
 	ilen = min_t(size_t, MAX_INLINE_DATA(inode), i_size_read(inode));
 	if (start >= ilen)
 		goto out;
-- 
2.43.0



_______________________________________________
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] 10+ messages in thread

* Re: [f2fs-dev] [PATCH v4 1/4] f2fs: refactor f2fs_move_node_folio function
  2026-03-17 11:54 [f2fs-dev] [PATCH v4 1/4] f2fs: refactor f2fs_move_node_folio function Yongpeng Yang
                   ` (2 preceding siblings ...)
  2026-03-17 11:56 ` [f2fs-dev] [PATCH v4 4/4] f2fs: fix inline data not being written to disk in writeback path Yongpeng Yang
@ 2026-03-18  4:15 ` Chao Yu via Linux-f2fs-devel
  2026-03-18  8:03   ` Yongpeng Yang
  3 siblings, 1 reply; 10+ messages in thread
From: Chao Yu via Linux-f2fs-devel @ 2026-03-18  4:15 UTC (permalink / raw)
  To: Yongpeng Yang, Jaegeuk Kim; +Cc: Yongpeng Yang, linux-f2fs-devel

On 2026/3/17 19:54, Yongpeng Yang wrote:
> From: Yongpeng Yang <yangyongpeng@xiaomi.com>
> 
> This patch refactor the f2fs_move_node_folio() function. No logical
> changes.
> 
> Signed-off-by: Yongpeng Yang <yangyongpeng@xiaomi.com>
> ---
>   fs/f2fs/f2fs.h |  2 ++
>   fs/f2fs/node.c | 54 ++++++++++++++++++++++++++++++--------------------
>   2 files changed, 34 insertions(+), 22 deletions(-)
> 
> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> index 660bf88a376f..afb4d10142dd 100644
> --- a/fs/f2fs/f2fs.h
> +++ b/fs/f2fs/f2fs.h
> @@ -3950,6 +3950,8 @@ int f2fs_sanity_check_node_footer(struct f2fs_sb_info *sbi,
>   					enum node_type ntype, bool in_irq);
>   struct folio *f2fs_get_inode_folio(struct f2fs_sb_info *sbi, pgoff_t ino);
>   struct folio *f2fs_get_xnode_folio(struct f2fs_sb_info *sbi, pgoff_t xnid);
> +int f2fs_write_single_node_folio(struct folio *node_folio, int sync_mode,
> +			bool mark_dirty, enum iostat_type io_type);
>   int f2fs_move_node_folio(struct folio *node_folio, int gc_type);
>   void f2fs_flush_inline_data(struct f2fs_sb_info *sbi);
>   int f2fs_fsync_node_pages(struct f2fs_sb_info *sbi, struct inode *inode,
> diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
> index 17eab01ae8f9..2e74d2882b6f 100644
> --- a/fs/f2fs/node.c
> +++ b/fs/f2fs/node.c
> @@ -1845,41 +1845,51 @@ static bool __write_node_folio(struct folio *folio, bool atomic, bool *submitted
>   	return false;
>   }
>   
> -int f2fs_move_node_folio(struct folio *node_folio, int gc_type)
> +int f2fs_write_single_node_folio(struct folio *node_folio, int sync_mode,
> +			bool mark_dirty, enum iostat_type io_type)
>   {
>   	int err = 0;
> +	struct writeback_control wbc = {
> +		.sync_mode = WB_SYNC_ALL,
> +		.nr_to_write = 1,
> +	};
>   
> -	if (gc_type == FG_GC) {
> -		struct writeback_control wbc = {
> -			.sync_mode = WB_SYNC_ALL,
> -			.nr_to_write = 1,
> -		};
> +	if (!sync_mode) {
> +		/* set page dirty and write it */
> +		if (mark_dirty && !folio_test_writeback(node_folio))

If mark_dirty in this check condition is always true, we can removed it?

Thanks,

> +			folio_mark_dirty(node_folio);
> +		goto out_folio;
> +	}
>   
> -		f2fs_folio_wait_writeback(node_folio, NODE, true, true);
> +	f2fs_folio_wait_writeback(node_folio, NODE, true, true);
>   
> +	if (mark_dirty)
>   		folio_mark_dirty(node_folio);
> +	else if (!folio_test_dirty(node_folio))
> +		goto out_folio;
>   
> -		if (!folio_clear_dirty_for_io(node_folio)) {
> -			err = -EAGAIN;
> -			goto out_page;
> -		}
> -
> -		if (!__write_node_folio(node_folio, false, NULL,
> -					&wbc, false, FS_GC_NODE_IO, NULL))
> -			err = -EAGAIN;
> -		goto release_page;
> -	} else {
> -		/* set page dirty and write it */
> -		if (!folio_test_writeback(node_folio))
> -			folio_mark_dirty(node_folio);
> +	if (!folio_clear_dirty_for_io(node_folio)) {
> +		err = -EAGAIN;
> +		goto out_folio;
>   	}
> -out_page:
> +
> +	if (!__write_node_folio(node_folio, false, NULL,
> +				&wbc, false, FS_GC_NODE_IO, NULL))
> +		err = -EAGAIN;
> +	goto release_folio;
> +out_folio:
>   	folio_unlock(node_folio);
> -release_page:
> +release_folio:
>   	f2fs_folio_put(node_folio, false);
>   	return err;
>   }
>   
> +int f2fs_move_node_folio(struct folio *node_folio, int gc_type)
> +{
> +	return f2fs_write_single_node_folio(node_folio, gc_type == FG_GC,
> +			true, FS_GC_NODE_IO);
> +}
> +
>   int f2fs_fsync_node_pages(struct f2fs_sb_info *sbi, struct inode *inode,
>   			struct writeback_control *wbc, bool atomic,
>   			unsigned int *seq_id)



_______________________________________________
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] 10+ messages in thread

* Re: [f2fs-dev] [PATCH v4 2/4] f2fs: refactor node footer flag setting related code
  2026-03-17 11:54 ` [f2fs-dev] [PATCH v4 2/4] f2fs: refactor node footer flag setting related code Yongpeng Yang
@ 2026-03-18  4:17   ` Chao Yu via Linux-f2fs-devel
  0 siblings, 0 replies; 10+ messages in thread
From: Chao Yu via Linux-f2fs-devel @ 2026-03-18  4:17 UTC (permalink / raw)
  To: Yongpeng Yang, Jaegeuk Kim; +Cc: Yongpeng Yang, linux-f2fs-devel

On 2026/3/17 19:54, Yongpeng Yang wrote:
> From: Yongpeng Yang <yangyongpeng@xiaomi.com>
> 
> This patch refactors the node footer flag setting code to simplify
> redundant logic and adjust function parameters and return types. No
> logical changes.
> 
> Signed-off-by: Yongpeng Yang <yangyongpeng@xiaomi.com>

Reviewed-by: Chao Yu <chao@kernel.org>

Thanks,


_______________________________________________
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] 10+ messages in thread

* Re: [f2fs-dev] [PATCH v4 3/4] f2fs: fix fsck inconsistency caused by FGGC of node block
  2026-03-17 11:55 ` [f2fs-dev] [PATCH v4 3/4] f2fs: fix fsck inconsistency caused by FGGC of node block Yongpeng Yang
@ 2026-03-18  4:26   ` Chao Yu via Linux-f2fs-devel
  0 siblings, 0 replies; 10+ messages in thread
From: Chao Yu via Linux-f2fs-devel @ 2026-03-18  4:26 UTC (permalink / raw)
  To: Yongpeng Yang, Jaegeuk Kim; +Cc: Yongpeng Yang, linux-f2fs-devel

On 2026/3/17 19:55, Yongpeng Yang wrote:
> From: Yongpeng Yang <yangyongpeng@xiaomi.com>
> 
> During FGGC node block migration, fsck may incorrectly treat the
> migrated node block as fsync-written data.
> 
> The reproduction scenario:
> root@vm:/mnt/f2fs# seq 1 2048 | xargs -n 1 ./test_sync // write inline inode and sync
> root@vm:/mnt/f2fs# rm -f 1
> root@vm:/mnt/f2fs# sync
> root@vm:/mnt/f2fs# f2fs_io gc_range // move data block in sync mode and not write CP
>    SPO, "fsck --dry-run" find inode has already checkpointed but still
>    with DENT_BIT_SHIFT set
> 
> The root cause is that GC does not clear the dentry mark and fsync mark
> during node block migration, leading fsck to misinterpret them as
> user-issued fsync writes.
> 
> In BGGC mode, node block migration is handled by f2fs_sync_node_pages(),
> which guarantees the dentry and fsync marks are cleared before writing.
> 
> This patch move the set/clear of the fsync|dentry marks into
> __write_node_folio to make the logic clearer, and ensures the
> fsync|dentry mark is cleared in FGGC.
> 

Cc: stable@kernel.org

> Fixes: da011cc0da8c ("f2fs: move node pages only in victim section during GC")
> Signed-off-by: Yongpeng Yang <yangyongpeng@xiaomi.com>

Reviewed-by: Chao Yu <chao@kernel.org>

Thanks,



_______________________________________________
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] 10+ messages in thread

* Re: [f2fs-dev] [PATCH v4 4/4] f2fs: fix inline data not being written to disk in writeback path
  2026-03-17 11:56 ` [f2fs-dev] [PATCH v4 4/4] f2fs: fix inline data not being written to disk in writeback path Yongpeng Yang
@ 2026-03-18  4:35   ` Chao Yu via Linux-f2fs-devel
  2026-03-18  8:05     ` Yongpeng Yang
  0 siblings, 1 reply; 10+ messages in thread
From: Chao Yu via Linux-f2fs-devel @ 2026-03-18  4:35 UTC (permalink / raw)
  To: Yongpeng Yang, Jaegeuk Kim; +Cc: Yongpeng Yang, linux-f2fs-devel

On 2026/3/17 19:56, Yongpeng Yang wrote:
> From: Yongpeng Yang <yangyongpeng@xiaomi.com>
> 
> When f2fs_fiemap() is called with `fileinfo->fi_flags` containing the
> FIEMAP_FLAG_SYNC flag, it attempts to write data to disk before
> retrieving file mappings via filemap_write_and_wait(). However, there is
> an issue where the file does not get mapped as expected. The following
> scenario can occur:
> 
> root@vm:/mnt/f2fs# dd if=/dev/zero of=data.3k bs=3k count=1
> root@vm:/mnt/f2fs# xfs_io data.3k -c "fiemap -v 0 4096"
> data.3k:
>   EXT: FILE-OFFSET      BLOCK-RANGE      TOTAL FLAGS
>     0: [0..5]:          0..5                 6 0x307
> 
> The root cause of this issue is that f2fs_write_single_data_page() only
> calls f2fs_write_inline_data() to copy data from the data folio to the
> inode folio, and it clears the dirty flag on the data folio. However, it
> does not mark the data folio as writeback. When
> __filemap_fdatawait_range() checks for folios with the writeback flag,
> it returns early, causing f2fs_fiemap() to report that the file has no
> mapping.
> 
> To fix this issue, the solution is to call
> f2fs_write_single_node_folio() in f2fs_inline_data_fiemap() when
> getting fiemap with FIEMAP_FLAG_SYNC flags. This patch ensures that the
> inode folio is written back and the writeback process completes before
> proceeding.
> 
> Fixes: 9ffe0fb5f3bb ("f2fs: handle inline data operations")
> Signed-off-by: Yongpeng Yang <yangyongpeng@xiaomi.com>
> ---
> v4:
> - Fix the missing return value check for f2fs_get_inode_folio().
> v3:
> - Call f2fs_write_single_node_folio() instead of f2fs_sync_node_pages()
> v2:
> - Call f2fs_sync_node_pages() in getting fiemap path rather than
> writeback path.
> ---
>   fs/f2fs/inline.c | 9 +++++++++
>   1 file changed, 9 insertions(+)
> 

Declaration should be relocated into this patch.

+int f2fs_write_single_node_folio(struct folio *node_folio, int sync_mode,
+			bool mark_dirty, enum iostat_type io_type);

Thanks,

> diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c
> index 86d2abbb40ff..62a8a1192a41 100644
> --- a/fs/f2fs/inline.c
> +++ b/fs/f2fs/inline.c
> @@ -814,6 +814,15 @@ int f2fs_inline_data_fiemap(struct inode *inode,
>   		goto out;
>   	}
>   
> +	if (fieinfo->fi_flags & FIEMAP_FLAG_SYNC) {
> +		err = f2fs_write_single_node_folio(ifolio, true, false, FS_NODE_IO);
> +		if (err)
> +			return err;
> +		ifolio = f2fs_get_inode_folio(F2FS_I_SB(inode), inode->i_ino);
> +		if (IS_ERR(ifolio))
> +			return PTR_ERR(ifolio);
> +		f2fs_folio_wait_writeback(ifolio, NODE, true, true);
> +	}
>   	ilen = min_t(size_t, MAX_INLINE_DATA(inode), i_size_read(inode));
>   	if (start >= ilen)
>   		goto out;



_______________________________________________
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] 10+ messages in thread

* Re: [f2fs-dev] [PATCH v4 1/4] f2fs: refactor f2fs_move_node_folio function
  2026-03-18  4:15 ` [f2fs-dev] [PATCH v4 1/4] f2fs: refactor f2fs_move_node_folio function Chao Yu via Linux-f2fs-devel
@ 2026-03-18  8:03   ` Yongpeng Yang
  0 siblings, 0 replies; 10+ messages in thread
From: Yongpeng Yang @ 2026-03-18  8:03 UTC (permalink / raw)
  To: Chao Yu, Yongpeng Yang, Jaegeuk Kim; +Cc: Yongpeng Yang, linux-f2fs-devel

On 3/18/2026 12:15 PM, Chao Yu via Linux-f2fs-devel wrote:
> On 2026/3/17 19:54, Yongpeng Yang wrote:
>> From: Yongpeng Yang <yangyongpeng@xiaomi.com>
>>
>> This patch refactor the f2fs_move_node_folio() function. No logical
>> changes.
>>
>> Signed-off-by: Yongpeng Yang <yangyongpeng@xiaomi.com>
>> ---
>>   fs/f2fs/f2fs.h |  2 ++
>>   fs/f2fs/node.c | 54 ++++++++++++++++++++++++++++++--------------------
>>   2 files changed, 34 insertions(+), 22 deletions(-)
>>
>> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
>> index 660bf88a376f..afb4d10142dd 100644
>> --- a/fs/f2fs/f2fs.h
>> +++ b/fs/f2fs/f2fs.h
>> @@ -3950,6 +3950,8 @@ int f2fs_sanity_check_node_footer(struct 
>> f2fs_sb_info *sbi,
>>                       enum node_type ntype, bool in_irq);
>>   struct folio *f2fs_get_inode_folio(struct f2fs_sb_info *sbi, pgoff_t 
>> ino);
>>   struct folio *f2fs_get_xnode_folio(struct f2fs_sb_info *sbi, pgoff_t 
>> xnid);
>> +int f2fs_write_single_node_folio(struct folio *node_folio, int 
>> sync_mode,
>> +            bool mark_dirty, enum iostat_type io_type);
>>   int f2fs_move_node_folio(struct folio *node_folio, int gc_type);
>>   void f2fs_flush_inline_data(struct f2fs_sb_info *sbi);
>>   int f2fs_fsync_node_pages(struct f2fs_sb_info *sbi, struct inode 
>> *inode,
>> diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
>> index 17eab01ae8f9..2e74d2882b6f 100644
>> --- a/fs/f2fs/node.c
>> +++ b/fs/f2fs/node.c
>> @@ -1845,41 +1845,51 @@ static bool __write_node_folio(struct folio 
>> *folio, bool atomic, bool *submitted
>>       return false;
>>   }
>> -int f2fs_move_node_folio(struct folio *node_folio, int gc_type)
>> +int f2fs_write_single_node_folio(struct folio *node_folio, int 
>> sync_mode,
>> +            bool mark_dirty, enum iostat_type io_type)
>>   {
>>       int err = 0;
>> +    struct writeback_control wbc = {
>> +        .sync_mode = WB_SYNC_ALL,
>> +        .nr_to_write = 1,
>> +    };
>> -    if (gc_type == FG_GC) {
>> -        struct writeback_control wbc = {
>> -            .sync_mode = WB_SYNC_ALL,
>> -            .nr_to_write = 1,
>> -        };
>> +    if (!sync_mode) {
>> +        /* set page dirty and write it */
>> +        if (mark_dirty && !folio_test_writeback(node_folio))
> 
> If mark_dirty in this check condition is always true, we can removed it?

OK, I'll remove it in v5 patch.

Thanks
Yongpeng,

> 
> Thanks,
> 
>> +            folio_mark_dirty(node_folio);
>> +        goto out_folio;
>> +    }
>> -        f2fs_folio_wait_writeback(node_folio, NODE, true, true);
>> +    f2fs_folio_wait_writeback(node_folio, NODE, true, true);
>> +    if (mark_dirty)
>>           folio_mark_dirty(node_folio);
>> +    else if (!folio_test_dirty(node_folio))
>> +        goto out_folio;
>> -        if (!folio_clear_dirty_for_io(node_folio)) {
>> -            err = -EAGAIN;
>> -            goto out_page;
>> -        }
>> -
>> -        if (!__write_node_folio(node_folio, false, NULL,
>> -                    &wbc, false, FS_GC_NODE_IO, NULL))
>> -            err = -EAGAIN;
>> -        goto release_page;
>> -    } else {
>> -        /* set page dirty and write it */
>> -        if (!folio_test_writeback(node_folio))
>> -            folio_mark_dirty(node_folio);
>> +    if (!folio_clear_dirty_for_io(node_folio)) {
>> +        err = -EAGAIN;
>> +        goto out_folio;
>>       }
>> -out_page:
>> +
>> +    if (!__write_node_folio(node_folio, false, NULL,
>> +                &wbc, false, FS_GC_NODE_IO, NULL))
>> +        err = -EAGAIN;
>> +    goto release_folio;
>> +out_folio:
>>       folio_unlock(node_folio);
>> -release_page:
>> +release_folio:
>>       f2fs_folio_put(node_folio, false);
>>       return err;
>>   }
>> +int f2fs_move_node_folio(struct folio *node_folio, int gc_type)
>> +{
>> +    return f2fs_write_single_node_folio(node_folio, gc_type == FG_GC,
>> +            true, FS_GC_NODE_IO);
>> +}
>> +
>>   int f2fs_fsync_node_pages(struct f2fs_sb_info *sbi, struct inode 
>> *inode,
>>               struct writeback_control *wbc, bool atomic,
>>               unsigned int *seq_id)
> 
> 
> 
> _______________________________________________
> Linux-f2fs-devel mailing list
> Linux-f2fs-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel



_______________________________________________
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] 10+ messages in thread

* Re: [f2fs-dev] [PATCH v4 4/4] f2fs: fix inline data not being written to disk in writeback path
  2026-03-18  4:35   ` Chao Yu via Linux-f2fs-devel
@ 2026-03-18  8:05     ` Yongpeng Yang
  0 siblings, 0 replies; 10+ messages in thread
From: Yongpeng Yang @ 2026-03-18  8:05 UTC (permalink / raw)
  To: Chao Yu, Yongpeng Yang, Jaegeuk Kim; +Cc: Yongpeng Yang, linux-f2fs-devel

On 3/18/2026 12:35 PM, Chao Yu via Linux-f2fs-devel wrote:
> On 2026/3/17 19:56, Yongpeng Yang wrote:
>> From: Yongpeng Yang <yangyongpeng@xiaomi.com>
>>
>> When f2fs_fiemap() is called with `fileinfo->fi_flags` containing the
>> FIEMAP_FLAG_SYNC flag, it attempts to write data to disk before
>> retrieving file mappings via filemap_write_and_wait(). However, there is
>> an issue where the file does not get mapped as expected. The following
>> scenario can occur:
>>
>> root@vm:/mnt/f2fs# dd if=/dev/zero of=data.3k bs=3k count=1
>> root@vm:/mnt/f2fs# xfs_io data.3k -c "fiemap -v 0 4096"
>> data.3k:
>>   EXT: FILE-OFFSET      BLOCK-RANGE      TOTAL FLAGS
>>     0: [0..5]:          0..5                 6 0x307
>>
>> The root cause of this issue is that f2fs_write_single_data_page() only
>> calls f2fs_write_inline_data() to copy data from the data folio to the
>> inode folio, and it clears the dirty flag on the data folio. However, it
>> does not mark the data folio as writeback. When
>> __filemap_fdatawait_range() checks for folios with the writeback flag,
>> it returns early, causing f2fs_fiemap() to report that the file has no
>> mapping.
>>
>> To fix this issue, the solution is to call
>> f2fs_write_single_node_folio() in f2fs_inline_data_fiemap() when
>> getting fiemap with FIEMAP_FLAG_SYNC flags. This patch ensures that the
>> inode folio is written back and the writeback process completes before
>> proceeding.
>>
>> Fixes: 9ffe0fb5f3bb ("f2fs: handle inline data operations")
>> Signed-off-by: Yongpeng Yang <yangyongpeng@xiaomi.com>
>> ---
>> v4:
>> - Fix the missing return value check for f2fs_get_inode_folio().
>> v3:
>> - Call f2fs_write_single_node_folio() instead of f2fs_sync_node_pages()
>> v2:
>> - Call f2fs_sync_node_pages() in getting fiemap path rather than
>> writeback path.
>> ---
>>   fs/f2fs/inline.c | 9 +++++++++
>>   1 file changed, 9 insertions(+)
>>
> 
> Declaration should be relocated into this patch.
> 
> +int f2fs_write_single_node_folio(struct folio *node_folio, int sync_mode,
> +            bool mark_dirty, enum iostat_type io_type);
> 

OK, I'll relocate it in v5 patch.

Thanks
Yongpeng,

> Thanks,
> 
>> diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c
>> index 86d2abbb40ff..62a8a1192a41 100644
>> --- a/fs/f2fs/inline.c
>> +++ b/fs/f2fs/inline.c
>> @@ -814,6 +814,15 @@ int f2fs_inline_data_fiemap(struct inode *inode,
>>           goto out;
>>       }
>> +    if (fieinfo->fi_flags & FIEMAP_FLAG_SYNC) {
>> +        err = f2fs_write_single_node_folio(ifolio, true, false, 
>> FS_NODE_IO);
>> +        if (err)
>> +            return err;
>> +        ifolio = f2fs_get_inode_folio(F2FS_I_SB(inode), inode->i_ino);
>> +        if (IS_ERR(ifolio))
>> +            return PTR_ERR(ifolio);
>> +        f2fs_folio_wait_writeback(ifolio, NODE, true, true);
>> +    }
>>       ilen = min_t(size_t, MAX_INLINE_DATA(inode), i_size_read(inode));
>>       if (start >= ilen)
>>           goto out;
> 
> 
> 
> _______________________________________________
> Linux-f2fs-devel mailing list
> Linux-f2fs-devel@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel



_______________________________________________
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] 10+ messages in thread

end of thread, other threads:[~2026-03-18  8:18 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-17 11:54 [f2fs-dev] [PATCH v4 1/4] f2fs: refactor f2fs_move_node_folio function Yongpeng Yang
2026-03-17 11:54 ` [f2fs-dev] [PATCH v4 2/4] f2fs: refactor node footer flag setting related code Yongpeng Yang
2026-03-18  4:17   ` Chao Yu via Linux-f2fs-devel
2026-03-17 11:55 ` [f2fs-dev] [PATCH v4 3/4] f2fs: fix fsck inconsistency caused by FGGC of node block Yongpeng Yang
2026-03-18  4:26   ` Chao Yu via Linux-f2fs-devel
2026-03-17 11:56 ` [f2fs-dev] [PATCH v4 4/4] f2fs: fix inline data not being written to disk in writeback path Yongpeng Yang
2026-03-18  4:35   ` Chao Yu via Linux-f2fs-devel
2026-03-18  8:05     ` Yongpeng Yang
2026-03-18  4:15 ` [f2fs-dev] [PATCH v4 1/4] f2fs: refactor f2fs_move_node_folio function Chao Yu via Linux-f2fs-devel
2026-03-18  8:03   ` Yongpeng Yang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox