All of lore.kernel.org
 help / color / mirror / Atom feed
* [f2fs-dev] [PATCH 1/4] f2fs: fix incorrect extent flag when physical addr is NEW_ADDR in f2fs_fiemap
@ 2026-02-03 13:36 Yongpeng Yang
  2026-02-03 13:36 ` [f2fs-dev] [PATCH 2/4] f2fs: fix incorrect file address mapping when inline inode is unwritten Yongpeng Yang
                   ` (4 more replies)
  0 siblings, 5 replies; 17+ messages in thread
From: Yongpeng Yang @ 2026-02-03 13:36 UTC (permalink / raw)
  To: Chao Yu, Jaegeuk Kim; +Cc: Yongpeng Yang, Yongpeng Yang, linux-f2fs-devel

From: Yongpeng Yang <yangyongpeng@xiaomi.com>

When the file block's address is mapped to NEW_ADDR, the extent is
currently marked with the FIEMAP_EXTENT_UNWRITTEN flag in f2fs_fiemap().
This flag indicates that the block has been allocated but not yet
written to. However, NEW_ADDR indicates delayed writing, meaning the
block has not been allocated yet. Therefore, this should be modified
such that when a file block's address is mapped to NEW_ADDR, the extent
is marked with the FIEMAP_EXTENT_DELALLOC flags instead.

Signed-off-by: Yongpeng Yang <yangyongpeng@xiaomi.com>
---
 fs/f2fs/data.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 84746a06cd58..42f15fd9c68e 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -2102,7 +2102,7 @@ int f2fs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
 				size += F2FS_BLKSIZE;
 			}
 		} else if (map.m_flags & F2FS_MAP_DELALLOC) {
-			flags = FIEMAP_EXTENT_UNWRITTEN;
+			flags = FIEMAP_EXTENT_DELALLOC;
 		}
 
 		start_blk += F2FS_BYTES_TO_BLK(size);
-- 
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] 17+ messages in thread

* [f2fs-dev] [PATCH 2/4] f2fs: fix incorrect file address mapping when inline inode is unwritten
  2026-02-03 13:36 [f2fs-dev] [PATCH 1/4] f2fs: fix incorrect extent flag when physical addr is NEW_ADDR in f2fs_fiemap Yongpeng Yang
@ 2026-02-03 13:36 ` Yongpeng Yang
  2026-03-04  9:14   ` Chao Yu via Linux-f2fs-devel
  2026-02-03 13:36 ` [f2fs-dev] [PATCH 3/4] f2fs: fix fiemap boundary handling when read extent cache is incomplete Yongpeng Yang
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 17+ messages in thread
From: Yongpeng Yang @ 2026-02-03 13:36 UTC (permalink / raw)
  To: Chao Yu, Jaegeuk Kim; +Cc: Yongpeng Yang, Yongpeng Yang, linux-f2fs-devel

From: Yongpeng Yang <yangyongpeng@xiaomi.com>

When `fileinfo->fi_flags` does not have the `FIEMAP_FLAG_SYNC` bit set
and inline data has not been persisted yet, the physical address of the
extent is calculated incorrectly for unwritten inline inodes.

root@vm:/mnt/f2fs# dd if=/dev/zero of=data.3k bs=3k count=1
root@vm:/mnt/f2fs# f2fs_io fiemap 0 100 data.3k
Fiemap: offset = 0 len = 100
	logical addr.    physical addr.   length           flags
0	0000000000000000 00000ffffffff16c 0000000000000c00 00000301

This patch fixes the issue by checking if the inode's address is valid.
If the inline inode is unwritten, set the physical address to 0 and
mark the extent with `FIEMAP_EXTENT_UNKNOWN | FIEMAP_EXTENT_DELALLOC`
flags.

Fixes: 67f8cf3cee6f ("f2fs: support fiemap for inline_data")
Signed-off-by: Yongpeng Yang <yangyongpeng@xiaomi.com>
---
 fs/f2fs/inline.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/fs/f2fs/inline.c b/fs/f2fs/inline.c
index 0a1052d5ee62..86d2abbb40ff 100644
--- a/fs/f2fs/inline.c
+++ b/fs/f2fs/inline.c
@@ -792,7 +792,7 @@ int f2fs_read_inline_dir(struct file *file, struct dir_context *ctx,
 int f2fs_inline_data_fiemap(struct inode *inode,
 		struct fiemap_extent_info *fieinfo, __u64 start, __u64 len)
 {
-	__u64 byteaddr, ilen;
+	__u64 byteaddr = 0, ilen;
 	__u32 flags = FIEMAP_EXTENT_DATA_INLINE | FIEMAP_EXTENT_NOT_ALIGNED |
 		FIEMAP_EXTENT_LAST;
 	struct node_info ni;
@@ -825,9 +825,14 @@ int f2fs_inline_data_fiemap(struct inode *inode,
 	if (err)
 		goto out;
 
-	byteaddr = (__u64)ni.blk_addr << inode->i_sb->s_blocksize_bits;
-	byteaddr += (char *)inline_data_addr(inode, ifolio) -
-					(char *)F2FS_INODE(ifolio);
+	if (__is_valid_data_blkaddr(ni.blk_addr)) {
+		byteaddr = (__u64)ni.blk_addr << inode->i_sb->s_blocksize_bits;
+		byteaddr += (char *)inline_data_addr(inode, ifolio) -
+						(char *)F2FS_INODE(ifolio);
+	} else {
+		f2fs_bug_on(F2FS_I_SB(inode), ni.blk_addr != NEW_ADDR);
+		flags |= FIEMAP_EXTENT_DELALLOC | FIEMAP_EXTENT_UNKNOWN;
+	}
 	err = fiemap_fill_next_extent(fieinfo, start, byteaddr, ilen, flags);
 	trace_f2fs_fiemap(inode, start, byteaddr, ilen, flags, err);
 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] 17+ messages in thread

* [f2fs-dev] [PATCH 3/4] f2fs: fix fiemap boundary handling when read extent cache is incomplete
  2026-02-03 13:36 [f2fs-dev] [PATCH 1/4] f2fs: fix incorrect extent flag when physical addr is NEW_ADDR in f2fs_fiemap Yongpeng Yang
  2026-02-03 13:36 ` [f2fs-dev] [PATCH 2/4] f2fs: fix incorrect file address mapping when inline inode is unwritten Yongpeng Yang
