We don't enable SB_NOSEC on fuse filesystems thinking filesystem is shared and files attrs setuid/setgid/capabilities can change without fuse knowing about it. This means on every WRITE, file_remove_privs(), is called and that calls into fuse server to figure out if security.capability xattr has been set on file. Most of the time this is a performance hog, specially for small writes done at high frequency. Enable SB_NOSEC if fuse filesystem sets flag FS_NONSHARED_FS. This means, do not expect file attrs/xattrs to change without the knowledge of fuse. In this case it should be possible to enable SB_NOSEC. For the case of shared filesystems, we will have to come up with a different mechanism to enable SB_NOSEC. I guess it will depend on invalidation mechanisms implemented by filesystem and cache coherency guarantees. I do clear inode S_NOSEC flag whenever file attrs are being refreshed. So this still honors attr timeout protocol. Signed-off-by: Vivek Goyal <vgoyal@xxxxxxxxxx> --- fs/fuse/inode.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 088faa3e352c..2da13fe25417 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -187,6 +187,9 @@ void fuse_change_attributes_common(struct inode *inode, struct fuse_attr *attr, inode->i_mode &= ~S_ISVTX; fi->orig_ino = attr->ino; + + /* Clear S_NOSEC whenever cached attrs are being refreshed */ + inode->i_flags &= ~S_NOSEC; } void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr, @@ -967,6 +970,9 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_args *args, } if (arg->flags & FUSE_NONSHARED_FS) { fc->nonshared_fs = 1; + down_write(&fc->sb->s_umount); + fc->sb->s_flags |= SB_NOSEC; + up_write(&fc->sb->s_umount); } } else { ra_pages = fc->max_read / PAGE_SIZE; -- 2.25.4