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>
This commit is contained in:
Konrad Sztyber 2026-04-14 10:27:23 +02:00 committed by Miklos Szeredi
parent 8c72b1f0e2
commit fde04c3d6f
2 changed files with 4 additions and 1 deletions

View File

@ -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);
}

View File

@ -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);