@ 2026-02-03 13:36 ` Yongpeng Yang
  2026-02-24  3:48   ` Jaegeuk Kim via Linux-f2fs-devel
  2026-02-24  4:38   ` Jaegeuk Kim via Linux-f2fs-devel
  2026-02-03 13:37 ` [f2fs-dev] [PATCH 4/4] f2fs: fix inline data not being written to disk in writeback path Yongpeng Yang
                   ` (2 subsequent siblings)
  4 siblings, 2 replies; 17+ messages in thread
From: Yongpeng Yang @ 2026-02-03 13:36 UTC (permalink / raw)
  To: Chao Yu, Jaegeuk Kim; +Cc: Yongpeng Yang, Yongpeng Yang, linux-f2fs-devel

From: Yongpeng Yang <yangyongpeng@xiaomi.com>

f2fs_fiemap() calls f2fs_map_blocks() to obtain the block mapping a
file, and then merges contiguous mappings into extents. If the mapping
is found in the read extent cache, node blocks do not need to be read.
However, in the following scenario, a contiguous extent can be split
into two extents:

root@vm:/mnt/f2fs# dd if=/dev/zero of=data.4M bs=1M count=4 && sync
root@vm:/mnt/f2fs# dd if=/dev/zero of=data.4M bs=1M count=2 seek=2 conv=notrunc && sync
root@vm:/mnt/f2fs# echo 3 > /proc/sys/vm/drop_caches # drop 2M~4M extent cache
root@vm:/mnt/f2fs# dd if=/dev/zero of=data.4M bs=1M count=2 seek=0 conv=notrunc && sync
root@vm:/mnt/f2fs# f2fs_io fiemap 0 1024 data.4M
Fiemap: offset = 0 len = 1024
logical addr.    physical addr.   length           flags
0	0000000000000000 0000000006400000 0000000000200000 00001000
1	0000000000200000 0000000006600000 0000000000200000 00001001

Although the physical addresses of the ranges 0~2MB and 2M~4MB are
contiguous, the mapping for the 2M~4MB range is not present in memory.
When the physical addresses for the 0~2MB range are updated, no merge
happens because the adjacent mapping is missing from the in-memory
cache. As a result, fiemap reports two separate extents instead of a
single contiguous one.

The root cause is that the read extent cache does not guarantee that all
blocks of an extent are present in memory. Therefore, when the extent
length returned by f2fs_map_blocks_cached() is smaller than maxblocks,
the remaining mappings are retrieved via f2fs_get_dnode_of_data() to
ensure correct fiemap extent boundary handling.

Fixes: cd8fc5226bef ("f2fs: remove the create argument to f2fs_map_blocks")
Signed-off-by: Yongpeng Yang <yangyongpeng@xiaomi.com>
---
 fs/f2fs/data.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 42f15fd9c68e..eedadccf86bb 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -1623,8 +1623,18 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map, int flag)
 	lfs_dio_write = (flag == F2FS_GET_BLOCK_DIO && f2fs_lfs_mode(sbi) &&
 				map->m_may_create);
 
-	if (!map->m_may_create && f2fs_map_blocks_cached(inode, map, flag))
-		goto out;
+	if (!map->m_may_create) {
+		if (f2fs_map_blocks_cached(inode, map, flag)) {
+			if (map->m_len == maxblocks)
+				goto out;
+			else {
+				pgofs =	(pgoff_t)map->m_lblk + map->m_len;
+				end = map->m_lblk + maxblocks;
+				ofs = map->m_len;
+				goto next_dnode;
+			}
+		}
+	}
 
 	map->m_bdev = inode->i_sb->s_bdev;
 	map->m_multidev_dio =
-- 
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] 17+ messages in thread

* [f2fs-dev] [PATCH 4/4] f2fs: fix inline data not being written to disk in writeback path
  2026-02-03 13:36 [f2fs-dev] [PATCH 1/4] f2fs: fix incorrect extent flag when physical addr is NEW_ADDR in f2fs_fiemap Yongpeng Yang
  2026-02-03 13:36 ` [f2fs-dev] [PATCH 2/4] f2fs: fix incorrect file address mapping when inline inode is unwritten Yongpeng Yang
  2026-02-03 13:36 ` [f2fs-dev] [PATCH 3/4] f2fs: fix fiemap boundary handling when read extent cache is incomplete Yongpeng Yang
@ 2026-02-03 13:37 ` Yongpeng Yang
  2026-03-04  9:30   ` Chao Yu via Linux-f2fs-devel
  2026-03-04  9:13 ` [f2fs-dev] [PATCH 1/4] f2fs: fix incorrect extent flag when physical addr is NEW_ADDR in f2fs_fiemap Chao Yu via Linux-f2fs-devel
  2026-03-05 19:10 ` patchwork-bot+f2fs--- via Linux-f2fs-devel
  4 siblings, 1 reply; 17+ messages in thread
From: Yongpeng Yang @ 2026-02-03 13:37 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_sync_node_pages() after
f2fs_write_inline_data() successfully returns, which will write back the
inode folio and wait for the writeback to complete.

Fixes: 9ffe0fb5f3bb ("f2fs: handle inline data operations")
Signed-off-by: Yongpeng Yang <yangyongpeng@xiaomi.com>
---
 fs/f2fs/checkpoint.c |  1 +
 fs/f2fs/data.c       | 19 ++++++++++++++++++-
 fs/f2fs/node.c       | 21 ++++++++++++++++-----
 3 files changed, 35 insertions(+), 6 deletions(-)

diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
index 5172396c0b01..d0bca57854da 100644
--- a/fs/f2fs/checkpoint.c
+++ b/fs/f2fs/checkpoint.c
@@ -1347,6 +1347,7 @@ static int block_operations(struct f2fs_sb_info *sbi)
 	struct writeback_control wbc = {
 		.sync_mode = WB_SYNC_ALL,
 		.nr_to_write = LONG_MAX,
+		.range_cyclic = 1,
 	};
 	int err = 0, cnt = 0;
 
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index eedadccf86bb..ccc5e4ddf547 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -3126,8 +3126,25 @@ int f2fs_write_single_data_page(struct folio *folio, int *submitted,
 	err = -EAGAIN;
 	if (f2fs_has_inline_data(inode)) {
 		err = f2fs_write_inline_data(inode, folio);
-		if (!err)
+		if (!err) {
+			struct folio *ifolio;
+			struct writeback_control iwbc = {
+				.sync_mode = WB_SYNC_ALL,
+				.range_start = inode->i_ino << PAGE_SHIFT,
+				.range_end = inode->i_ino << PAGE_SHIFT,
+				.nr_to_write = 1,
+				.range_cyclic = 0,
+			};
+
+			if (!f2fs_sync_node_pages(sbi, &iwbc, true, FS_NODE_IO)) {
+				ifolio = f2fs_get_inode_folio(sbi, inode->i_ino);
+				if (!IS_ERR(ifolio)) {
+					f2fs_folio_wait_writeback(ifolio, NODE, true, true);
+					f2fs_folio_put(ifolio, true);
+				}
+			}
 			goto out;
+		}
 	}
 
 	if (err == -EAGAIN) {
diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
index 74992fd9c9b6..47bff89bafe6 100644
--- a/fs/f2fs/node.c
+++ b/fs/f2fs/node.c
@@ -2083,7 +2083,8 @@ int f2fs_sync_node_pages(struct f2fs_sb_info *sbi,
 				struct writeback_control *wbc,
 				bool do_balance, enum iostat_type io_type)
 {
-	pgoff_t index;
+	pgoff_t index, wbc_index;
+	pgoff_t end, wbc_end;
 	struct folio_batch fbatch;
 	int step = 0;
 	int nwritten = 0;
@@ -2092,14 +2093,24 @@ int f2fs_sync_node_pages(struct f2fs_sb_info *sbi,
 
 	folio_batch_init(&fbatch);
 
+	wbc_index = 0;
+	wbc_end = LONG_MAX;
+	if (!wbc->range_cyclic) {
+		wbc_index = wbc->range_start >> PAGE_SHIFT;
+		wbc_end = wbc->range_end >> PAGE_SHIFT;
+	}
 next_step:
-	index = 0;
+	index = wbc_index;
+	end = wbc_end;
 
-	while (!done && (nr_folios = filemap_get_folios_tag(NODE_MAPPING(sbi),
-				&index, (pgoff_t)-1, PAGECACHE_TAG_DIRTY,
-				&fbatch))) {
+	while (!done && (index <= end)) {
 		int i;
 
+		nr_folios = filemap_get_folios_tag(NODE_MAPPING(sbi),
+				&index, end, PAGECACHE_TAG_DIRTY,
+				&fbatch);
+		if (nr_folios == 0)
+			break;
 		for (i = 0; i < nr_folios; i++) {
 			struct folio *folio = fbatch.folios[i];
 			bool submitted = false;
-- 
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] 17+ messages in thread

* Re: [f2fs-dev] [PATCH 3/4] f2fs: fix fiemap boundary handling when read extent cache is incomplete
  2026-02-03 13:36 ` [f2fs-dev] [PATCH 3/4] f2fs: fix fiemap boundary handling when read extent cache is incomplete Yongpeng Yang
@ 2026-02-24  3:48   ` Jaegeuk Kim via Linux-f2fs-devel
  2026-02-24  4:38   ` Jaegeuk Kim via Linux-f2fs-devel
  1 sibling, 0 replies; 17+ messages in thread
From: Jaegeuk Kim via Linux-f2fs-devel @ 2026-02-24  3:48 UTC (permalink / raw)
  To: Yongpeng Yang; +Cc: Yongpeng Yang, linux-f2fs-devel

On 02/03, Yongpeng Yang wrote:
> From: Yongpeng Yang <yangyongpeng@xiaomi.com>
> 
> f2fs_fiemap() calls f2fs_map_blocks() to obtain the block mapping a
> file, and then merges contiguous mappings into extents. If the mapping
> is found in the read extent cache, node blocks do not need to be read.
> However, in the following scenario, a contiguous extent can be split
> into two extents:
> 
> root@vm:/mnt/f2fs# dd if=/dev/zero of=data.4M bs=1M count=4 && sync
> root@vm:/mnt/f2fs# dd if=/dev/zero of=data.4M bs=1M count=2 seek=2 conv=notrunc && sync
> root@vm:/mnt/f2fs# echo 3 > /proc/sys/vm/drop_caches # drop 2M~4M extent cache
> root@vm:/mnt/f2fs# dd if=/dev/zero of=data.4M bs=1M count=2 seek=0 conv=notrunc && sync
> root@vm:/mnt/f2fs# f2fs_io fiemap 0 1024 data.4M
> Fiemap: offset = 0 len = 1024
> logical addr.    physical addr.   length           flags
> 0	0000000000000000 0000000006400000 0000000000200000 00001000
> 1	0000000000200000 0000000006600000 0000000000200000 00001001
> 
> Although the physical addresses of the ranges 0~2MB and 2M~4MB are
> contiguous, the mapping for the 2M~4MB range is not present in memory.
> When the physical addresses for the 0~2MB range are updated, no merge
> happens because the adjacent mapping is missing from the in-memory
> cache. As a result, fiemap reports two separate extents instead of a
> single contiguous one.
> 
> The root cause is that the read extent cache does not guarantee that all
> blocks of an extent are present in memory. Therefore, when the extent
> length returned by f2fs_map_blocks_cached() is smaller than maxblocks,
> the remaining mappings are retrieved via f2fs_get_dnode_of_data() to
> ensure correct fiemap extent boundary handling.
> 
> Fixes: cd8fc5226bef ("f2fs: remove the create argument to f2fs_map_blocks")
> Signed-off-by: Yongpeng Yang <yangyongpeng@xiaomi.com>
> ---
>  fs/f2fs/data.c | 14 ++++++++++++--
>  1 file changed, 12 insertions(+), 2 deletions(-)
> 
> diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
> index 42f15fd9c68e..eedadccf86bb 100644
> --- a/fs/f2fs/data.c
> +++ b/fs/f2fs/data.c
> @@ -1623,8 +1623,18 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map, int flag)
>  	lfs_dio_write = (flag == F2FS_GET_BLOCK_DIO && f2fs_lfs_mode(sbi) &&
>  				map->m_may_create);
>  
> -	if (!map->m_may_create && f2fs_map_blocks_cached(inode, map, flag))
> -		goto out;
> +	if (!map->m_may_create) {
> +		if (f2fs_map_blocks_cached(inode, map, flag)) {
> +			if (map->m_len == maxblocks)
> +				goto out;
> +			else {
> +				pgofs =	(pgoff_t)map->m_lblk + map->m_len;
> +				end = map->m_lblk + maxblocks;
> +				ofs = map->m_len;
> +				goto next_dnode;
> +			}
> +		}
> +	}

Cleaned up as below:

-       if (!map->m_may_create && f2fs_map_blocks_cached(inode, map, flag))
-               goto out;
+       if (!map->m_may_create && f2fs_map_blocks_cached(inode, map, flag)) {
+               if (map->m_len == maxblocks)
+                       goto out;
+
+               pgofs = (pgoff_t)map->m_lblk + map->m_len;
+               end = map->m_lblk + maxblocks;
+               ofs = map->m_len;
+               goto next_dnode;
+       }

>  
>  	map->m_bdev = inode->i_sb->s_bdev;
>  	map->m_multidev_dio =
> -- 
> 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	[flat|nested] 17+ messages in thread

* Re: [f2fs-dev] [PATCH 3/4] f2fs: fix fiemap boundary handling when read extent cache is incomplete
  2026-02-03 13:36 ` [f2fs-dev] [PATCH 3/4] f2fs: fix fiemap boundary handling when read extent cache is incomplete Yongpeng Yang
  2026-02-24  3:48   ` Jaegeuk Kim via Linux-f2fs-devel
@ 2026-02-24  4:38   ` Jaegeuk Kim via Linux-f2fs-devel
  2026-02-27  7:44     ` Yongpeng Yang
  1 sibling, 1 reply; 17+ messages in thread
From: Jaegeuk Kim via Linux-f2fs-devel @ 2026-02-24  4:38 UTC (permalink / raw)
  To: Yongpeng Yang; +Cc: Yongpeng Yang, linux-f2fs-devel

