From: Hungyu Lin <dennylin0707@gmail.com>
To: jaegeuk@kernel.org, chao@kernel.org
Cc: daehojeong@google.com, linux-f2fs-devel@lists.sourceforge.net,
linux-kernel@vger.kernel.org, stable@vger.kernel.org,
Hungyu Lin <dennylin0707@gmail.com>
Subject: [PATCH] f2fs: read atomic replacements through the COW inode
Date: Wed, 4 Nov 2026 19:16:21 +0000 [thread overview]
Message-ID: <20261104191621.89561-1-dennylin0707@gmail.com> (raw)
Starting an atomic replacement drops the page cache and resets i_size,
but keeps the original block mappings so the operation can be aborted.
After a sparse write extends the replacement, buffered reads still use
those original mappings for the skipped range and cache the old data.
Commit removes the old gap mappings, but the cached data remains visible
even after reopening the file. A subsequent partial write to the gap can
write those stale bytes back to disk.
Resolve buffered reads through the COW inode during atomic replacement,
so unwritten ranges are read as holes. Keep using the original inode for
the read bio and its encryption context. Once FI_ATOMIC_COMMITTED is set,
use the newly committed original mappings again.
Hold the mapping invalidate lock while committing or aborting the atomic
write to serialize these mapping transitions with buffered-read faults
and readahead.
Fixes: 41e8f85a75fc ("f2fs: introduce F2FS_IOC_START_ATOMIC_REPLACE")
Cc: stable@vger.kernel.org
Signed-off-by: Hungyu Lin <dennylin0707@gmail.com>
---
fs/f2fs/data.c | 8 +++++++-
fs/f2fs/segment.c | 6 ++++++
2 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c
index 28fd8afff5d..89c4de3640d 100644
--- a/fs/f2fs/data.c
+++ b/fs/f2fs/data.c
@@ -2489,7 +2489,13 @@ static int f2fs_read_single_page(struct inode *inode, struct fsverity_info *vi,
map->m_lblk = block_in_file;
map->m_len = last_block - block_in_file;
- ret = f2fs_map_blocks(inode, map, F2FS_GET_BLOCK_DEFAULT);
+ /* Original blocks are kept for rollback, not for replacement reads. */
+ if (is_inode_flag_set(inode, FI_ATOMIC_REPLACE) &&
+ !is_inode_flag_set(inode, FI_ATOMIC_COMMITTED))
+ ret = f2fs_map_blocks(F2FS_I(inode)->cow_inode, map,
+ F2FS_GET_BLOCK_DEFAULT);
+ else
+ ret = f2fs_map_blocks(inode, map, F2FS_GET_BLOCK_DEFAULT);
if (ret)
goto out;
got_it:
diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c
index 43f40071576..f45b5ad78fc 100644
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -193,6 +193,8 @@ void f2fs_abort_atomic_write(struct inode *inode, bool clean)
if (!f2fs_is_atomic_file(inode))
return;
+ filemap_invalidate_lock(inode->i_mapping);
+
if (clean)
truncate_inode_pages(inode->i_mapping, 0);
@@ -218,6 +220,8 @@ void f2fs_abort_atomic_write(struct inode *inode, bool clean)
f2fs_i_size_write(inode, fi->original_i_size);
fi->original_i_size = 0;
}
+ filemap_invalidate_unlock(inode->i_mapping);
+
/* avoid stale dirty inode during eviction */
sync_inode_metadata(inode, 0);
}
@@ -409,11 +413,13 @@ int f2fs_commit_atomic_write(struct inode *inode)
return err;
f2fs_down_write(&fi->i_gc_rwsem[WRITE]);
+ filemap_invalidate_lock(inode->i_mapping);
f2fs_lock_op(sbi, &lc);
err = __f2fs_commit_atomic_write(inode);
f2fs_unlock_op(sbi, &lc);
+ filemap_invalidate_unlock(inode->i_mapping);
f2fs_up_write(&fi->i_gc_rwsem[WRITE]);
return err;
base-commit: 05441d697f7f9a927264f4058cbbc6a03dfcac9d
--
2.50.1 (Apple Git-155)
reply other threads:[~2026-11-04 19:16 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20261104191621.89561-1-dennylin0707@gmail.com \
--to=dennylin0707@gmail.com \
--cc=chao@kernel.org \
--cc=daehojeong@google.com \
--cc=jaegeuk@kernel.org \
--cc=linux-f2fs-devel@lists.sourceforge.net \
--cc=linux-kernel@vger.kernel.org \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®