]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
f2fs: fix to round down start offset of fallocate for pin file
authorSunmin Jeong <s_min.jeong@samsung.com>
Mon, 22 Jun 2026 05:28:17 +0000 (14:28 +0900)
committerJaegeuk Kim <jaegeuk@kernel.org>
Mon, 22 Jun 2026 19:55:27 +0000 (19:55 +0000)
Currently, the length of fallocate for pin file is section-aligned to
keep allocated sections from being selected as victims of GC. However,
for the case that the start offset of fallocate is not aligned in
section, the allocated sections can't be fully utilized. It's because a
new section is allocated by f2fs_allocate_pinning_section() after using
blks_per_sec blocks regardless of the start offset. As a result, several
unexpected dirty segments may be created, including blocks assigned to
the pinned file.

To address this issue, let's round down the start offset of fallocate
to the length of section.

The reproducing scenario is as below

chunk=$(((2<<20)+4096)) # 2MB + 4KB
touch test
f2fs_io pinfile set test
f2fs_io fallocate 0 0 $chunk test
f2fs_io fallocate 0 $chunk $chunk test
f2fs_io fallocate 0 $((chunk*2)) $chunk test
f2fs_io fiemap 0 $((chunk*3)) test

Fiemap: offset = 0 len = 12288
    logical addr.    physical addr.   length           flags
0   0000000000000000 000000068c600000 0000000000400000 00001088
1   0000000000400000 000000003d400000 0000000000001000 00001088
2   0000000000401000 00000003eb200000 0000000000200000 00001088
3   0000000000601000 00000005e4200000 0000000000001000 00001088
4   0000000000602000 0000000605400000 0000000000200000 00001089

Cc: stable@vger.kernel.org
Fixes: f5a53edcf01e ("f2fs: support aligned pinned file")
Reviewed-by: Yunji Kang <yunji0.kang@samsung.com>
Reviewed-by: Yeongjin Gil <youngjin.gil@samsung.com>
Reviewed-by: Sungjong Seo <sj1557.seo@samsung.com>
Signed-off-by: Sunmin Jeong <s_min.jeong@samsung.com>
Reviewed-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
fs/f2fs/file.c

index 8acdd94272a0ced448e0ba21635d702cfec10682..4b52c56d71f07f57676a6c21add6c948d57db4d0 100644 (file)
@@ -1916,8 +1916,15 @@ static int f2fs_expand_inode_data(struct inode *inode, loff_t offset,
 
        if (f2fs_is_pinned_file(inode)) {
                block_t sec_blks = CAP_BLKS_PER_SEC(sbi);
-               block_t sec_len = roundup(map.m_len, sec_blks);
+               block_t sec_len;
 
+               if (map.m_lblk % sec_blks) {
+                       map.m_lblk = rounddown(map.m_lblk, sec_blks);
+                       map.m_len = pg_end - map.m_lblk;
+                       if (off_end)
+                               map.m_len++;
+               }
+               sec_len = roundup(map.m_len, sec_blks);
                map.m_len = sec_blks;
 next_alloc:
                f2fs_down_write(&sbi->pin_sem);