* [f2fs-dev] [PATCH v4 1/2] f2fs: fix to off-by-one issue in f2fs_zero_post_eof_page()
@ 2026-08-09 1:19 ` Chao Yu
0 siblings, 0 replies; 8+ messages in thread
From: Chao Yu via Linux-f2fs-devel @ 2026-08-09 1:19 UTC (permalink / raw)
To: jaegeuk; +Cc: stable, linux-kernel, linux-f2fs-devel
Otherwise, it will drop one more page after new_size which is not
necessary.
Cc: stable@kernel.org
Fixes: ba8dac350faf ("f2fs: fix to zero post-eof page")
Signed-off-by: Chao Yu <chao@kernel.org>
---
v4:
- no changes
fs/f2fs/file.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index b99d9cdf9ba7..be319a2e9830 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -50,7 +50,7 @@ static void f2fs_zero_post_eof_page(struct inode *inode,
if (lock)
filemap_invalidate_lock(inode->i_mapping);
/* zero or drop pages only in range of [old_size, new_size] */
- truncate_inode_pages_range(inode->i_mapping, old_size, new_size);
+ truncate_inode_pages_range(inode->i_mapping, old_size, new_size - 1);
if (lock)
filemap_invalidate_unlock(inode->i_mapping);
}
--
2.49.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] 8+ messages in thread
* [PATCH v4 1/2] f2fs: fix to off-by-one issue in f2fs_zero_post_eof_page()
@ 2026-08-09 1:19 ` Chao Yu
0 siblings, 0 replies; 8+ messages in thread
From: Chao Yu @ 2026-08-09 1:19 UTC (permalink / raw)
To: jaegeuk; +Cc: linux-f2fs-devel, linux-kernel, Chao Yu, stable
Otherwise, it will drop one more page after new_size which is not
necessary.
Cc: stable@kernel.org
Fixes: ba8dac350faf ("f2fs: fix to zero post-eof page")
Signed-off-by: Chao Yu <chao@kernel.org>
---
v4:
- no changes
fs/f2fs/file.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index b99d9cdf9ba7..be319a2e9830 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -50,7 +50,7 @@ static void f2fs_zero_post_eof_page(struct inode *inode,
if (lock)
filemap_invalidate_lock(inode->i_mapping);
/* zero or drop pages only in range of [old_size, new_size] */
- truncate_inode_pages_range(inode->i_mapping, old_size, new_size);
+ truncate_inode_pages_range(inode->i_mapping, old_size, new_size - 1);
if (lock)
filemap_invalidate_unlock(inode->i_mapping);
}
--
2.49.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [f2fs-dev] [PATCH v4 2/2] f2fs: fix to zero post-EOF data when extending file size
2026-08-09 1:19 ` Chao Yu
@ 2026-08-09 1:19 ` Chao Yu
-1 siblings, 0 replies; 8+ messages in thread
From: Chao Yu via Linux-f2fs-devel @ 2026-08-09 1:19 UTC (permalink / raw)
To: jaegeuk; +Cc: stable, linux-kernel, linux-f2fs-devel
generic/794 4s ... - output mismatch (see /share/git/fstests/results//generic/794.out.bad)
--- tests/generic/794.out 2026-06-12 08:46:32.766426241 +0800
+++ /share/git/fstests/results//generic/794.out.bad 2026-07-05 18:32:55.000000000 +0800
@@ -1,4 +1,16 @@
QA output created by 794
append_write
+FAIL: non-zero data in gap [4080,4096) after shutdown+remount
+000000 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a >ZZZZZZZZZZZZZZZZ<
+*
+001000
truncate_up
...
(Run 'diff -u /share/git/fstests/tests/generic/794.out /share/git/fstests/results//generic/794.out.bad' to see the entire diff)
Ran: generic/794
Failures: generic/794
Failed 1 of 1 tests
Steps of generic/794:
1. write 4096 bytes to file w/ 0x5a
2. use fiemap to get PBA of first block in file
3. truncate file to 4080
4. umount; write 4096 bytes to file w/ 0x5a directly via PBA; mount
5. extend filesize via
a) append 4096 from offset 4096, or
b) truncate 8192, or
c) fallocate 4096 from offset 4096
6. verify the gap is zeroed in memory [4080,4096)
7. sync range 4096 from offset 4096; shutdown -f (flush meta before shutdown)
8. umount; mount; verify [4080,4096) is zeroed or not.
When extending file size (e.g. via truncate, fallocate, or write) across an
unaligned EOF boundary, we need to ensure that post-EOF data in the partial
page is zeroed out in pagecache and marked dirty, meanwhile, tagging the inode
with FI_ZERO_POST_EOF, so that following checkpoint() and fsync() can persist
the page contain zeroed data before committing inode w/ updated i_size.
This help to prevent stale disk data beyond the previous EOF from being exposed
after remounting or crash recovery.
Since f2fs is a LFS filesystem, we only support direct write via PBA in pinfile,
and pinfile has section-aligned filesize, so in Android, there should no problem,
but for other usage in different environment, let's fix this w/ fsync_mode=strict
mount option.
Cc: stable@kernel.org
Signed-off-by: Chao Yu <chao@kernel.org>
---
v4:
- fix to receive return value of f2fs_zero_post_eof_page() w/ @err rather than
@ret in f2fs_vm_page_mkwrite().
fs/f2fs/file.c | 100 +++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 84 insertions(+), 16 deletions(-)
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index be319a2e9830..446d2328f975 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -36,16 +36,52 @@
#include <trace/events/f2fs.h>
#include <uapi/linux/f2fs.h>
-static void f2fs_zero_post_eof_page(struct inode *inode,
- loff_t new_size, bool lock)
+static int fill_zero(struct inode *inode, pgoff_t index,
+ loff_t start, loff_t len);
+
+static int do_zero_post_eof_page(struct inode *inode, loff_t new_size)
+{
+ loff_t old_size = i_size_read(inode);
+ unsigned int offset, len;
+ pgoff_t index;
+ int err;
+
+ offset = old_size & (PAGE_SIZE - 1);
+
+ if (!offset)
+ return 0;
+
+ len = min_t(loff_t, PAGE_SIZE - offset, new_size - old_size);
+ index = old_size >> PAGE_SHIFT;
+
+ if (f2fs_has_inline_data(inode)) {
+ /* data post eof should be always zero */
+ if (new_size <= MAX_INLINE_DATA(inode))
+ return 0;
+ err = f2fs_convert_inline_inode(inode);
+ if (err)
+ return err;
+ }
+
+ err = fill_zero(inode, index, offset, len);
+ if (err)
+ return err;
+ return filemap_write_and_wait_range(inode->i_mapping,
+ old_size, old_size + len - 1);
+}
+
+static int f2fs_zero_post_eof_page(struct inode *inode,
+ loff_t new_size, bool lock, bool writeback)
{
loff_t old_size = i_size_read(inode);
+ bool strict =
+ F2FS_OPTION(F2FS_I_SB(inode)).fsync_mode == FSYNC_MODE_STRICT;
if (old_size >= new_size)
- return;
+ return 0;
- if (mapping_empty(inode->i_mapping))
- return;
+ if (!strict && mapping_empty(inode->i_mapping))
+ return 0;
if (lock)
filemap_invalidate_lock(inode->i_mapping);
@@ -53,6 +89,16 @@ static void f2fs_zero_post_eof_page(struct inode *inode,
truncate_inode_pages_range(inode->i_mapping, old_size, new_size - 1);
if (lock)
filemap_invalidate_unlock(inode->i_mapping);
+
+ if (!writeback || !strict)
+ return 0;
+ /*
+ * In fsync_mode=strict, when we expand an unaligned EOF size, we
+ * should zero post EOF data and writeback the data immediately,
+ * so that it can avoid exposing stale data after metadata flush
+ * and POR.
+ */
+ return do_zero_post_eof_page(inode, new_size);
}
static vm_fault_t f2fs_filemap_fault(struct vm_fault *vmf)
@@ -132,7 +178,10 @@ static vm_fault_t f2fs_vm_page_mkwrite(struct vm_fault *vmf)
f2fs_bug_on(sbi, f2fs_has_inline_data(inode));
- f2fs_zero_post_eof_page(inode, (folio->index + 1) << PAGE_SHIFT, true);
+ err = f2fs_zero_post_eof_page(inode,
+ (folio->index + 1) << PAGE_SHIFT, true, false);
+ if (err)
+ goto out_pagefault;
file_update_time(vmf->vma->vm_file);
filemap_invalidate_lock_shared(inode->i_mapping);
@@ -189,7 +238,7 @@ static vm_fault_t f2fs_vm_page_mkwrite(struct vm_fault *vmf)
out_sem:
filemap_invalidate_unlock_shared(inode->i_mapping);
-
+out_pagefault:
sb_end_pagefault(inode->i_sb);
out:
ret = vmf_fs_error(err);
@@ -1175,8 +1224,12 @@ int f2fs_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
f2fs_down_write(&fi->i_gc_rwsem[WRITE]);
filemap_invalidate_lock(inode->i_mapping);
- if (attr->ia_size > old_size)
- f2fs_zero_post_eof_page(inode, attr->ia_size, false);
+ if (attr->ia_size > old_size) {
+ err = f2fs_zero_post_eof_page(inode,
+ attr->ia_size, false, true);
+ if (err)
+ goto err_out;
+ }
truncate_setsize(inode, attr->ia_size);
if (attr->ia_size <= old_size)
@@ -1185,6 +1238,7 @@ int f2fs_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
* do not trim all blocks after i_size if target size is
* larger than i_size.
*/
+err_out:
filemap_invalidate_unlock(inode->i_mapping);
f2fs_up_write(&fi->i_gc_rwsem[WRITE]);
if (err)
@@ -1296,7 +1350,9 @@ static int f2fs_punch_hole(struct inode *inode, loff_t offset, loff_t len)
if (ret)
return ret;
- f2fs_zero_post_eof_page(inode, offset + len, true);
+ ret = f2fs_zero_post_eof_page(inode, offset + len, true, false);
+ if (ret)
+ return ret;
pg_start = ((unsigned long long) offset) >> PAGE_SHIFT;
pg_end = ((unsigned long long) offset + len) >> PAGE_SHIFT;
@@ -1583,7 +1639,9 @@ static int f2fs_do_collapse(struct inode *inode, loff_t offset, loff_t len)
f2fs_down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
filemap_invalidate_lock(inode->i_mapping);
- f2fs_zero_post_eof_page(inode, offset + len, false);
+ ret = f2fs_zero_post_eof_page(inode, offset + len, false, false);
+ if (ret)
+ goto out_unlock;
f2fs_lock_op(sbi, &lc);
f2fs_drop_extent_tree(inode);
@@ -1591,6 +1649,7 @@ static int f2fs_do_collapse(struct inode *inode, loff_t offset, loff_t len)
ret = __exchange_data_block(inode, inode, end, start, nrpages - end, true);
f2fs_unlock_op(sbi, &lc);
+out_unlock:
filemap_invalidate_unlock(inode->i_mapping);
f2fs_up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
return ret;
@@ -1712,7 +1771,9 @@ static int f2fs_zero_range(struct inode *inode, loff_t offset, loff_t len,
if (ret)
return ret;
- f2fs_zero_post_eof_page(inode, offset + len, true);
+ ret = f2fs_zero_post_eof_page(inode, offset + len, true, false);
+ if (ret)
+ return ret;
pg_start = ((unsigned long long) offset) >> PAGE_SHIFT;
pg_end = ((unsigned long long) offset + len) >> PAGE_SHIFT;
@@ -1847,7 +1908,9 @@ static int f2fs_insert_range(struct inode *inode, loff_t offset, loff_t len)
f2fs_down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
filemap_invalidate_lock(mapping);
- f2fs_zero_post_eof_page(inode, offset + len, false);
+ ret = f2fs_zero_post_eof_page(inode, offset + len, false, false);
+ if (ret)
+ goto out_unlock;
truncate_pagecache(inode, offset);
while (!ret && idx > pg_start) {
@@ -1865,6 +1928,7 @@ static int f2fs_insert_range(struct inode *inode, loff_t offset, loff_t len)
idx + delta, nr, false);
f2fs_unlock_op(sbi, &lc);
}
+out_unlock:
filemap_invalidate_unlock(mapping);
f2fs_up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
if (ret)
@@ -1907,7 +1971,9 @@ static int f2fs_expand_inode_data(struct inode *inode, loff_t offset,
if (err)
return err;
- f2fs_zero_post_eof_page(inode, offset + len, true);
+ err = f2fs_zero_post_eof_page(inode, offset + len, true, true);
+ if (err)
+ return err;
f2fs_balance_fs(sbi, true);
@@ -5023,8 +5089,10 @@ static ssize_t f2fs_write_checks(struct kiocb *iocb, struct iov_iter *from)
if (err)
return err;
- f2fs_zero_post_eof_page(inode,
- iocb->ki_pos + iov_iter_count(from), true);
+ err = f2fs_zero_post_eof_page(inode,
+ iocb->ki_pos + iov_iter_count(from), true, true);
+ if (err)
+ return err;
return count;
}
--
2.49.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] 8+ messages in thread
* [PATCH v4 2/2] f2fs: fix to zero post-EOF data when extending file size
@ 2026-08-09 1:19 ` Chao Yu
0 siblings, 0 replies; 8+ messages in thread
From: Chao Yu @ 2026-08-09 1:19 UTC (permalink / raw)
To: jaegeuk; +Cc: linux-f2fs-devel, linux-kernel, Chao Yu, stable
generic/794 4s ... - output mismatch (see /share/git/fstests/results//generic/794.out.bad)
--- tests/generic/794.out 2026-06-12 08:46:32.766426241 +0800
+++ /share/git/fstests/results//generic/794.out.bad 2026-07-05 18:32:55.000000000 +0800
@@ -1,4 +1,16 @@
QA output created by 794
append_write
+FAIL: non-zero data in gap [4080,4096) after shutdown+remount
+000000 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a >ZZZZZZZZZZZZZZZZ<
+*
+001000
truncate_up
...
(Run 'diff -u /share/git/fstests/tests/generic/794.out /share/git/fstests/results//generic/794.out.bad' to see the entire diff)
Ran: generic/794
Failures: generic/794
Failed 1 of 1 tests
Steps of generic/794:
1. write 4096 bytes to file w/ 0x5a
2. use fiemap to get PBA of first block in file
3. truncate file to 4080
4. umount; write 4096 bytes to file w/ 0x5a directly via PBA; mount
5. extend filesize via
a) append 4096 from offset 4096, or
b) truncate 8192, or
c) fallocate 4096 from offset 4096
6. verify the gap is zeroed in memory [4080,4096)
7. sync range 4096 from offset 4096; shutdown -f (flush meta before shutdown)
8. umount; mount; verify [4080,4096) is zeroed or not.
When extending file size (e.g. via truncate, fallocate, or write) across an
unaligned EOF boundary, we need to ensure that post-EOF data in the partial
page is zeroed out in pagecache and marked dirty, meanwhile, tagging the inode
with FI_ZERO_POST_EOF, so that following checkpoint() and fsync() can persist
the page contain zeroed data before committing inode w/ updated i_size.
This help to prevent stale disk data beyond the previous EOF from being exposed
after remounting or crash recovery.
Since f2fs is a LFS filesystem, we only support direct write via PBA in pinfile,
and pinfile has section-aligned filesize, so in Android, there should no problem,
but for other usage in different environment, let's fix this w/ fsync_mode=strict
mount option.
Cc: stable@kernel.org
Signed-off-by: Chao Yu <chao@kernel.org>
---
v4:
- fix to receive return value of f2fs_zero_post_eof_page() w/ @err rather than
@ret in f2fs_vm_page_mkwrite().
fs/f2fs/file.c | 100 +++++++++++++++++++++++++++++++++++++++++--------
1 file changed, 84 insertions(+), 16 deletions(-)
diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index be319a2e9830..446d2328f975 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -36,16 +36,52 @@
#include <trace/events/f2fs.h>
#include <uapi/linux/f2fs.h>
-static void f2fs_zero_post_eof_page(struct inode *inode,
- loff_t new_size, bool lock)
+static int fill_zero(struct inode *inode, pgoff_t index,
+ loff_t start, loff_t len);
+
+static int do_zero_post_eof_page(struct inode *inode, loff_t new_size)
+{
+ loff_t old_size = i_size_read(inode);
+ unsigned int offset, len;
+ pgoff_t index;
+ int err;
+
+ offset = old_size & (PAGE_SIZE - 1);
+
+ if (!offset)
+ return 0;
+
+ len = min_t(loff_t, PAGE_SIZE - offset, new_size - old_size);
+ index = old_size >> PAGE_SHIFT;
+
+ if (f2fs_has_inline_data(inode)) {
+ /* data post eof should be always zero */
+ if (new_size <= MAX_INLINE_DATA(inode))
+ return 0;
+ err = f2fs_convert_inline_inode(inode);
+ if (err)
+ return err;
+ }
+
+ err = fill_zero(inode, index, offset, len);
+ if (err)
+ return err;
+ return filemap_write_and_wait_range(inode->i_mapping,
+ old_size, old_size + len - 1);
+}
+
+static int f2fs_zero_post_eof_page(struct inode *inode,
+ loff_t new_size, bool lock, bool writeback)
{
loff_t old_size = i_size_read(inode);
+ bool strict =
+ F2FS_OPTION(F2FS_I_SB(inode)).fsync_mode == FSYNC_MODE_STRICT;
if (old_size >= new_size)
- return;
+ return 0;
- if (mapping_empty(inode->i_mapping))
- return;
+ if (!strict && mapping_empty(inode->i_mapping))
+ return 0;
if (lock)
filemap_invalidate_lock(inode->i_mapping);
@@ -53,6 +89,16 @@ static void f2fs_zero_post_eof_page(struct inode *inode,
truncate_inode_pages_range(inode->i_mapping, old_size, new_size - 1);
if (lock)
filemap_invalidate_unlock(inode->i_mapping);
+
+ if (!writeback || !strict)
+ return 0;
+ /*
+ * In fsync_mode=strict, when we expand an unaligned EOF size, we
+ * should zero post EOF data and writeback the data immediately,
+ * so that it can avoid exposing stale data after metadata flush
+ * and POR.
+ */
+ return do_zero_post_eof_page(inode, new_size);
}
static vm_fault_t f2fs_filemap_fault(struct vm_fault *vmf)
@@ -132,7 +178,10 @@ static vm_fault_t f2fs_vm_page_mkwrite(struct vm_fault *vmf)
f2fs_bug_on(sbi, f2fs_has_inline_data(inode));
- f2fs_zero_post_eof_page(inode, (folio->index + 1) << PAGE_SHIFT, true);
+ err = f2fs_zero_post_eof_page(inode,
+ (folio->index + 1) << PAGE_SHIFT, true, false);
+ if (err)
+ goto out_pagefault;
file_update_time(vmf->vma->vm_file);
filemap_invalidate_lock_shared(inode->i_mapping);
@@ -189,7 +238,7 @@ static vm_fault_t f2fs_vm_page_mkwrite(struct vm_fault *vmf)
out_sem:
filemap_invalidate_unlock_shared(inode->i_mapping);
-
+out_pagefault:
sb_end_pagefault(inode->i_sb);
out:
ret = vmf_fs_error(err);
@@ -1175,8 +1224,12 @@ int f2fs_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
f2fs_down_write(&fi->i_gc_rwsem[WRITE]);
filemap_invalidate_lock(inode->i_mapping);
- if (attr->ia_size > old_size)
- f2fs_zero_post_eof_page(inode, attr->ia_size, false);
+ if (attr->ia_size > old_size) {
+ err = f2fs_zero_post_eof_page(inode,
+ attr->ia_size, false, true);
+ if (err)
+ goto err_out;
+ }
truncate_setsize(inode, attr->ia_size);
if (attr->ia_size <= old_size)
@@ -1185,6 +1238,7 @@ int f2fs_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
* do not trim all blocks after i_size if target size is
* larger than i_size.
*/
+err_out:
filemap_invalidate_unlock(inode->i_mapping);
f2fs_up_write(&fi->i_gc_rwsem[WRITE]);
if (err)
@@ -1296,7 +1350,9 @@ static int f2fs_punch_hole(struct inode *inode, loff_t offset, loff_t len)
if (ret)
return ret;
- f2fs_zero_post_eof_page(inode, offset + len, true);
+ ret = f2fs_zero_post_eof_page(inode, offset + len, true, false);
+ if (ret)
+ return ret;
pg_start = ((unsigned long long) offset) >> PAGE_SHIFT;
pg_end = ((unsigned long long) offset + len) >> PAGE_SHIFT;
@@ -1583,7 +1639,9 @@ static int f2fs_do_collapse(struct inode *inode, loff_t offset, loff_t len)
f2fs_down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
filemap_invalidate_lock(inode->i_mapping);
- f2fs_zero_post_eof_page(inode, offset + len, false);
+ ret = f2fs_zero_post_eof_page(inode, offset + len, false, false);
+ if (ret)
+ goto out_unlock;
f2fs_lock_op(sbi, &lc);
f2fs_drop_extent_tree(inode);
@@ -1591,6 +1649,7 @@ static int f2fs_do_collapse(struct inode *inode, loff_t offset, loff_t len)
ret = __exchange_data_block(inode, inode, end, start, nrpages - end, true);
f2fs_unlock_op(sbi, &lc);
+out_unlock:
filemap_invalidate_unlock(inode->i_mapping);
f2fs_up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
return ret;
@@ -1712,7 +1771,9 @@ static int f2fs_zero_range(struct inode *inode, loff_t offset, loff_t len,
if (ret)
return ret;
- f2fs_zero_post_eof_page(inode, offset + len, true);
+ ret = f2fs_zero_post_eof_page(inode, offset + len, true, false);
+ if (ret)
+ return ret;
pg_start = ((unsigned long long) offset) >> PAGE_SHIFT;
pg_end = ((unsigned long long) offset + len) >> PAGE_SHIFT;
@@ -1847,7 +1908,9 @@ static int f2fs_insert_range(struct inode *inode, loff_t offset, loff_t len)
f2fs_down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
filemap_invalidate_lock(mapping);
- f2fs_zero_post_eof_page(inode, offset + len, false);
+ ret = f2fs_zero_post_eof_page(inode, offset + len, false, false);
+ if (ret)
+ goto out_unlock;
truncate_pagecache(inode, offset);
while (!ret && idx > pg_start) {
@@ -1865,6 +1928,7 @@ static int f2fs_insert_range(struct inode *inode, loff_t offset, loff_t len)
idx + delta, nr, false);
f2fs_unlock_op(sbi, &lc);
}
+out_unlock:
filemap_invalidate_unlock(mapping);
f2fs_up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
if (ret)
@@ -1907,7 +1971,9 @@ static int f2fs_expand_inode_data(struct inode *inode, loff_t offset,
if (err)
return err;
- f2fs_zero_post_eof_page(inode, offset + len, true);
+ err = f2fs_zero_post_eof_page(inode, offset + len, true, true);
+ if (err)
+ return err;
f2fs_balance_fs(sbi, true);
@@ -5023,8 +5089,10 @@ static ssize_t f2fs_write_checks(struct kiocb *iocb, struct iov_iter *from)
if (err)
return err;
- f2fs_zero_post_eof_page(inode,
- iocb->ki_pos + iov_iter_count(from), true);
+ err = f2fs_zero_post_eof_page(inode,
+ iocb->ki_pos + iov_iter_count(from), true, true);
+ if (err)
+ return err;
return count;
}
--
2.49.0
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [f2fs-dev] [PATCH v4 2/2] f2fs: fix to zero post-EOF data when extending file size
2026-08-09 1:19 ` Chao Yu
@ 2026-08-10 8:52 ` Zhiguo Niu
-1 siblings, 0 replies; 8+ messages in thread
From: Zhiguo Niu @ 2026-08-10 8:52 UTC (permalink / raw)
To: Chao Yu; +Cc: jaegeuk, linux-f2fs-devel, stable, linux-kernel
Chao Yu via Linux-f2fs-devel <linux-f2fs-devel@lists.sourceforge.net>
于2026年8月9日周日 09:21写道:
>
> generic/794 4s ... - output mismatch (see /share/git/fstests/results//generic/794.out.bad)
> --- tests/generic/794.out 2026-06-12 08:46:32.766426241 +0800
> +++ /share/git/fstests/results//generic/794.out.bad 2026-07-05 18:32:55.000000000 +0800
> @@ -1,4 +1,16 @@
> QA output created by 794
> append_write
> +FAIL: non-zero data in gap [4080,4096) after shutdown+remount
> +000000 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a >ZZZZZZZZZZZZZZZZ<
> +*
> +001000
> truncate_up
> ...
> (Run 'diff -u /share/git/fstests/tests/generic/794.out /share/git/fstests/results//generic/794.out.bad' to see the entire diff)
> Ran: generic/794
> Failures: generic/794
> Failed 1 of 1 tests
>
> Steps of generic/794:
> 1. write 4096 bytes to file w/ 0x5a
> 2. use fiemap to get PBA of first block in file
> 3. truncate file to 4080
> 4. umount; write 4096 bytes to file w/ 0x5a directly via PBA; mount
> 5. extend filesize via
> a) append 4096 from offset 4096, or
> b) truncate 8192, or
> c) fallocate 4096 from offset 4096
> 6. verify the gap is zeroed in memory [4080,4096)
> 7. sync range 4096 from offset 4096; shutdown -f (flush meta before shutdown)
> 8. umount; mount; verify [4080,4096) is zeroed or not.
>
> When extending file size (e.g. via truncate, fallocate, or write) across an
> unaligned EOF boundary, we need to ensure that post-EOF data in the partial
> page is zeroed out in pagecache and marked dirty, meanwhile, tagging the inode
> with FI_ZERO_POST_EOF, so that following checkpoint() and fsync() can persist
Hi Chao,
It looks like this version doesn't have this flag "FI_ZERO_POST_EOF"?
thanks!
> the page contain zeroed data before committing inode w/ updated i_size.
>
> This help to prevent stale disk data beyond the previous EOF from being exposed
> after remounting or crash recovery.
>
> Since f2fs is a LFS filesystem, we only support direct write via PBA in pinfile,
> and pinfile has section-aligned filesize, so in Android, there should no problem,
> but for other usage in different environment, let's fix this w/ fsync_mode=strict
> mount option.
>
> Cc: stable@kernel.org
> Signed-off-by: Chao Yu <chao@kernel.org>
> ---
> v4:
> - fix to receive return value of f2fs_zero_post_eof_page() w/ @err rather than
> @ret in f2fs_vm_page_mkwrite().
> fs/f2fs/file.c | 100 +++++++++++++++++++++++++++++++++++++++++--------
> 1 file changed, 84 insertions(+), 16 deletions(-)
>
> diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
> index be319a2e9830..446d2328f975 100644
> --- a/fs/f2fs/file.c
> +++ b/fs/f2fs/file.c
> @@ -36,16 +36,52 @@
> #include <trace/events/f2fs.h>
> #include <uapi/linux/f2fs.h>
>
> -static void f2fs_zero_post_eof_page(struct inode *inode,
> - loff_t new_size, bool lock)
> +static int fill_zero(struct inode *inode, pgoff_t index,
> + loff_t start, loff_t len);
> +
> +static int do_zero_post_eof_page(struct inode *inode, loff_t new_size)
> +{
> + loff_t old_size = i_size_read(inode);
> + unsigned int offset, len;
> + pgoff_t index;
> + int err;
> +
> + offset = old_size & (PAGE_SIZE - 1);
> +
> + if (!offset)
> + return 0;
> +
> + len = min_t(loff_t, PAGE_SIZE - offset, new_size - old_size);
> + index = old_size >> PAGE_SHIFT;
> +
> + if (f2fs_has_inline_data(inode)) {
> + /* data post eof should be always zero */
> + if (new_size <= MAX_INLINE_DATA(inode))
> + return 0;
> + err = f2fs_convert_inline_inode(inode);
> + if (err)
> + return err;
> + }
> +
> + err = fill_zero(inode, index, offset, len);
> + if (err)
> + return err;
> + return filemap_write_and_wait_range(inode->i_mapping,
> + old_size, old_size + len - 1);
> +}
> +
> +static int f2fs_zero_post_eof_page(struct inode *inode,
> + loff_t new_size, bool lock, bool writeback)
> {
> loff_t old_size = i_size_read(inode);
> + bool strict =
> + F2FS_OPTION(F2FS_I_SB(inode)).fsync_mode == FSYNC_MODE_STRICT;
>
> if (old_size >= new_size)
> - return;
> + return 0;
>
> - if (mapping_empty(inode->i_mapping))
> - return;
> + if (!strict && mapping_empty(inode->i_mapping))
> + return 0;
>
> if (lock)
> filemap_invalidate_lock(inode->i_mapping);
> @@ -53,6 +89,16 @@ static void f2fs_zero_post_eof_page(struct inode *inode,
> truncate_inode_pages_range(inode->i_mapping, old_size, new_size - 1);
> if (lock)
> filemap_invalidate_unlock(inode->i_mapping);
> +
> + if (!writeback || !strict)
> + return 0;
> + /*
> + * In fsync_mode=strict, when we expand an unaligned EOF size, we
> + * should zero post EOF data and writeback the data immediately,
> + * so that it can avoid exposing stale data after metadata flush
> + * and POR.
> + */
> + return do_zero_post_eof_page(inode, new_size);
> }
>
> static vm_fault_t f2fs_filemap_fault(struct vm_fault *vmf)
> @@ -132,7 +178,10 @@ static vm_fault_t f2fs_vm_page_mkwrite(struct vm_fault *vmf)
>
> f2fs_bug_on(sbi, f2fs_has_inline_data(inode));
>
> - f2fs_zero_post_eof_page(inode, (folio->index + 1) << PAGE_SHIFT, true);
> + err = f2fs_zero_post_eof_page(inode,
> + (folio->index + 1) << PAGE_SHIFT, true, false);
> + if (err)
> + goto out_pagefault;
>
> file_update_time(vmf->vma->vm_file);
> filemap_invalidate_lock_shared(inode->i_mapping);
> @@ -189,7 +238,7 @@ static vm_fault_t f2fs_vm_page_mkwrite(struct vm_fault *vmf)
>
> out_sem:
> filemap_invalidate_unlock_shared(inode->i_mapping);
> -
> +out_pagefault:
> sb_end_pagefault(inode->i_sb);
> out:
> ret = vmf_fs_error(err);
> @@ -1175,8 +1224,12 @@ int f2fs_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
> f2fs_down_write(&fi->i_gc_rwsem[WRITE]);
> filemap_invalidate_lock(inode->i_mapping);
>
> - if (attr->ia_size > old_size)
> - f2fs_zero_post_eof_page(inode, attr->ia_size, false);
> + if (attr->ia_size > old_size) {
> + err = f2fs_zero_post_eof_page(inode,
> + attr->ia_size, false, true);
> + if (err)
> + goto err_out;
> + }
> truncate_setsize(inode, attr->ia_size);
>
> if (attr->ia_size <= old_size)
> @@ -1185,6 +1238,7 @@ int f2fs_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
> * do not trim all blocks after i_size if target size is
> * larger than i_size.
> */
> +err_out:
> filemap_invalidate_unlock(inode->i_mapping);
> f2fs_up_write(&fi->i_gc_rwsem[WRITE]);
> if (err)
> @@ -1296,7 +1350,9 @@ static int f2fs_punch_hole(struct inode *inode, loff_t offset, loff_t len)
> if (ret)
> return ret;
>
> - f2fs_zero_post_eof_page(inode, offset + len, true);
> + ret = f2fs_zero_post_eof_page(inode, offset + len, true, false);
> + if (ret)
> + return ret;
>
> pg_start = ((unsigned long long) offset) >> PAGE_SHIFT;
> pg_end = ((unsigned long long) offset + len) >> PAGE_SHIFT;
> @@ -1583,7 +1639,9 @@ static int f2fs_do_collapse(struct inode *inode, loff_t offset, loff_t len)
> f2fs_down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
> filemap_invalidate_lock(inode->i_mapping);
>
> - f2fs_zero_post_eof_page(inode, offset + len, false);
> + ret = f2fs_zero_post_eof_page(inode, offset + len, false, false);
> + if (ret)
> + goto out_unlock;
>
> f2fs_lock_op(sbi, &lc);
> f2fs_drop_extent_tree(inode);
> @@ -1591,6 +1649,7 @@ static int f2fs_do_collapse(struct inode *inode, loff_t offset, loff_t len)
> ret = __exchange_data_block(inode, inode, end, start, nrpages - end, true);
> f2fs_unlock_op(sbi, &lc);
>
> +out_unlock:
> filemap_invalidate_unlock(inode->i_mapping);
> f2fs_up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
> return ret;
> @@ -1712,7 +1771,9 @@ static int f2fs_zero_range(struct inode *inode, loff_t offset, loff_t len,
> if (ret)
> return ret;
>
> - f2fs_zero_post_eof_page(inode, offset + len, true);
> + ret = f2fs_zero_post_eof_page(inode, offset + len, true, false);
> + if (ret)
> + return ret;
>
> pg_start = ((unsigned long long) offset) >> PAGE_SHIFT;
> pg_end = ((unsigned long long) offset + len) >> PAGE_SHIFT;
> @@ -1847,7 +1908,9 @@ static int f2fs_insert_range(struct inode *inode, loff_t offset, loff_t len)
> f2fs_down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
> filemap_invalidate_lock(mapping);
>
> - f2fs_zero_post_eof_page(inode, offset + len, false);
> + ret = f2fs_zero_post_eof_page(inode, offset + len, false, false);
> + if (ret)
> + goto out_unlock;
> truncate_pagecache(inode, offset);
>
> while (!ret && idx > pg_start) {
> @@ -1865,6 +1928,7 @@ static int f2fs_insert_range(struct inode *inode, loff_t offset, loff_t len)
> idx + delta, nr, false);
> f2fs_unlock_op(sbi, &lc);
> }
> +out_unlock:
> filemap_invalidate_unlock(mapping);
> f2fs_up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
> if (ret)
> @@ -1907,7 +1971,9 @@ static int f2fs_expand_inode_data(struct inode *inode, loff_t offset,
> if (err)
> return err;
>
> - f2fs_zero_post_eof_page(inode, offset + len, true);
> + err = f2fs_zero_post_eof_page(inode, offset + len, true, true);
> + if (err)
> + return err;
>
> f2fs_balance_fs(sbi, true);
>
> @@ -5023,8 +5089,10 @@ static ssize_t f2fs_write_checks(struct kiocb *iocb, struct iov_iter *from)
> if (err)
> return err;
>
> - f2fs_zero_post_eof_page(inode,
> - iocb->ki_pos + iov_iter_count(from), true);
> + err = f2fs_zero_post_eof_page(inode,
> + iocb->ki_pos + iov_iter_count(from), true, true);
> + if (err)
> + return err;
> return count;
> }
>
> --
> 2.49.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] 8+ messages in thread
* Re: [f2fs-dev] [PATCH v4 2/2] f2fs: fix to zero post-EOF data when extending file size
@ 2026-08-10 8:52 ` Zhiguo Niu
0 siblings, 0 replies; 8+ messages in thread
From: Zhiguo Niu @ 2026-08-10 8:52 UTC (permalink / raw)
To: Chao Yu; +Cc: jaegeuk, stable, linux-kernel, linux-f2fs-devel
Chao Yu via Linux-f2fs-devel <linux-f2fs-devel@lists.sourceforge.net>
于2026年8月9日周日 09:21写道:
>
> generic/794 4s ... - output mismatch (see /share/git/fstests/results//generic/794.out.bad)
> --- tests/generic/794.out 2026-06-12 08:46:32.766426241 +0800
> +++ /share/git/fstests/results//generic/794.out.bad 2026-07-05 18:32:55.000000000 +0800
> @@ -1,4 +1,16 @@
> QA output created by 794
> append_write
> +FAIL: non-zero data in gap [4080,4096) after shutdown+remount
> +000000 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a 5a >ZZZZZZZZZZZZZZZZ<
> +*
> +001000
> truncate_up
> ...
> (Run 'diff -u /share/git/fstests/tests/generic/794.out /share/git/fstests/results//generic/794.out.bad' to see the entire diff)
> Ran: generic/794
> Failures: generic/794
> Failed 1 of 1 tests
>
> Steps of generic/794:
> 1. write 4096 bytes to file w/ 0x5a
> 2. use fiemap to get PBA of first block in file
> 3. truncate file to 4080
> 4. umount; write 4096 bytes to file w/ 0x5a directly via PBA; mount
> 5. extend filesize via
> a) append 4096 from offset 4096, or
> b) truncate 8192, or
> c) fallocate 4096 from offset 4096
> 6. verify the gap is zeroed in memory [4080,4096)
> 7. sync range 4096 from offset 4096; shutdown -f (flush meta before shutdown)
> 8. umount; mount; verify [4080,4096) is zeroed or not.
>
> When extending file size (e.g. via truncate, fallocate, or write) across an
> unaligned EOF boundary, we need to ensure that post-EOF data in the partial
> page is zeroed out in pagecache and marked dirty, meanwhile, tagging the inode
> with FI_ZERO_POST_EOF, so that following checkpoint() and fsync() can persist
Hi Chao,
It looks like this version doesn't have this flag "FI_ZERO_POST_EOF"?
thanks!
> the page contain zeroed data before committing inode w/ updated i_size.
>
> This help to prevent stale disk data beyond the previous EOF from being exposed
> after remounting or crash recovery.
>
> Since f2fs is a LFS filesystem, we only support direct write via PBA in pinfile,
> and pinfile has section-aligned filesize, so in Android, there should no problem,
> but for other usage in different environment, let's fix this w/ fsync_mode=strict
> mount option.
>
> Cc: stable@kernel.org
> Signed-off-by: Chao Yu <chao@kernel.org>
> ---
> v4:
> - fix to receive return value of f2fs_zero_post_eof_page() w/ @err rather than
> @ret in f2fs_vm_page_mkwrite().
> fs/f2fs/file.c | 100 +++++++++++++++++++++++++++++++++++++++++--------
> 1 file changed, 84 insertions(+), 16 deletions(-)
>
> diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
> index be319a2e9830..446d2328f975 100644
> --- a/fs/f2fs/file.c
> +++ b/fs/f2fs/file.c
> @@ -36,16 +36,52 @@
> #include <trace/events/f2fs.h>
> #include <uapi/linux/f2fs.h>
>
> -static void f2fs_zero_post_eof_page(struct inode *inode,
> - loff_t new_size, bool lock)
> +static int fill_zero(struct inode *inode, pgoff_t index,
> + loff_t start, loff_t len);
> +
> +static int do_zero_post_eof_page(struct inode *inode, loff_t new_size)
> +{
> + loff_t old_size = i_size_read(inode);
> + unsigned int offset, len;
> + pgoff_t index;
> + int err;
> +
> + offset = old_size & (PAGE_SIZE - 1);
> +
> + if (!offset)
> + return 0;
> +
> + len = min_t(loff_t, PAGE_SIZE - offset, new_size - old_size);
> + index = old_size >> PAGE_SHIFT;
> +
> + if (f2fs_has_inline_data(inode)) {
> + /* data post eof should be always zero */
> + if (new_size <= MAX_INLINE_DATA(inode))
> + return 0;
> + err = f2fs_convert_inline_inode(inode);
> + if (err)
> + return err;
> + }
> +
> + err = fill_zero(inode, index, offset, len);
> + if (err)
> + return err;
> + return filemap_write_and_wait_range(inode->i_mapping,
> + old_size, old_size + len - 1);
> +}
> +
> +static int f2fs_zero_post_eof_page(struct inode *inode,
> + loff_t new_size, bool lock, bool writeback)
> {
> loff_t old_size = i_size_read(inode);
> + bool strict =
> + F2FS_OPTION(F2FS_I_SB(inode)).fsync_mode == FSYNC_MODE_STRICT;
>
> if (old_size >= new_size)
> - return;
> + return 0;
>
> - if (mapping_empty(inode->i_mapping))
> - return;
> + if (!strict && mapping_empty(inode->i_mapping))
> + return 0;
>
> if (lock)
> filemap_invalidate_lock(inode->i_mapping);
> @@ -53,6 +89,16 @@ static void f2fs_zero_post_eof_page(struct inode *inode,
> truncate_inode_pages_range(inode->i_mapping, old_size, new_size - 1);
> if (lock)
> filemap_invalidate_unlock(inode->i_mapping);
> +
> + if (!writeback || !strict)
> + return 0;
> + /*
> + * In fsync_mode=strict, when we expand an unaligned EOF size, we
> + * should zero post EOF data and writeback the data immediately,
> + * so that it can avoid exposing stale data after metadata flush
> + * and POR.
> + */
> + return do_zero_post_eof_page(inode, new_size);
> }
>
> static vm_fault_t f2fs_filemap_fault(struct vm_fault *vmf)
> @@ -132,7 +178,10 @@ static vm_fault_t f2fs_vm_page_mkwrite(struct vm_fault *vmf)
>
> f2fs_bug_on(sbi, f2fs_has_inline_data(inode));
>
> - f2fs_zero_post_eof_page(inode, (folio->index + 1) << PAGE_SHIFT, true);
> + err = f2fs_zero_post_eof_page(inode,
> + (folio->index + 1) << PAGE_SHIFT, true, false);
> + if (err)
> + goto out_pagefault;
>
> file_update_time(vmf->vma->vm_file);
> filemap_invalidate_lock_shared(inode->i_mapping);
> @@ -189,7 +238,7 @@ static vm_fault_t f2fs_vm_page_mkwrite(struct vm_fault *vmf)
>
> out_sem:
> filemap_invalidate_unlock_shared(inode->i_mapping);
> -
> +out_pagefault:
> sb_end_pagefault(inode->i_sb);
> out:
> ret = vmf_fs_error(err);
> @@ -1175,8 +1224,12 @@ int f2fs_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
> f2fs_down_write(&fi->i_gc_rwsem[WRITE]);
> filemap_invalidate_lock(inode->i_mapping);
>
> - if (attr->ia_size > old_size)
> - f2fs_zero_post_eof_page(inode, attr->ia_size, false);
> + if (attr->ia_size > old_size) {
> + err = f2fs_zero_post_eof_page(inode,
> + attr->ia_size, false, true);
> + if (err)
> + goto err_out;
> + }
> truncate_setsize(inode, attr->ia_size);
>
> if (attr->ia_size <= old_size)
> @@ -1185,6 +1238,7 @@ int f2fs_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
> * do not trim all blocks after i_size if target size is
> * larger than i_size.
> */
> +err_out:
> filemap_invalidate_unlock(inode->i_mapping);
> f2fs_up_write(&fi->i_gc_rwsem[WRITE]);
> if (err)
> @@ -1296,7 +1350,9 @@ static int f2fs_punch_hole(struct inode *inode, loff_t offset, loff_t len)
> if (ret)
> return ret;
>
> - f2fs_zero_post_eof_page(inode, offset + len, true);
> + ret = f2fs_zero_post_eof_page(inode, offset + len, true, false);
> + if (ret)
> + return ret;
>
> pg_start = ((unsigned long long) offset) >> PAGE_SHIFT;
> pg_end = ((unsigned long long) offset + len) >> PAGE_SHIFT;
> @@ -1583,7 +1639,9 @@ static int f2fs_do_collapse(struct inode *inode, loff_t offset, loff_t len)
> f2fs_down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
> filemap_invalidate_lock(inode->i_mapping);
>
> - f2fs_zero_post_eof_page(inode, offset + len, false);
> + ret = f2fs_zero_post_eof_page(inode, offset + len, false, false);
> + if (ret)
> + goto out_unlock;
>
> f2fs_lock_op(sbi, &lc);
> f2fs_drop_extent_tree(inode);
> @@ -1591,6 +1649,7 @@ static int f2fs_do_collapse(struct inode *inode, loff_t offset, loff_t len)
> ret = __exchange_data_block(inode, inode, end, start, nrpages - end, true);
> f2fs_unlock_op(sbi, &lc);
>
> +out_unlock:
> filemap_invalidate_unlock(inode->i_mapping);
> f2fs_up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
> return ret;
> @@ -1712,7 +1771,9 @@ static int f2fs_zero_range(struct inode *inode, loff_t offset, loff_t len,
> if (ret)
> return ret;
>
> - f2fs_zero_post_eof_page(inode, offset + len, true);
> + ret = f2fs_zero_post_eof_page(inode, offset + len, true, false);
> + if (ret)
> + return ret;
>
> pg_start = ((unsigned long long) offset) >> PAGE_SHIFT;
> pg_end = ((unsigned long long) offset + len) >> PAGE_SHIFT;
> @@ -1847,7 +1908,9 @@ static int f2fs_insert_range(struct inode *inode, loff_t offset, loff_t len)
> f2fs_down_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
> filemap_invalidate_lock(mapping);
>
> - f2fs_zero_post_eof_page(inode, offset + len, false);
> + ret = f2fs_zero_post_eof_page(inode, offset + len, false, false);
> + if (ret)
> + goto out_unlock;
> truncate_pagecache(inode, offset);
>
> while (!ret && idx > pg_start) {
> @@ -1865,6 +1928,7 @@ static int f2fs_insert_range(struct inode *inode, loff_t offset, loff_t len)
> idx + delta, nr, false);
> f2fs_unlock_op(sbi, &lc);
> }
> +out_unlock:
> filemap_invalidate_unlock(mapping);
> f2fs_up_write(&F2FS_I(inode)->i_gc_rwsem[WRITE]);
> if (ret)
> @@ -1907,7 +1971,9 @@ static int f2fs_expand_inode_data(struct inode *inode, loff_t offset,
> if (err)
> return err;
>
> - f2fs_zero_post_eof_page(inode, offset + len, true);
> + err = f2fs_zero_post_eof_page(inode, offset + len, true, true);
> + if (err)
> + return err;
>
> f2fs_balance_fs(sbi, true);
>
> @@ -5023,8 +5089,10 @@ static ssize_t f2fs_write_checks(struct kiocb *iocb, struct iov_iter *from)
> if (err)
> return err;
>
> - f2fs_zero_post_eof_page(inode,
> - iocb->ki_pos + iov_iter_count(from), true);
> + err = f2fs_zero_post_eof_page(inode,
> + iocb->ki_pos + iov_iter_count(from), true, true);
> + if (err)
> + return err;
> return count;
> }
>
> --
> 2.49.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] 8+ messages in thread
* Re: [f2fs-dev] [PATCH v4 2/2] f2fs: fix to zero post-EOF data when extending file size
2026-08-10 8:52 ` Zhiguo Niu
@ 2026-08-11 7:17 ` Chao Yu
-1 siblings, 0 replies; 8+ messages in thread
From: Chao Yu via Linux-f2fs-devel @ 2026-08-11 7:17 UTC (permalink / raw)
To: Zhiguo Niu; +Cc: jaegeuk, linux-f2fs-devel, stable, linux-kernel
On 8/10/26 16:52, Zhiguo Niu wrote:
> Chao Yu via Linux-f2fs-devel <linux-f2fs-devel@lists.sourceforge.net>
>> When extending file size (e.g. via truncate, fallocate, or write) across an
>> unaligned EOF boundary, we need to ensure that post-EOF data in the partial
>> page is zeroed out in pagecache and marked dirty, meanwhile, tagging the inode
>> with FI_ZERO_POST_EOF, so that following checkpoint() and fsync() can persist
> Hi Chao,
> It looks like this version doesn't have this flag "FI_ZERO_POST_EOF"?
Thanks for catching this, fixed in v5.
Thanks,
> 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] 8+ messages in thread
* Re: [f2fs-dev] [PATCH v4 2/2] f2fs: fix to zero post-EOF data when extending file size
@ 2026-08-11 7:17 ` Chao Yu
0 siblings, 0 replies; 8+ messages in thread
From: Chao Yu @ 2026-08-11 7:17 UTC (permalink / raw)
To: Zhiguo Niu; +Cc: chao, jaegeuk, stable, linux-kernel, linux-f2fs-devel
On 8/10/26 16:52, Zhiguo Niu wrote:
> Chao Yu via Linux-f2fs-devel <linux-f2fs-devel@lists.sourceforge.net>
>> When extending file size (e.g. via truncate, fallocate, or write) across an
>> unaligned EOF boundary, we need to ensure that post-EOF data in the partial
>> page is zeroed out in pagecache and marked dirty, meanwhile, tagging the inode
>> with FI_ZERO_POST_EOF, so that following checkpoint() and fsync() can persist
> Hi Chao,
> It looks like this version doesn't have this flag "FI_ZERO_POST_EOF"?
Thanks for catching this, fixed in v5.
Thanks,
> thanks!
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-08-11 7:17 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-09 1:19 [f2fs-dev] [PATCH v4 1/2] f2fs: fix to off-by-one issue in f2fs_zero_post_eof_page() Chao Yu via Linux-f2fs-devel
2026-08-09 1:19 ` Chao Yu
2026-08-09 1:19 ` [f2fs-dev] [PATCH v4 2/2] f2fs: fix to zero post-EOF data when extending file size Chao Yu via Linux-f2fs-devel
2026-08-09 1:19 ` Chao Yu
2026-08-10 8:52 ` [f2fs-dev] " Zhiguo Niu
2026-08-10 8:52 ` Zhiguo Niu
2026-08-11 7:17 ` Chao Yu via Linux-f2fs-devel
2026-08-11 7:17 ` Chao Yu
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.