[QUESTION] fuse: why invalidate all page cache in truncate()

From: Zhang Tianci
Date: Sun Jan 04 2026 - 01:51:29 EST


Hi all,

We have recently encountered a case where aria2c adopts the following
IO pattern when downloading files(We enabled writeback_cache option):

It allocates file space via fallocate. If fallocate is not supported,
it will circularly write 256KB of zero-filled data to the file until it reaches
an enough size, and then truncate the file to the desired size. Subsequently,
it fills non-zero data into the file through random writes.

This causes aria2c to run extremely slowly, which does not meet our
expectations,
because we have enabled writeback_cache, random writes should not be this slow.
After investigation, I found that a readpage operation is performed in every
write_begin callback. This is quite odd, as the file was just fully filled with
zeros via write operations; the file's page cache should all be uptodate,
so there is no need for a readpage. Upon further analysis, I discovered that the
root cause is that truncate has invalidated all the page cache.

I would like to know why the invalidation is performed. After checking the code
commit history, I found that this has been the implementation since FUSE added
support for the writeback cache mode.

Therefore, I can only seek help from the community: What were the
considerations
behind this implementation, and can it be removed?

--- a/fs/fuse/dir.c
+++ b/fs/fuse/dir.c
@@ -2279,7 +2279,6 @@ int fuse_do_setattr(struct mnt_idmap *idmap,
struct dentry *dentry,
        if ((is_truncate || !is_wb) &&
            S_ISREG(inode->i_mode) && oldsize != outarg.attr.size) {
                truncate_pagecache(inode, outarg.attr.size);
-               invalidate_inode_pages2(mapping);
        }

        clear_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);

Thanks,
Tianci