From fde04c3d6f2bbc5c8fe25c99fd640f57e1e80d10 Mon Sep 17 00:00:00 2001 From: Konrad Sztyber Date: Tue, 14 Apr 2026 10:27:23 +0200 Subject: [PATCH] fuse: reduce attributes invalidated on directory change When the contents of a directory is modified, some of its attributes may also change, so they need to be invalidated. But this isn't the case for every attribute. For instance, unlinking or creating a file doesn't change the uid/gid of its parent directory. This can cause unnecessary FUSE_GETATTRs to be sent to user-space. For example, fuse_permission() checks if mode, uid, and gid are valid and will issue a FUSE_GETATTR if they're not, which results in an extra FUSE_GETATTR request for every FUSE_UNLINK when removing files in the same directory. Signed-off-by: Konrad Sztyber Signed-off-by: Miklos Szeredi --- fs/fuse/dir.c | 2 +- fs/fuse/fuse_i.h | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 2872e068c317..1b71fb5adc01 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -318,7 +318,7 @@ void fuse_invalidate_attr(struct inode *inode) static void fuse_dir_changed(struct inode *dir) { - fuse_invalidate_attr(dir); + fuse_invalidate_attr_mask(dir, FUSE_STATX_MODDIR); inode_maybe_inc_iversion(dir, false); } diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 93087fc04975..3a7ac74a23ed 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -1034,6 +1034,9 @@ void fuse_epoch_work(struct work_struct *work); /* Attributes possibly changed on data and/or size modification */ #define FUSE_STATX_MODSIZE (FUSE_STATX_MODIFY | STATX_SIZE) +/* Attributes possibly changed on directory modification */ +#define FUSE_STATX_MODDIR (FUSE_STATX_MODSIZE | STATX_NLINK) + void fuse_invalidate_attr(struct inode *inode); void fuse_invalidate_attr_mask(struct inode *inode, u32 mask);