summaryrefslogtreecommitdiff
path: root/rust/kernel/gpu/git@git.tavy.me:linux-stable.git
diff options
context:
space:
mode:
authorDave Chen <davechen@synology.com>2026-03-23 11:43:22 +0800
committerDavid Sterba <dsterba@suse.com>2026-04-07 18:56:06 +0200
commit0e6a169c6487ca3a13d19a9ec6dc9673af5a1cf7 (patch)
treebe3aae87cf43b654c2ea6b4ac4ab04edc44d4b6e /rust/kernel/gpu/git@git.tavy.me:linux-stable.git
parent304076527c38efaf68a17f9e4837834ac66cfc1a (diff)
btrfs: fix unnecessary flush on close when truncating zero-sized files
In btrfs_setsize(), when a file is truncated to size 0, the BTRFS_INODE_FLUSH_ON_CLOSE flag is unconditionally set to ensure pending writes get flushed on close. This flag was designed to protect the "truncate-then-rewrite" pattern, where an application truncates a file with existing data down to zero and writes new content, ensuring the new data reach disk on close. However, when a file already has a size of 0 (e.g. a newly created file opened with O_CREAT | O_TRUNC), oldsize and newsize are both 0. In this case, setting BTRFS_INODE_FLUSH_ON_CLOSE is unnecessary because no "good data" was truncated away. The subsequent filemap_flush() in btrfs_release_file() then triggers avoidable writeback that disrupts the normal delayed writeback batching, adding I/O overhead. This comes from a real workload. A backup service creates temporary files via mkstemp(), closes them, and later reopens them with O_TRUNC for writing. The O_TRUNC is defensive. The file creation and usage is done by a different component, so removing the unneeded truncation is not straightforward. This pattern repeats for a large number of files each close() triggers an unnecessary filemap_flush(). Signed-off-by: Dave Chen <davechen@synology.com> Signed-off-by: Robbie Ko <robbieko@synology.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'rust/kernel/gpu/git@git.tavy.me:linux-stable.git')
0 files changed, 0 insertions, 0 deletions