summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonrad Sztyber <ksztyber@nvidia.com>2026-04-14 11:27:23 +0300
committerMiklos Szeredi <mszeredi@redhat.com>2026-06-15 15:06:18 +0300
commitfde04c3d6f2bbc5c8fe25c99fd640f57e1e80d10 (patch)
treee954dc53393f7b7d578505ba32ab2fdbaeeae8f0
parent8c72b1f0e2a284f6c775789a7a52f772a1052d3e (diff)
downloadlinux-fde04c3d6f2bbc5c8fe25c99fd640f57e1e80d10.tar.xz
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 <ksztyber@nvidia.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
-rw-r--r--fs/fuse/dir.c2
-rw-r--r--fs/fuse/fuse_i.h3
2 files changed, 4 insertions, 1 deletions
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);