On 02/03, Yongpeng Yang wrote:
> From: Yongpeng Yang <yangyongpeng@xiaomi.com>
> 
> f2fs_fiemap() calls f2fs_map_blocks() to obtain the block mapping a
> file, and then merges contiguous mappings into extents. If the mapping
> is found in the read extent cache, node blocks do not need to be read.
> However, in the following scenario, a contiguous extent can be split
> into two extents:
> 
> root@vm:/mnt/f2fs# dd if=/dev/zero of=data.4M bs=1M count=4 && sync
> root@vm:/mnt/f2fs# dd if=/dev/zero of=data.4M bs=1M count=2 seek=2 conv=notrunc && sync
> root@vm:/mnt/f2fs# echo 3 > /proc/sys/vm/drop_caches # drop 2M~4M extent cache
> root@vm:/mnt/f2fs# dd if=/dev/zero of=data.4M bs=1M count=2 seek=0 conv=notrunc && sync
> root@vm:/mnt/f2fs# f2fs_io fiemap 0 1024 data.4M
> Fiemap: offset = 0 len = 1024
> logical addr.    physical addr.   length           flags
> 0	0000000000000000 0000000006400000 0000000000200000 00001000
> 1	0000000000200000 0000000006600000 0000000000200000 00001001
> 
> Although the physical addresses of the ranges 0~2MB and 2M~4MB are
> contiguous, the mapping for the 2M~4MB range is not present in memory.
> When the physical addresses for the 0~2MB range are updated, no merge
> happens because the adjacent mapping is missing from the in-memory
> cache. As a result, fiemap reports two separate extents instead of a
> single contiguous one.
> 
> The root cause is that the read extent cache does not guarantee that all
> blocks of an extent are present in memory. Therefore, when the extent
> length returned by f2fs_map_blocks_cached() is smaller than maxblocks,
> the remaining mappings are retrieved via f2fs_get_dnode_of_data() to
> ensure correct fiemap extent boundary handling.
> 
> Fixes: cd8fc5226bef ("f2fs: remove the create argument to f2fs_map_blocks")
> Signed-off-by: Yongpeng Yang <yangyongpeng@xiaomi.com>
> ---
>  fs/f2fs/data.c | 14 ++++++++++++--
>  1 file changed, 12 insertions(+), 2 deletions(-)
> 
> diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
> index 42f15fd9c68e..eedadccf86bb 100644
> --- a/fs/f2fs/data.c
> +++ b/fs/f2fs/data.c
> @@ -1623,8 +1623,18 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map, int flag)
>  	lfs_dio_write = (flag == F2FS_GET_BLOCK_DIO && f2fs_lfs_mode(sbi) &&
>  				map->m_may_create);
>  
> -	if (!map->m_may_create && f2fs_map_blocks_cached(inode, map, flag))
> -		goto out;
> +	if (!map->m_may_create) {
> +		if (f2fs_map_blocks_cached(inode, map, flag)) {
> +			if (map->m_len == maxblocks)
> +				goto out;
> +			else {
> +				pgofs =	(pgoff_t)map->m_lblk + map->m_len;
> +				end = map->m_lblk + maxblocks;
> +				ofs = map->m_len;
> +				goto next_dnode;
> +			}
> +		}
> +	}

This patch makes a system panic.

>  
>  	map->m_bdev = inode->i_sb->s_bdev;
>  	map->m_multidev_dio =
> -- 
> 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	[flat|nested] 17+ messages in thread

* Re: [f2fs-dev] [PATCH 3/4] f2fs: fix fiemap boundary handling when read extent cache is incomplete
  2026-02-24  4:38   ` Jaegeuk Kim via Linux-f2fs-devel
@ 2026-02-27  7:44     ` Yongpeng Yang
  2026-02-27 19:23       ` Jaegeuk Kim via Linux-f2fs-devel
  0 siblings, 1 reply; 17+ messages in thread
From: Yongpeng Yang @ 2026-02-27  7:44 UTC (permalink / raw)
  To: Jaegeuk Kim; +Cc: Yongpeng Yang, linux-f2fs-devel

On 2/24/26 12:38, Jaegeuk Kim via Linux-f2fs-devel wrote:
> On 02/03, Yongpeng Yang wrote:
>> From: Yongpeng Yang <yangyongpeng@xiaomi.com>
>>
>> f2fs_fiemap() calls f2fs_map_blocks() to obtain the block mapping a
>> file, and then merges contiguous mappings into extents. If the mapping
>> is found in the read extent cache, node blocks do not need to be read.
>> However, in the following scenario, a contiguous extent can be split
>> into two extents:
>>
>> root@vm:/mnt/f2fs# dd if=/dev/zero of=data.4M bs=1M count=4 && sync
>> root@vm:/mnt/f2fs# dd if=/dev/zero of=data.4M bs=1M count=2 seek=2 conv=notrunc && sync
>> root@vm:/mnt/f2fs# echo 3 > /proc/sys/vm/drop_caches # drop 2M~4M extent cache
>> root@vm:/mnt/f2fs# dd if=/dev/zero of=data.4M bs=1M count=2 seek=0 conv=notrunc && sync
>> root@vm:/mnt/f2fs# f2fs_io fiemap 0 1024 data.4M
>> Fiemap: offset = 0 len = 1024
>> logical addr.    physical addr.   length           flags
>> 0	0000000000000000 0000000006400000 0000000000200000 00001000
>> 1	0000000000200000 0000000006600000 0000000000200000 00001001
>>
>> Although the physical addresses of the ranges 0~2MB and 2M~4MB are
>> contiguous, the mapping for the 2M~4MB range is not present in memory.
>> When the physical addresses for the 0~2MB range are updated, no merge
>> happens because the adjacent mapping is missing from the in-memory
>> cache. As a result, fiemap reports two separate extents instead of a
>> single contiguous one.
>>
>> The root cause is that the read extent cache does not guarantee that all
>> blocks of an extent are present in memory. Therefore, when the extent
>> length returned by f2fs_map_blocks_cached() is smaller than maxblocks,
>> the remaining mappings are retrieved via f2fs_get_dnode_of_data() to
>> ensure correct fiemap extent boundary handling.
>>
>> Fixes: cd8fc5226bef ("f2fs: remove the create argument to f2fs_map_blocks")
>> Signed-off-by: Yongpeng Yang <yangyongpeng@xiaomi.com>
>> ---
>>  fs/f2fs/data.c | 14 ++++++++++++--
>>  1 file changed, 12 insertions(+), 2 deletions(-)
>>
>> diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
>> index 42f15fd9c68e..eedadccf86bb 100644
>> --- a/fs/f2fs/data.c
>> +++ b/fs/f2fs/data.c
>> @@ -1623,8 +1623,18 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map, int flag)
>>  	lfs_dio_write = (flag == F2FS_GET_BLOCK_DIO && f2fs_lfs_mode(sbi) &&
>>  				map->m_may_create);
>>  
>> -	if (!map->m_may_create && f2fs_map_blocks_cached(inode, map, flag))
>> -		goto out;
>> +	if (!map->m_may_create) {
>> +		if (f2fs_map_blocks_cached(inode, map, flag)) {
>> +			if (map->m_len == maxblocks)
>> +				goto out;
>> +			else {
>> +				pgofs =	(pgoff_t)map->m_lblk + map->m_len;
>> +				end = map->m_lblk + maxblocks;
>> +				ofs = map->m_len;
>> +				goto next_dnode;
>> +			}
>> +		}
>> +	}
> 
> This patch makes a system panic.

I have done some testing and only observed the panic in the
f2fs_write_end_io() path. Syzbot has also reported it:
https://syzkaller.appspot.com/bug?extid=6e4cb1cac5efc96ea0ca
My proposed fix is here:
https://lore.kernel.org/all/20260227073052.3940958-2-monty_pavel@sina.com/

Is this the same issue?

Thanks
Yongpeng,

> 
>>  
>>  	map->m_bdev = inode->i_sb->s_bdev;
>>  	map->m_multidev_dio =
>> -- 
>> 2.43.0
> 
> 
> _______________________________________________
> 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] 17+ messages in thread

* Re: [f2fs-dev] [PATCH 3/4] f2fs: fix fiemap boundary handling when read extent cache is incomplete
  2026-02-27  7:44     ` Yongpeng Yang
@ 2026-02-27 19:23       ` Jaegeuk Kim via Linux-f2fs-devel
  2026-02-27 20:41         ` Jaegeuk Kim via Linux-f2fs-devel
  0 siblings, 1 reply; 17+ messages in thread
From: Jaegeuk Kim via Linux-f2fs-devel @ 2026-02-27 19:23 UTC (permalink / raw)
  To: Yongpeng Yang; +Cc: Yongpeng Yang, linux-f2fs-devel

