[Devel] [PATCH RHEL9 COMMIT] fs/fuse: invalidate file attrs when it is necessary

Konstantin Khorenko khorenko at virtuozzo.com
Thu Jan 23 20:40:17 MSK 2025


The commit is pushed to "branch-rh9-5.14.0-427.44.1.vz9.80.x-ovz" and will appear at git at bitbucket.org:openvz/vzkernel.git
after rh9-5.14.0-427.44.1.vz9.80.4
------>
commit 24e8397e7edf2ae8657e2863e5d7bbaca921006d
Author: Alexey Kuznetsov <kuznet at virtuozzo.com>
Date:   Sat Jan 18 02:08:41 2025 +0800

    fs/fuse: invalidate file attrs when it is necessary
    
    The patch is executed only for vstorage (close wait condition), to be safe.
    No doubts the same problem exists for mainstream, but we do not care
    and leave it alone.
    Note: we do not mean such attributes as st_size and st_mtime - they are
    handled entirely in kernel side for write cached files, it is rather
    about st_blocks.
    
    When doing direct writes attributes are invalidated on each write,
    but this invalidation is missing for cached writes, so that user
    does not see increase in st_blocks after write.
    
    We add it to two places: after fsync - this is definitely
    necessary for vstorage raid files even in O_DIRECT mode
    because fsync changes space allocation. And after completion
    of write_page.
    Mainstream added such invalidation but skipped it for write_cache files
    by some obscure reasons explained in long commit comment, which is just
    a bullshit: indeed if we mean update mtime/size, it is noop for
    write_cache files, but st_blocks still needs invalidation.
    So, just leave non-vstorage alone.
    
    Signed-off-by: Alexey Kuznetsov <kuznet at virtuozzo.com>
    
    Feature: vStorage
---
 fs/fuse/file.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index 6a89f9642325..2112dcf2fa0a 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -776,6 +776,9 @@ static int fuse_fsync(struct file *file, loff_t start, loff_t end,
 		fc->no_fsync = 1;
 		err = 0;
 	}
+	/* vstorage changes i_blocks on fsync, so we have to invalidate. */
+	if (fc->close_wait)
+		fuse_invalidate_attr(inode);
 	return err;
 out:
 	inode_unlock(inode);
@@ -2139,7 +2142,7 @@ static void fuse_writepage_end(struct fuse_mount *fm, struct fuse_args *args,
 	 * Do this only if writeback_cache is not enabled.  If writeback_cache
 	 * is enabled, we trust local ctime/mtime.
 	 */
-	if (!fc->writeback_cache)
+	if (!fc->writeback_cache || fc->close_wait)
 		fuse_invalidate_attr(inode);
 	spin_lock(&fi->lock);
 	rb_erase(&wpa->writepages_entry, &fi->writepages);


More information about the Devel mailing list