Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

f2fs: fix inline data not being written to disk in writeback path

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.

Cc: stable@kernel.org
Fixes: 9ffe0fb5f3bb ("f2fs: handle inline data operations")
Signed-off-by: Yongpeng Yang <yangyongpeng@xiaomi.com>
Reviewed-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>

authored by

Yongpeng Yang and committed by
Jaegeuk Kim
fe9b8b30 c3e238bd

+12 -1
+2
fs/f2fs/f2fs.h
··· 3946 3946 enum node_type ntype, bool in_irq); 3947 3947 struct folio *f2fs_get_inode_folio(struct f2fs_sb_info *sbi, pgoff_t ino); 3948 3948 struct folio *f2fs_get_xnode_folio(struct f2fs_sb_info *sbi, pgoff_t xnid); 3949 + int f2fs_write_single_node_folio(struct folio *node_folio, int sync_mode, 3950 + bool mark_dirty, enum iostat_type io_type); 3949 3951 int f2fs_move_node_folio(struct folio *node_folio, int gc_type); 3950 3952 void f2fs_flush_inline_data(struct f2fs_sb_info *sbi); 3951 3953 int f2fs_fsync_node_pages(struct f2fs_sb_info *sbi, struct inode *inode,
+9
fs/f2fs/inline.c
··· 814 814 goto out; 815 815 } 816 816 817 + if (fieinfo->fi_flags & FIEMAP_FLAG_SYNC) { 818 + err = f2fs_write_single_node_folio(ifolio, true, false, FS_NODE_IO); 819 + if (err) 820 + return err; 821 + ifolio = f2fs_get_inode_folio(F2FS_I_SB(inode), inode->i_ino); 822 + if (IS_ERR(ifolio)) 823 + return PTR_ERR(ifolio); 824 + f2fs_folio_wait_writeback(ifolio, NODE, true, true); 825 + } 817 826 ilen = min_t(size_t, MAX_INLINE_DATA(inode), i_size_read(inode)); 818 827 if (start >= ilen) 819 828 goto out;
+1 -1
fs/f2fs/node.c
··· 1843 1843 return false; 1844 1844 } 1845 1845 1846 - static int f2fs_write_single_node_folio(struct folio *node_folio, int sync_mode, 1846 + int f2fs_write_single_node_folio(struct folio *node_folio, int sync_mode, 1847 1847 bool mark_dirty, enum iostat_type io_type) 1848 1848 { 1849 1849 int err = 0;