On 02/27, Yongpeng Yang wrote:
> On 2/24/26 12:38, Jaegeuk Kim via Linux-f2fs-devel wrote:
> > On 02/03, Yongpeng Yang wrote:
> >> From: Yongpeng Yang <yangyongpeng@xiaomi.com>
> >>
> >> f2fs_fiemap() calls f2fs_map_blocks() to obtain the block mapping a
> >> file, and then merges contiguous mappings into extents. If the mapping
> >> is found in the read extent cache, node blocks do not need to be read.
> >> However, in the following scenario, a contiguous extent can be split
> >> into two extents:
> >>
> >> root@vm:/mnt/f2fs# dd if=/dev/zero of=data.4M bs=1M count=4 && sync
> >> root@vm:/mnt/f2fs# dd if=/dev/zero of=data.4M bs=1M count=2 seek=2 conv=notrunc && sync
> >> root@vm:/mnt/f2fs# echo 3 > /proc/sys/vm/drop_caches # drop 2M~4M extent cache
> >> root@vm:/mnt/f2fs# dd if=/dev/zero of=data.4M bs=1M count=2 seek=0 conv=notrunc && sync
> >> root@vm:/mnt/f2fs# f2fs_io fiemap 0 1024 data.4M
> >> Fiemap: offset = 0 len = 1024
> >> logical addr.    physical addr.   length           flags
> >> 0	0000000000000000 0000000006400000 0000000000200000 00001000
> >> 1	0000000000200000 0000000006600000 0000000000200000 00001001
> >>
> >> Although the physical addresses of the ranges 0~2MB and 2M~4MB are
> >> contiguous, the mapping for the 2M~4MB range is not present in memory.
> >> When the physical addresses for the 0~2MB range are updated, no merge
> >> happens because the adjacent mapping is missing from the in-memory
> >> cache. As a result, fiemap reports two separate extents instead of a
> >> single contiguous one.
> >>
> >> The root cause is that the read extent cache does not guarantee that all
> >> blocks of an extent are present in memory. Therefore, when the extent
> >> length returned by f2fs_map_blocks_cached() is smaller than maxblocks,
> >> the remaining mappings are retrieved via f2fs_get_dnode_of_data() to
> >> ensure correct fiemap extent boundary handling.
> >>
> >> Fixes: cd8fc5226bef ("f2fs: remove the create argument to f2fs_map_blocks")
> >> Signed-off-by: Yongpeng Yang <yangyongpeng@xiaomi.com>
> >> ---
> >>  fs/f2fs/data.c | 14 ++++++++++++--
> >>  1 file changed, 12 insertions(+), 2 deletions(-)
> >>
> >> diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
> >> index 42f15fd9c68e..eedadccf86bb 100644
> >> --- a/fs/f2fs/data.c
> >> +++ b/fs/f2fs/data.c
> >> @@ -1623,8 +1623,18 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map, int flag)
> >>  	lfs_dio_write = (flag == F2FS_GET_BLOCK_DIO && f2fs_lfs_mode(sbi) &&
> >>  				map->m_may_create);
> >>  
> >> -	if (!map->m_may_create && f2fs_map_blocks_cached(inode, map, flag))
> >> -		goto out;
> >> +	if (!map->m_may_create) {
> >> +		if (f2fs_map_blocks_cached(inode, map, flag)) {
> >> +			if (map->m_len == maxblocks)
> >> +				goto out;
> >> +			else {
> >> +				pgofs =	(pgoff_t)map->m_lblk + map->m_len;
> >> +				end = map->m_lblk + maxblocks;
> >> +				ofs = map->m_len;
> >> +				goto next_dnode;
> >> +			}
> >> +		}
> >> +	}
> > 
> > This patch makes a system panic.
> 
> I have done some testing and only observed the panic in the
> f2fs_write_end_io() path. Syzbot has also reported it:
> https://syzkaller.appspot.com/bug?extid=6e4cb1cac5efc96ea0ca
> My proposed fix is here:
> https://lore.kernel.org/all/20260227073052.3940958-2-monty_pavel@sina.com/
> 
> Is this the same issue?

Yeah, I think so.

> 
> Thanks
> Yongpeng,
> 
> > 
> >>  
> >>  	map->m_bdev = inode->i_sb->s_bdev;
> >>  	map->m_multidev_dio =
> >> -- 
> >> 2.43.0
> > 
> > 
> > _______________________________________________
> > 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] 17+ messages in thread

* Re: [f2fs-dev] [PATCH 3/4] f2fs: fix fiemap boundary handling when read extent cache is incomplete
  2026-02-27 19:23       ` Jaegeuk Kim via Linux-f2fs-devel
@ 2026-02-27 20:41         ` Jaegeuk Kim via Linux-f2fs-devel
  2026-03-06  9:15           ` Yongpeng Yang
  2026-03-19  3:38           ` Yongpeng Yang
  0 siblings, 2 replies; 17+ messages in thread
From: Jaegeuk Kim via Linux-f2fs-devel @ 2026-02-27 20:41 UTC (permalink / raw)
  To: Yongpeng Yang, Yongpeng Yang, linux-f2fs-devel

On 02/27, Jaegeuk Kim via Linux-f2fs-devel wrote:
> On 02/27, Yongpeng Yang wrote:
> > On 2/24/26 12:38, Jaegeuk Kim via Linux-f2fs-devel wrote:
> > > On 02/03, Yongpeng Yang wrote:
> > >> From: Yongpeng Yang <yangyongpeng@xiaomi.com>
> > >>
> > >> f2fs_fiemap() calls f2fs_map_blocks() to obtain the block mapping a
> > >> file, and then merges contiguous mappings into extents. If the mapping
> > >> is found in the read extent cache, node blocks do not need to be read.
> > >> However, in the following scenario, a contiguous extent can be split
> > >> into two extents:
> > >>
> > >> root@vm:/mnt/f2fs# dd if=/dev/zero of=data.4M bs=1M count=4 && sync
> > >> root@vm:/mnt/f2fs# dd if=/dev/zero of=data.4M bs=1M count=2 seek=2 conv=notrunc && sync
> > >> root@vm:/mnt/f2fs# echo 3 > /proc/sys/vm/drop_caches # drop 2M~4M extent cache
> > >> root@vm:/mnt/f2fs# dd if=/dev/zero of=data.4M bs=1M count=2 seek=0 conv=notrunc && sync
> > >> root@vm:/mnt/f2fs# f2fs_io fiemap 0 1024 data.4M
> > >> Fiemap: offset = 0 len = 1024
> > >> logical addr.    physical addr.   length           flags
> > >> 0	0000000000000000 0000000006400000 0000000000200000 00001000
> > >> 1	0000000000200000 0000000006600000 0000000000200000 00001001
> > >>
> > >> Although the physical addresses of the ranges 0~2MB and 2M~4MB are
> > >> contiguous, the mapping for the 2M~4MB range is not present in memory.
> > >> When the physical addresses for the 0~2MB range are updated, no merge
> > >> happens because the adjacent mapping is missing from the in-memory
> > >> cache. As a result, fiemap reports two separate extents instead of a
> > >> single contiguous one.
> > >>
> > >> The root cause is that the read extent cache does not guarantee that all
> > >> blocks of an extent are present in memory. Therefore, when the extent
> > >> length returned by f2fs_map_blocks_cached() is smaller than maxblocks,
> > >> the remaining mappings are retrieved via f2fs_get_dnode_of_data() to
> > >> ensure correct fiemap extent boundary handling.
> > >>
> > >> Fixes: cd8fc5226bef ("f2fs: remove the create argument to f2fs_map_blocks")
> > >> Signed-off-by: Yongpeng Yang <yangyongpeng@xiaomi.com>
> > >> ---
> > >>  fs/f2fs/data.c | 14 ++++++++++++--
> > >>  1 file changed, 12 insertions(+), 2 deletions(-)
> > >>
> > >> diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
> > >> index 42f15fd9c68e..eedadccf86bb 100644
> > >> --- a/fs/f2fs/data.c
> > >> +++ b/fs/f2fs/data.c
> > >> @@ -1623,8 +1623,18 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map, int flag)
> > >>  	lfs_dio_write = (flag == F2FS_GET_BLOCK_DIO && f2fs_lfs_mode(sbi) &&
> > >>  				map->m_may_create);
> > >>  
> > >> -	if (!map->m_may_create && f2fs_map_blocks_cached(inode, map, flag))
> > >> -		goto out;
> > >> +	if (!map->m_may_create) {
> > >> +		if (f2fs_map_blocks_cached(inode, map, flag)) {
> > >> +			if (map->m_len == maxblocks)
> > >> +				goto out;
> > >> +			else {
> > >> +				pgofs =	(pgoff_t)map->m_lblk + map->m_len;
> > >> +				end = map->m_lblk + maxblocks;
> > >> +				ofs = map->m_len;
> > >> +				goto next_dnode;
> > >> +			}
> > >> +		}
> > >> +	}
> > > 
> > > This patch makes a system panic.
> > 
> > I have done some testing and only observed the panic in the
> > f2fs_write_end_io() path. Syzbot has also reported it:
> > https://syzkaller.appspot.com/bug?extid=6e4cb1cac5efc96ea0ca
> > My proposed fix is here:
> > https://lore.kernel.org/all/20260227073052.3940958-2-monty_pavel@sina.com/
> > 
> > Is this the same issue?
> 
> Yeah, I think so.

Actually, not.

[315868.068811] BUG: kernel NULL pointer dereference, address: 0000000000000008
[315868.074623] RIP: 0010:f2fs_map_blocks+0xb70/0x1480 [f2fs]
[315868.201394] Call Trace:
[315868.202689]  <TASK>
[315868.203809]  ? xa_load+0x6c/0xa0
[315868.205431]  f2fs_mpage_readpages+0x22b/0xf80 [f2fs]
[315868.208902]  ? get_page_from_freelist+0x3ff/0x1790
[315868.211374]  ? debug_smp_processor_id+0x17/0x20
[315868.213627]  f2fs_readahead+0xbc/0x110 [f2fs]
[315868.215809]  read_pages+0x60/0x200
[315868.217478]  page_cache_ra_unbounded+0x187/0x260
[315868.220271]  do_page_cache_ra.isra.0+0x62/0x80
[315868.222507]  page_cache_sync_ra+0x69/0x250
[315868.224491]  filemap_get_pages+0x14e/0x740
[315868.226555]  filemap_read+0xfe/0x450
[315868.228488]  ? debug_smp_processor_id+0x17/0x20
[315868.232896]  ? fpregs_assert_state_consistent+0x38/0x60
[315868.235421]  ? fscrypt_dio_supported+0x37/0xa0
[315868.238587]  ? f2fs_force_buffered_io+0x24/0xd0 [f2fs]
[315868.241819]  f2fs_file_read_iter+0x244/0x470 [f2fs]
[315868.246198]  ? f2fs_llseek+0x17c/0x6f0 [f2fs]
[315868.248666]  vfs_read+0x258/0x350
[315868.251489]  ksys_read+0x69/0xe0
[315868.253304]  __x64_sys_read+0x19/0x20
[315868.255961]  x64_sys_call+0x2000/0x2120
[315868.259178]  do_syscall_64+0xd3/0x760
[315868.260930]  ? debug_smp_processor_id+0x17/0x20
[315868.264900]  ? fpregs_assert_state_consistent+0x38/0x60
[315868.268329]  ? do_syscall_64+0x10c/0x760
[315868.273216]  ? kmem_cache_free+0x14a/0x350
[315868.276156]  ? _raw_spin_unlock+0x19/0x40
[315868.278147]  ? __fput+0x199/0x2b0
[315868.279873]  ? fput_close_sync+0x3f/0xc0
[315868.281756]  ? debug_smp_processor_id+0x17/0x20
[315868.285602]  ? fpregs_assert_state_consistent+0x38/0x60
[315868.288218]  ? do_syscall_64+0x10c/0x760
[315868.291295]  ? debug_smp_processor_id+0x17/0x20
[315868.293514]  ? fpregs_assert_state_consistent+0x38/0x60
[315868.295924]  ? do_syscall_64+0x3cf/0x760
[315868.298689]  ? clear_bhb_loop+0x30/0x80
[315868.300504]  entry_SYSCALL_64_after_hwframe+0x76/0x7e
[315868.302812] RIP: 0033:0x7f50ed51a7a1

