[PATCH] f2fs: skip clean inode update during fsync

Wenjie Qi posted 1 patch 1 week, 4 days ago
fs/f2fs/f2fs.h | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
[PATCH] f2fs: skip clean inode update during fsync
Posted by Wenjie Qi 1 week, 4 days ago
f2fs_do_sync_file() calls f2fs_skip_inode_update() before deciding
whether it has to write an inode block and continue into the recovery
info/flush path.

For a full fsync, f2fs_skip_inode_update() currently returns false when
FI_AUTO_RECOVER is not set.  That makes fsync on an already clean file
call f2fs_write_inode().  f2fs_write_inode() then returns immediately if
the in-memory timestamps match the inode block and FI_DIRTY_INODE is not
set, but f2fs_do_sync_file() still continues through go_write and may end
at f2fs_issue_flush().

Avoid that unnecessary path for clean, time-consistent inodes without
FI_AUTO_RECOVER.  Keep the existing conservative checks for keep-size
files and non-block-aligned i_size before allowing the skip, and leave the
FI_AUTO_RECOVER path unchanged.

On a QEMU/KASAN test VM, repeated fsync() on an existing clean F2FS file
improved from about 35.7 us/fsync to about 1.13 us/fsync.  The baseline
issued one flush per fsync, while the patched kernel kept the F2FS flush
count unchanged over 140000 clean fsync calls.

Signed-off-by: Wenjie Qi <qiwenjie@xiaomi.com>
---
 fs/f2fs/f2fs.h | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 9f24287de4c3..ebd485abecb4 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -3668,11 +3668,13 @@ static inline bool f2fs_skip_inode_update(struct inode *inode, int dsync)
 		spin_unlock(&sbi->inode_lock[DIRTY_META]);
 		return ret;
 	}
-	if (!is_inode_flag_set(inode, FI_AUTO_RECOVER) ||
-			file_keep_isize(inode) ||
-			i_size_read(inode) & ~PAGE_MASK)
+	if (file_keep_isize(inode) || i_size_read(inode) & ~PAGE_MASK)
 		return false;
 
+	if (!is_inode_flag_set(inode, FI_AUTO_RECOVER))
+		return f2fs_is_time_consistent(inode) &&
+			!is_inode_flag_set(inode, FI_DIRTY_INODE);
+
 	if (!f2fs_is_time_consistent(inode))
 		return false;
 
-- 
2.43.0