> 
> > 
> > Thanks
> > Yongpeng,
> > 
> > > 
> > >>  
> > >>  	map->m_bdev = inode->i_sb->s_bdev;
> > >>  	map->m_multidev_dio =
> > >> -- 
> > >> 2.43.0
> > > 
> > > 
> > > _______________________________________________
> > > 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


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

* Re: [f2fs-dev] [PATCH 1/4] f2fs: fix incorrect extent flag when physical addr is NEW_ADDR in f2fs_fiemap
  2026-02-03 13:36 [f2fs-dev] [PATCH 1/4] f2fs: fix incorrect extent flag when physical addr is NEW_ADDR in f2fs_fiemap Yongpeng Yang
                   ` (2 preceding siblings ...)
  2026-02-03 13:37 ` [f2fs-dev] [PATCH 4/4] f2fs: fix inline data not being written to disk in writeback path Yongpeng Yang
@ 2026-03-04  9:13 ` Chao Yu via Linux-f2fs-devel
  2026-03-06  9:18   ` Yongpeng Yang
  2026-03-05 19:10 ` patchwork-bot+f2fs--- via Linux-f2fs-devel
  4 siblings, 1 reply; 17+ messages in thread
From: Chao Yu via Linux-f2fs-devel @ 2026-03-04  9:13 UTC (permalink / raw)
  To: Yongpeng Yang, Jaegeuk Kim; +Cc: Yongpeng Yang, linux-f2fs-devel

FYI, there is a similar proposal previously:

https://lore.kernel.org/linux-f2fs-devel/20230410020724.1817150-1-chao@kernel.org

On 2026/2/3 21:36, Yongpeng Yang wrote:
> From: Yongpeng Yang <yangyongpeng@xiaomi.com>
> 
> When the file block's address is mapped to NEW_ADDR, the extent is
> currently marked with the FIEMAP_EXTENT_UNWRITTEN flag in f2fs_fiemap().
> This flag indicates that the block has been allocated but not yet
> written to. However, NEW_ADDR indicates delayed writing, meaning the
> block has not been allocated yet. Therefore, this should be modified
> such that when a file block's address is mapped to NEW_ADDR, the extent
> is marked with the FIEMAP_EXTENT_DELALLOC flags instead.
> 
> Signed-off-by: Yongpeng Yang <yangyongpeng@xiaomi.com>
> ---
>   fs/f2fs/data.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
> index 84746a06cd58..42f15fd9c68e 100644
> --- a/fs/f2fs/data.c
> +++ b/fs/f2fs/data.c
> @@ -2102,7 +2102,7 @@ int f2fs_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
>   				size += F2FS_BLKSIZE;
>   			}
>   		} else if (map.m_flags & F2FS_MAP_DELALLOC) {
> -			flags = FIEMAP_EXTENT_UNWRITTEN;
> +			flags = FIEMAP_EXTENT_DELALLOC;
>   		}
>   
>   		start_blk += F2FS_BYTES_TO_BLK(size);



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

* Re: [f2fs-dev] [PATCH 2/4] f2fs: fix incorrect file address mapping when inline inode is unwritten
  2026-02-03 13:36 ` [f2fs-dev] [PATCH 2/4] f2fs: fix incorrect file address mapping when inline inode is unwritten Yongpeng Yang
@ 2026-03-04  9:14   ` Chao Yu via Linux-f2fs-devel
  0 siblings, 0 replies; 17+ messages in thread
From: Chao Yu via Linux-f2fs-devel @ 2026-03-04  9:14 UTC (permalink / raw)
  To: Yongpeng Yang, Jaegeuk Kim; +Cc: Yongpeng Yang, linux-f2fs-devel

On 2026/2/3 21:36, Yongpeng Yang wrote:
> From: Yongpeng Yang <yangyongpeng@xiaomi.com>
> 
> When `fileinfo->fi_flags` does not have the `FIEMAP_FLAG_SYNC` bit set
> and inline data has not been persisted yet, the physical address of the
> extent is calculated incorrectly for unwritten inline inodes.
> 
> root@vm:/mnt/f2fs# dd if=/dev/zero of=data.3k bs=3k count=1
> root@vm:/mnt/f2fs# f2fs_io fiemap 0 100 data.3k
> Fiemap: offset = 0 len = 100
> 	logical addr.    physical addr.   length           flags
> 0	0000000000000000 00000ffffffff16c 0000000000000c00 00000301
> 
> This patch fixes the issue by checking if the inode's address is valid.
> If the inline inode is unwritten, set the physical address to 0 and
> mark the extent with `FIEMAP_EXTENT_UNKNOWN | FIEMAP_EXTENT_DELALLOC`
> flags.
> 

Cc: stable@kernel.org

> Fixes: 67f8cf3cee6f ("f2fs: support fiemap for inline_data")
> 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] 17+ messages in thread

* Re: [f2fs-dev] [PATCH 4/4] f2fs: fix inline data not being written to disk in writeback path
  2026-02-03 13:37 ` [f2fs-dev] [PATCH 4/4] f2fs: fix inline data not being written to disk in writeback path Yongpeng Yang
@ 2026-03-04  9:30   ` Chao Yu via Linux-f2fs-devel
  2026-03-06  8:55     ` Yongpeng Yang
  0 siblings, 1 reply; 17+ messages in thread
From: Chao Yu via Linux-f2fs-devel @ 2026-03-04  9:30 UTC (permalink / raw)
  To: Yongpeng Yang, Jaegeuk Kim; +Cc: Yongpeng Yang, linux-f2fs-devel

On 2026/2/3 21:37, 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

Can we fix this in f2fs_fiemap()? rather than in f2fs_write_single_data_page(),
since it affects more.

f2fs_inline_data_fiemap()
...

if (fieinfo->fi_flags & FIEMAP_FLAG_SYNC)
	write single node page if it is dirty?

Thanks,

> 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_sync_node_pages() after
> f2fs_write_inline_data() successfully returns, which will write back the
> inode folio and wait for the writeback to complete.
> 
> Fixes: 9ffe0fb5f3bb ("f2fs: handle inline data operations")
> Signed-off-by: Yongpeng Yang <yangyongpeng@xiaomi.com>
> ---
>   fs/f2fs/checkpoint.c |  1 +
>   fs/f2fs/data.c       | 19 ++++++++++++++++++-
>   fs/f2fs/node.c       | 21 ++++++++++++++++-----
>   3 files changed, 35 insertions(+), 6 deletions(-)
> 
> diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
> index 5172396c0b01..d0bca57854da 100644
> --- a/fs/f2fs/checkpoint.c
> +++ b/fs/f2fs/checkpoint.c
> @@ -1347,6 +1347,7 @@ static int block_operations(struct f2fs_sb_info *sbi)
>   	struct writeback_control wbc = {
>   		.sync_mode = WB_SYNC_ALL,
>   		.nr_to_write = LONG_MAX,
> +		.range_cyclic = 1,
>   	};
>   	int err = 0, cnt = 0;
>   
> diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
> index eedadccf86bb..ccc5e4ddf547 100644
> --- a/fs/f2fs/data.c
> +++ b/fs/f2fs/data.c
> @@ -3126,8 +3126,25 @@ int f2fs_write_single_data_page(struct folio *folio, int *submitted,
>   	err = -EAGAIN;
>   	if (f2fs_has_inline_data(inode)) {
>   		err = f2fs_write_inline_data(inode, folio);
> -		if (!err)
> +		if (!err) {
> +			struct folio *ifolio;
> +			struct writeback_control iwbc = {
> +				.sync_mode = WB_SYNC_ALL,
> +				.range_start = inode->i_ino << PAGE_SHIFT,
> +				.range_end = inode->i_ino << PAGE_SHIFT,
> +				.nr_to_write = 1,
> +				.range_cyclic = 0,
> +			};
> +
> +			if (!f2fs_sync_node_pages(sbi, &iwbc, true, FS_NODE_IO)) {
> +				ifolio = f2fs_get_inode_folio(sbi, inode->i_ino);
> +				if (!IS_ERR(ifolio)) {
> +					f2fs_folio_wait_writeback(ifolio, NODE, true, true);
> +					f2fs_folio_put(ifolio, true);
> +				}
> +			}
>   			goto out;
> +		}
>   	}
>   
>   	if (err == -EAGAIN) {
> diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
> index 74992fd9c9b6..47bff89bafe6 100644
> --- a/fs/f2fs/node.c
> +++ b/fs/f2fs/node.c
> @@ -2083,7 +2083,8 @@ int f2fs_sync_node_pages(struct f2fs_sb_info *sbi,
>   				struct writeback_control *wbc,
>   				bool do_balance, enum iostat_type io_type)
>   {
> -	pgoff_t index;
> +	pgoff_t index, wbc_index;
> +	pgoff_t end, wbc_end;
>   	struct folio_batch fbatch;
>   	int step = 0;
>   	int nwritten = 0;
> @@ -2092,14 +2093,24 @@ int f2fs_sync_node_pages(struct f2fs_sb_info *sbi,
>   
>   	folio_batch_init(&fbatch);
>   
> +	wbc_index = 0;
> +	wbc_end = LONG_MAX;
> +	if (!wbc->range_cyclic) {
> +		wbc_index = wbc->range_start >> PAGE_SHIFT;
> +		wbc_end = wbc->range_end >> PAGE_SHIFT;
> +	}
>   next_step:
> -	index = 0;
> +	index = wbc_index;
> +	end = wbc_end;
>   
> -	while (!done && (nr_folios = filemap_get_folios_tag(NODE_MAPPING(sbi),
> -				&index, (pgoff_t)-1, PAGECACHE_TAG_DIRTY,
> -				&fbatch))) {
> +	while (!done && (index <= end)) {
>   		int i;
>   
> +		nr_folios = filemap_get_folios_tag(NODE_MAPPING(sbi),
> +				&index, end, PAGECACHE_TAG_DIRTY,
> +				&fbatch);
> +		if (nr_folios == 0)
> +			break;
>   		for (i = 0; i < nr_folios; i++) {
>   			struct folio *folio = fbatch.folios[i];
>   			bool submitted = false;



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

* Re: [f2fs-dev] [PATCH 1/4] f2fs: fix incorrect extent flag when physical addr is NEW_ADDR in f2fs_fiemap
  2026-02-03 13:36 [f2fs-dev] [PATCH 1/4] f2fs: fix incorrect extent flag when physical addr is NEW_ADDR in f2fs_fiemap Yongpeng Yang
                   ` (3 preceding siblings ...)
  2026-03-04  9:13 ` [f2fs-dev] [PATCH 1/4] f2fs: fix incorrect extent flag when physical addr is NEW_ADDR in f2fs_fiemap Chao Yu via Linux-f2fs-devel
@ 2026-03-05 19:10 ` patchwork-bot+f2fs--- via Linux-f2fs-devel
  4 siblings, 0 replies; 17+ messages in thread
From: patchwork-bot+f2fs--- via Linux-f2fs-devel @ 2026-03-05 19:10 UTC (permalink / raw)
  To: Yongpeng Yang; +Cc: jaegeuk, yangyongpeng, linux-f2fs-devel

Hello:

This series was applied to jaegeuk/f2fs.git (dev)
by Jaegeuk Kim <jaegeuk@kernel.org>:

On Tue,  3 Feb 2026 21:36:33 +0800 you wrote:
> From: Yongpeng Yang <yangyongpeng@xiaomi.com>
> 
> When the file block's address is mapped to NEW_ADDR, the extent is
> currently marked with the FIEMAP_EXTENT_UNWRITTEN flag in f2fs_fiemap().
> This flag indicates that the block has been allocated but not yet
> written to. However, NEW_ADDR indicates delayed writing, meaning the
> block has not been allocated yet. Therefore, this should be modified
> such that when a file block's address is mapped to NEW_ADDR, the extent
> is marked with the FIEMAP_EXTENT_DELALLOC flags instead.
> 
> [...]

Here is the summary with links:
  - [f2fs-dev,1/4] f2fs: fix incorrect extent flag when physical addr is NEW_ADDR in f2fs_fiemap
    (no matching commit)
  - [f2fs-dev,2/4] f2fs: fix incorrect file address mapping when inline inode is unwritten
    https://git.kernel.org/jaegeuk/f2fs/c/56528dc7fcc6
  - [f2fs-dev,3/4] f2fs: fix fiemap boundary handling when read extent cache is incomplete
    (no matching commit)
  - [f2fs-dev,4/4] f2fs: fix inline data not being written to disk in writeback path
    (no matching commit)

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




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

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


On 3/4/2026 5:30 PM, Chao Yu via Linux-f2fs-devel wrote:
> On 2026/2/3 21:37, 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
> 
> Can we fix this in f2fs_fiemap()? rather than in 
> f2fs_write_single_data_page(),
> since it affects more.
> 
> f2fs_inline_data_fiemap()
> ...
> 
> if (fieinfo->fi_flags & FIEMAP_FLAG_SYNC)
>      write single node page if it is dirty?
> 

This makes more sense. I'll fix this in v2 patch. In
f2fs_write_single_data_page(), writing a node folio may cause
f2fs_do_sync_file() to write the inode folio once through the
file_write_and_wait_range() path. Afterwards, f2fs_write_inode() marks
the inode folio dirty again, which can lead to redundant writeback of
the inode folio.

f2fs_do_sync_file
  - file_write_and_wait_range
  - f2fs_write_inode

Thanks
Yongpeng,

> Thanks,
> 
>> 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_sync_node_pages() after
>> f2fs_write_inline_data() successfully returns, which will write back the
>> inode folio and wait for the writeback to complete.
>>
>> Fixes: 9ffe0fb5f3bb ("f2fs: handle inline data operations")
>> Signed-off-by: Yongpeng Yang <yangyongpeng@xiaomi.com>
>> ---
>>   fs/f2fs/checkpoint.c |  1 +
>>   fs/f2fs/data.c       | 19 ++++++++++++++++++-
>>   fs/f2fs/node.c       | 21 ++++++++++++++++-----
>>   3 files changed, 35 insertions(+), 6 deletions(-)
>>
>> diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
>> index 5172396c0b01..d0bca57854da 100644
>> --- a/fs/f2fs/checkpoint.c
>> +++ b/fs/f2fs/checkpoint.c
>> @@ -1347,6 +1347,7 @@ static int block_operations(struct f2fs_sb_info 
>> *sbi)
>>       struct writeback_control wbc = {
>>           .sync_mode = WB_SYNC_ALL,
>>           .nr_to_write = LONG_MAX,
>> +        .range_cyclic = 1,
>>       };
>>       int err = 0, cnt = 0;
>> diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
>> index eedadccf86bb..ccc5e4ddf547 100644
>> --- a/fs/f2fs/data.c
>> +++ b/fs/f2fs/data.c
>> @@ -3126,8 +3126,25 @@ int f2fs_write_single_data_page(struct folio 
>> *folio, int *submitted,
>>       err = -EAGAIN;
>>       if (f2fs_has_inline_data(inode)) {
>>           err = f2fs_write_inline_data(inode, folio);
>> -        if (!err)
>> +        if (!err) {
>> +            struct folio *ifolio;
>> +            struct writeback_control iwbc = {
>> +                .sync_mode = WB_SYNC_ALL,
>> +                .range_start = inode->i_ino << PAGE_SHIFT,
>> +                .range_end = inode->i_ino << PAGE_SHIFT,
>> +                .nr_to_write = 1,
>> +                .range_cyclic = 0,
>> +            };
>> +
>> +            if (!f2fs_sync_node_pages(sbi, &iwbc, true, FS_NODE_IO)) {
>> +                ifolio = f2fs_get_inode_folio(sbi, inode->i_ino);
>> +                if (!IS_ERR(ifolio)) {
>> +                    f2fs_folio_wait_writeback(ifolio, NODE, true, true);
>> +                    f2fs_folio_put(ifolio, true);
>> +                }
>> +            }
>>               goto out;
>> +        }
>>       }
>>       if (err == -EAGAIN) {
>> diff --git a/fs/f2fs/node.c b/fs/f2fs/node.c
>> index 74992fd9c9b6..47bff89bafe6 100644
>> --- a/fs/f2fs/node.c
>> +++ b/fs/f2fs/node.c
>> @@ -2083,7 +2083,8 @@ int f2fs_sync_node_pages(struct f2fs_sb_info *sbi,
>>                   struct writeback_control *wbc,
>>                   bool do_balance, enum iostat_type io_type)
>>   {
>> -    pgoff_t index;
>> +    pgoff_t index, wbc_index;
>> +    pgoff_t end, wbc_end;
>>       struct folio_batch fbatch;
>>       int step = 0;
>>       int nwritten = 0;
>> @@ -2092,14 +2093,24 @@ int f2fs_sync_node_pages(struct f2fs_sb_info 
>> *sbi,
>>       folio_batch_init(&fbatch);
>> +    wbc_index = 0;
>> +    wbc_end = LONG_MAX;
>> +    if (!wbc->range_cyclic) {
>> +        wbc_index = wbc->range_start >> PAGE_SHIFT;
>> +        wbc_end = wbc->range_end >> PAGE_SHIFT;
>> +    }
>>   next_step:
>> -    index = 0;
>> +    index = wbc_index;
>> +    end = wbc_end;
>> -    while (!done && (nr_folios = 
>> filemap_get_folios_tag(NODE_MAPPING(sbi),
>> -                &index, (pgoff_t)-1, PAGECACHE_TAG_DIRTY,
>> -                &fbatch))) {
>> +    while (!done && (index <= end)) {
>>           int i;
>> +        nr_folios = filemap_get_folios_tag(NODE_MAPPING(sbi),
>> +                &index, end, PAGECACHE_TAG_DIRTY,
>> +                &fbatch);
>> +        if (nr_folios == 0)
>> +            break;
>>           for (i = 0; i < nr_folios; i++) {
>>               struct folio *folio = fbatch.folios[i];
>>               bool submitted = false;
> 
> 
> 
> _______________________________________________
> 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] 17+ messages in thread

* Re: [f2fs-dev] [PATCH 3/4] f2fs: fix fiemap boundary handling when read extent cache is incomplete
  2026-02-27 20:41         ` Jaegeuk Kim via Linux-f2fs-devel
@ 2026-03-06  9:15           ` Yongpeng Yang
  2026-03-19  3:38           ` Yongpeng Yang
  1 sibling, 0 replies; 17+ messages in thread
From: Yongpeng Yang @ 2026-03-06  9:15 UTC (permalink / raw)
  To: Jaegeuk Kim, Yongpeng Yang, Yongpeng Yang, linux-f2fs-devel,
	Chao Yu


On 2/28/2026 4:41 AM, Jaegeuk Kim via Linux-f2fs-devel wrote:
> On 02/27, Jaegeuk Kim via Linux-f2fs-devel wrote:
>> On 02/27, Yongpeng Yang wrote:
>>> On 2/24/26 12:38, Jaegeuk Kim via Linux-f2fs-devel wrote:
>>>> On 02/03, Yongpeng Yang wrote:
>>>>> From: Yongpeng Yang <yangyongpeng@xiaomi.com>
>>>>>
>>>>> f2fs_fiemap() calls f2fs_map_blocks() to obtain the block mapping a
>>>>> file, and then merges contiguous mappings into extents. If the mapping
>>>>> is found in the read extent cache, node blocks do not need to be read.
>>>>> However, in the following scenario, a contiguous extent can be split
>>>>> into two extents:
>>>>>
>>>>> root@vm:/mnt/f2fs# dd if=/dev/zero of=data.4M bs=1M count=4 && sync
>>>>> root@vm:/mnt/f2fs# dd if=/dev/zero of=data.4M bs=1M count=2 seek=2 conv=notrunc && sync
>>>>> root@vm:/mnt/f2fs# echo 3 > /proc/sys/vm/drop_caches # drop 2M~4M extent cache
>>>>> root@vm:/mnt/f2fs# dd if=/dev/zero of=data.4M bs=1M count=2 seek=0 conv=notrunc && sync
>>>>> root@vm:/mnt/f2fs# f2fs_io fiemap 0 1024 data.4M
>>>>> Fiemap: offset = 0 len = 1024
>>>>> logical addr.    physical addr.   length           flags
>>>>> 0	0000000000000000 0000000006400000 0000000000200000 00001000
>>>>> 1	0000000000200000 0000000006600000 0000000000200000 00001001
>>>>>
>>>>> Although the physical addresses of the ranges 0~2MB and 2M~4MB are
>>>>> contiguous, the mapping for the 2M~4MB range is not present in memory.
>>>>> When the physical addresses for the 0~2MB range are updated, no merge
>>>>> happens because the adjacent mapping is missing from the in-memory
>>>>> cache. As a result, fiemap reports two separate extents instead of a
>>>>> single contiguous one.
>>>>>
>>>>> The root cause is that the read extent cache does not guarantee that all
>>>>> blocks of an extent are present in memory. Therefore, when the extent
>>>>> length returned by f2fs_map_blocks_cached() is smaller than maxblocks,
>>>>> the remaining mappings are retrieved via f2fs_get_dnode_of_data() to
>>>>> ensure correct fiemap extent boundary handling.
>>>>>
>>>>> Fixes: cd8fc5226bef ("f2fs: remove the create argument to f2fs_map_blocks")
>>>>> Signed-off-by: Yongpeng Yang <yangyongpeng@xiaomi.com>
>>>>> ---
>>>>>   fs/f2fs/data.c | 14 ++++++++++++--
>>>>>   1 file changed, 12 insertions(+), 2 deletions(-)
>>>>>
>>>>> diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
>>>>> index 42f15fd9c68e..eedadccf86bb 100644
>>>>> --- a/fs/f2fs/data.c
>>>>> +++ b/fs/f2fs/data.c
>>>>> @@ -1623,8 +1623,18 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map, int flag)
>>>>>   	lfs_dio_write = (flag == F2FS_GET_BLOCK_DIO && f2fs_lfs_mode(sbi) &&
>>>>>   				map->m_may_create);
>>>>>   
>>>>> -	if (!map->m_may_create && f2fs_map_blocks_cached(inode, map, flag))
>>>>> -		goto out;
>>>>> +	if (!map->m_may_create) {
>>>>> +		if (f2fs_map_blocks_cached(inode, map, flag)) {
>>>>> +			if (map->m_len == maxblocks)
>>>>> +				goto out;
>>>>> +			else {
>>>>> +				pgofs =	(pgoff_t)map->m_lblk + map->m_len;
>>>>> +				end = map->m_lblk + maxblocks;
>>>>> +				ofs = map->m_len;
>>>>> +				goto next_dnode;
>>>>> +			}
>>>>> +		}
>>>>> +	}
>>>>
>>>> This patch makes a system panic.
>>>
>>> I have done some testing and only observed the panic in the
>>> f2fs_write_end_io() path. Syzbot has also reported it:
>>> https://syzkaller.appspot.com/bug?extid=6e4cb1cac5efc96ea0ca
>>> My proposed fix is here:
>>> https://lore.kernel.org/all/20260227073052.3940958-2-monty_pavel@sina.com/
>>>
>>> Is this the same issue?
>>
>> Yeah, I think so.
> 
> Actually, not.
> 
> [315868.068811] BUG: kernel NULL pointer dereference, address: 0000000000000008
> [315868.074623] RIP: 0010:f2fs_map_blocks+0xb70/0x1480 [f2fs]
> [315868.201394] Call Trace:
> [315868.202689]  <TASK>
> [315868.203809]  ? xa_load+0x6c/0xa0
> [315868.205431]  f2fs_mpage_readpages+0x22b/0xf80 [f2fs]
> [315868.208902]  ? get_page_from_freelist+0x3ff/0x1790
> [315868.211374]  ? debug_smp_processor_id+0x17/0x20
> [315868.213627]  f2fs_readahead+0xbc/0x110 [f2fs]
> [315868.215809]  read_pages+0x60/0x200
> [315868.217478]  page_cache_ra_unbounded+0x187/0x260
> [315868.220271]  do_page_cache_ra.isra.0+0x62/0x80
> [315868.222507]  page_cache_sync_ra+0x69/0x250
> [315868.224491]  filemap_get_pages+0x14e/0x740
> [315868.226555]  filemap_read+0xfe/0x450
> [315868.228488]  ? debug_smp_processor_id+0x17/0x20
> [315868.232896]  ? fpregs_assert_state_consistent+0x38/0x60
> [315868.235421]  ? fscrypt_dio_supported+0x37/0xa0
> [315868.238587]  ? f2fs_force_buffered_io+0x24/0xd0 [f2fs]
> [315868.241819]  f2fs_file_read_iter+0x244/0x470 [f2fs]
> [315868.246198]  ? f2fs_llseek+0x17c/0x6f0 [f2fs]
> [315868.248666]  vfs_read+0x258/0x350
> [315868.251489]  ksys_read+0x69/0xe0
> [315868.253304]  __x64_sys_read+0x19/0x20
> [315868.255961]  x64_sys_call+0x2000/0x2120
> [315868.259178]  do_syscall_64+0xd3/0x760
> [315868.260930]  ? debug_smp_processor_id+0x17/0x20
> [315868.264900]  ? fpregs_assert_state_consistent+0x38/0x60
> [315868.268329]  ? do_syscall_64+0x10c/0x760
> [315868.273216]  ? kmem_cache_free+0x14a/0x350
> [315868.276156]  ? _raw_spin_unlock+0x19/0x40
> [315868.278147]  ? __fput+0x199/0x2b0
> [315868.279873]  ? fput_close_sync+0x3f/0xc0
> [315868.281756]  ? debug_smp_processor_id+0x17/0x20
> [315868.285602]  ? fpregs_assert_state_consistent+0x38/0x60
> [315868.288218]  ? do_syscall_64+0x10c/0x760
> [315868.291295]  ? debug_smp_processor_id+0x17/0x20
> [315868.293514]  ? fpregs_assert_state_consistent+0x38/0x60
> [315868.295924]  ? do_syscall_64+0x3cf/0x760
> [315868.298689]  ? clear_bhb_loop+0x30/0x80
> [315868.300504]  entry_SYSCALL_64_after_hwframe+0x76/0x7e
> [315868.302812] RIP: 0033:0x7f50ed51a7a1

I ran xfstests and some stress tests but could not reproduce the issue.
Could you please provide a test case that can reproduce this problem?

Thanks
Yongpeng,

> 
>>
>>>
>>> Thanks
>>> Yongpeng,
>>>
>>>>
>>>>>   
>>>>>   	map->m_bdev = inode->i_sb->s_bdev;
>>>>>   	map->m_multidev_dio =
>>>>> -- 
>>>>> 2.43.0
>>>>
>>>>
>>>> _______________________________________________
>>>> 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
> 
> 
> _______________________________________________
> 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] 17+ messages in thread

* Re: [f2fs-dev] [PATCH 1/4] f2fs: fix incorrect extent flag when physical addr is NEW_ADDR in f2fs_fiemap
  2026-03-04  9:13 ` [f2fs-dev] [PATCH 1/4] f2fs: fix incorrect extent flag when physical addr is NEW_ADDR in f2fs_fiemap Chao Yu via Linux-f2fs-devel
@ 2026-03-06  9:18   ` Yongpeng Yang
  0 siblings, 0 replies; 17+ messages in thread
From: Yongpeng Yang @ 2026-03-06  9:18 UTC (permalink / raw)
  To: Chao Yu, Yongpeng Yang, Jaegeuk Kim; +Cc: Yongpeng Yang, linux-f2fs-devel

On 3/4/2026 5:13 PM, Chao Yu via Linux-f2fs-devel wrote:
> FYI, there is a similar proposal previously:
> 
> https://lore.kernel.org/linux-f2fs-devel/20230410020724.1817150-1- 
> chao@kernel.org

Looks better than my patch, and the commit message is more detailed.

Thanks
Yongpeng,

> 
> On 2026/2/3 21:36, Yongpeng Yang wrote:
>> From: Yongpeng Yang <yangyongpeng@xiaomi.com>
>>
>> When the file block's address is mapped to NEW_ADDR, the extent is
>> currently marked with the FIEMAP_EXTENT_UNWRITTEN flag in f2fs_fiemap().
>> This flag indicates that the block has been allocated but not yet
>> written to. However, NEW_ADDR indicates delayed writing, meaning the
>> block has not been allocated yet. Therefore, this should be modified
>> such that when a file block's address is mapped to NEW_ADDR, the extent
>> is marked with the FIEMAP_EXTENT_DELALLOC flags instead.
>>
>> Signed-off-by: Yongpeng Yang <yangyongpeng@xiaomi.com>
>> ---
>>   fs/f2fs/data.c | 2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
>> index 84746a06cd58..42f15fd9c68e 100644
>> --- a/fs/f2fs/data.c
>> +++ b/fs/f2fs/data.c
>> @@ -2102,7 +2102,7 @@ int f2fs_fiemap(struct inode *inode, struct 
>> fiemap_extent_info *fieinfo,
>>                   size += F2FS_BLKSIZE;
>>               }
>>           } else if (map.m_flags & F2FS_MAP_DELALLOC) {
>> -            flags = FIEMAP_EXTENT_UNWRITTEN;
>> +            flags = FIEMAP_EXTENT_DELALLOC;
>>           }
>>           start_blk += F2FS_BYTES_TO_BLK(size);
> 
> 
> 
> _______________________________________________
> 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] 17+ messages in thread

* Re: [f2fs-dev] [PATCH 3/4] f2fs: fix fiemap boundary handling when read extent cache is incomplete
  2026-02-27 20:41         ` Jaegeuk Kim via Linux-f2fs-devel
  2026-03-06  9:15           ` Yongpeng Yang
@ 2026-03-19  3:38           ` Yongpeng Yang
  1 sibling, 0 replies; 17+ messages in thread
From: Yongpeng Yang @ 2026-03-19  3:38 UTC (permalink / raw)
  To: Jaegeuk Kim, Yongpeng Yang, linux-f2fs-devel, Chao Yu

On 2/28/26 04:41, Jaegeuk Kim via Linux-f2fs-devel wrote:
> On 02/27, Jaegeuk Kim via Linux-f2fs-devel wrote:
>> On 02/27, Yongpeng Yang wrote:
>>> On 2/24/26 12:38, Jaegeuk Kim via Linux-f2fs-devel wrote:
>>>> On 02/03, Yongpeng Yang wrote:
>>>>> From: Yongpeng Yang <yangyongpeng@xiaomi.com>
>>>>>
>>>>> f2fs_fiemap() calls f2fs_map_blocks() to obtain the block mapping a
>>>>> file, and then merges contiguous mappings into extents. If the mapping
>>>>> is found in the read extent cache, node blocks do not need to be read.
>>>>> However, in the following scenario, a contiguous extent can be split
>>>>> into two extents:
>>>>>
>>>>> root@vm:/mnt/f2fs# dd if=/dev/zero of=data.4M bs=1M count=4 && sync
>>>>> root@vm:/mnt/f2fs# dd if=/dev/zero of=data.4M bs=1M count=2 seek=2 conv=notrunc && sync
>>>>> root@vm:/mnt/f2fs# echo 3 > /proc/sys/vm/drop_caches # drop 2M~4M extent cache
>>>>> root@vm:/mnt/f2fs# dd if=/dev/zero of=data.4M bs=1M count=2 seek=0 conv=notrunc && sync
>>>>> root@vm:/mnt/f2fs# f2fs_io fiemap 0 1024 data.4M
>>>>> Fiemap: offset = 0 len = 1024
>>>>> logical addr.    physical addr.   length           flags
>>>>> 0	0000000000000000 0000000006400000 0000000000200000 00001000
>>>>> 1	0000000000200000 0000000006600000 0000000000200000 00001001
>>>>>
>>>>> Although the physical addresses of the ranges 0~2MB and 2M~4MB are
>>>>> contiguous, the mapping for the 2M~4MB range is not present in memory.
>>>>> When the physical addresses for the 0~2MB range are updated, no merge
>>>>> happens because the adjacent mapping is missing from the in-memory
>>>>> cache. As a result, fiemap reports two separate extents instead of a
>>>>> single contiguous one.
>>>>>
>>>>> The root cause is that the read extent cache does not guarantee that all
>>>>> blocks of an extent are present in memory. Therefore, when the extent
>>>>> length returned by f2fs_map_blocks_cached() is smaller than maxblocks,
>>>>> the remaining mappings are retrieved via f2fs_get_dnode_of_data() to
>>>>> ensure correct fiemap extent boundary handling.
>>>>>
>>>>> Fixes: cd8fc5226bef ("f2fs: remove the create argument to f2fs_map_blocks")
>>>>> Signed-off-by: Yongpeng Yang <yangyongpeng@xiaomi.com>
>>>>> ---
>>>>>  fs/f2fs/data.c | 14 ++++++++++++--
>>>>>  1 file changed, 12 insertions(+), 2 deletions(-)
>>>>>
>>>>> diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
>>>>> index 42f15fd9c68e..eedadccf86bb 100644
>>>>> --- a/fs/f2fs/data.c
>>>>> +++ b/fs/f2fs/data.c
>>>>> @@ -1623,8 +1623,18 @@ int f2fs_map_blocks(struct inode *inode, struct f2fs_map_blocks *map, int flag)
>>>>>  	lfs_dio_write = (flag == F2FS_GET_BLOCK_DIO && f2fs_lfs_mode(sbi) &&
>>>>>  				map->m_may_create);
>>>>>  
>>>>> -	if (!map->m_may_create && f2fs_map_blocks_cached(inode, map, flag))
>>>>> -		goto out;
>>>>> +	if (!map->m_may_create) {
>>>>> +		if (f2fs_map_blocks_cached(inode, map, flag)) {
>>>>> +			if (map->m_len == maxblocks)
>>>>> +				goto out;
>>>>> +			else {
>>>>> +				pgofs =	(pgoff_t)map->m_lblk + map->m_len;
>>>>> +				end = map->m_lblk + maxblocks;
>>>>> +				ofs = map->m_len;
>>>>> +				goto next_dnode;
>>>>> +			}
>>>>> +		}
>>>>> +	}
>>>>
>>>> This patch makes a system panic.
>>>
>>> I have done some testing and only observed the panic in the
>>> f2fs_write_end_io() path. Syzbot has also reported it:
>>> https://syzkaller.appspot.com/bug?extid=6e4cb1cac5efc96ea0ca
>>> My proposed fix is here:
>>> https://lore.kernel.org/all/20260227073052.3940958-2-monty_pavel@sina.com/
>>>
>>> Is this the same issue?
>>
>> Yeah, I think so.
> 
> Actually, not.
> 
> [315868.068811] BUG: kernel NULL pointer dereference, address: 0000000000000008
> [315868.074623] RIP: 0010:f2fs_map_blocks+0xb70/0x1480 [f2fs]
> [315868.201394] Call Trace:
> [315868.202689]  <TASK>
> [315868.203809]  ? xa_load+0x6c/0xa0
> [315868.205431]  f2fs_mpage_readpages+0x22b/0xf80 [f2fs]
> [315868.208902]  ? get_page_from_freelist+0x3ff/0x1790
> [315868.211374]  ? debug_smp_processor_id+0x17/0x20
> [315868.213627]  f2fs_readahead+0xbc/0x110 [f2fs]
> [315868.215809]  read_pages+0x60/0x200
> [315868.217478]  page_cache_ra_unbounded+0x187/0x260
> [315868.220271]  do_page_cache_ra.isra.0+0x62/0x80
> [315868.222507]  page_cache_sync_ra+0x69/0x250
> [315868.224491]  filemap_get_pages+0x14e/0x740
> [315868.226555]  filemap_read+0xfe/0x450
> [315868.228488]  ? debug_smp_processor_id+0x17/0x20
> [315868.232896]  ? fpregs_assert_state_consistent+0x38/0x60
> [315868.235421]  ? fscrypt_dio_supported+0x37/0xa0
> [315868.238587]  ? f2fs_force_buffered_io+0x24/0xd0 [f2fs]
> [315868.241819]  f2fs_file_read_iter+0x244/0x470 [f2fs]
> [315868.246198]  ? f2fs_llseek+0x17c/0x6f0 [f2fs]
> [315868.248666]  vfs_read+0x258/0x350
> [315868.251489]  ksys_read+0x69/0xe0
> [315868.253304]  __x64_sys_read+0x19/0x20
> [315868.255961]  x64_sys_call+0x2000/0x2120
> [315868.259178]  do_syscall_64+0xd3/0x760
> [315868.260930]  ? debug_smp_processor_id+0x17/0x20
> [315868.264900]  ? fpregs_assert_state_consistent+0x38/0x60
> [315868.268329]  ? do_syscall_64+0x10c/0x760
> [315868.273216]  ? kmem_cache_free+0x14a/0x350
> [315868.276156]  ? _raw_spin_unlock+0x19/0x40
> [315868.278147]  ? __fput+0x199/0x2b0
> [315868.279873]  ? fput_close_sync+0x3f/0xc0
> [315868.281756]  ? debug_smp_processor_id+0x17/0x20
> [315868.285602]  ? fpregs_assert_state_consistent+0x38/0x60
> [315868.288218]  ? do_syscall_64+0x10c/0x760
> [315868.291295]  ? debug_smp_processor_id+0x17/0x20
> [315868.293514]  ? fpregs_assert_state_consistent+0x38/0x60
> [315868.295924]  ? do_syscall_64+0x3cf/0x760
> [315868.298689]  ? clear_bhb_loop+0x30/0x80
> [315868.300504]  entry_SYSCALL_64_after_hwframe+0x76/0x7e
> [315868.302812] RIP: 0033:0x7f50ed51a7a1
> 

I reproduced this issue. The root cause is that when f2fs_map_blocks()
->f2fs_map_blocks_cached() hits the read extent cache, map
->m_multidev_dio is not updated. Meanwhile, the f2fs_mpage_readpages()
call path does not initialize it either. As a result, on a single-device
mount, map->m_multidev_dio may be left as non-zero, causing
f2fs_map_blocks()->map_is_mergeable() to access FDEV(bidx).bdev, which
can lead to a NULL pointer dereference.

I'll fix this in v2 patch.

Thanks
Yongpeng,

>>
>>>
>>> Thanks
>>> Yongpeng,
>>>
>>>>
>>>>>  
>>>>>  	map->m_bdev = inode->i_sb->s_bdev;
>>>>>  	map->m_multidev_dio =
>>>>> -- 
>>>>> 2.43.0
>>>>
>>>>
>>>> _______________________________________________
>>>> 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
> 
> 
> _______________________________________________
> 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] 17+ messages in thread

end of thread, other threads:[~2026-03-19  3:38 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-02-03 13:36 [f2fs-dev] [PATCH 1/4] f2fs: fix incorrect extent flag when physical addr is NEW_ADDR in f2fs_fiemap Yongpeng Yang
2026-02-03 13:36 ` [f2fs-dev] [PATCH 2/4] f2fs: fix incorrect file address mapping when inline inode is unwritten Yongpeng Yang
2026-03-04  9:14   ` Chao Yu via Linux-f2fs-devel
2026-02-03 13:36 ` [f2fs-dev] [PATCH 3/4] f2fs: fix fiemap boundary handling when read extent cache is incomplete Yongpeng Yang
2026-02-24  3:48   ` Jaegeuk Kim via Linux-f2fs-devel
2026-02-24  4:38   ` Jaegeuk Kim via Linux-f2fs-devel
2026-02-27  7:44     ` Yongpeng Yang
2026-02-27 19:23       ` Jaegeuk Kim via Linux-f2fs-devel
2026-02-27 20:41         ` Jaegeuk Kim via Linux-f2fs-devel
2026-03-06  9:15           ` Yongpeng Yang
2026-03-19  3:38           ` Yongpeng Yang
2026-02-03 13:37 ` [f2fs-dev] [PATCH 4/4] f2fs: fix inline data not being written to disk in writeback path Yongpeng Yang
2026-03-04  9:30   ` Chao Yu via Linux-f2fs-devel
2026-03-06  8:55     ` Yongpeng Yang
2026-03-04  9:13 ` [f2fs-dev] [PATCH 1/4] f2fs: fix incorrect extent flag when physical addr is NEW_ADDR in f2fs_fiemap Chao Yu via Linux-f2fs-devel
2026-03-06  9:18   ` Yongpeng Yang
2026-03-05 19:10 ` patchwork-bot+f2fs--- via Linux-f2fs-devel

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.