Right now we determine if filesystem support vfs idmappings or not basing on the FS_ALLOW_IDMAP flag presence. This "static" way works perfecly well for local filesystems like ext4, xfs, btrfs, etc. But for network-like filesystems like fuse, cephfs this approach is not ideal, because sometimes proper support of vfs idmaps requires some extensions for the on-wire protocol, which implies that changes have to be made not only in the Linux kernel code but also in the 3rd party components like libfuse, cephfs MDS server and so on. We have seen that issue during our work on cephfs idmapped mounts [1] with Christian, but right now I'm working on the idmapped mounts support for fuse and I think that it is a right time for this extension. [1] 5ccd8530dd7 ("ceph: handle idmapped mounts in create_request_message()") Cc: Christian Brauner <brauner@xxxxxxxxxx> Cc: Seth Forshee <sforshee@xxxxxxxxxx> Cc: Miklos Szeredi <miklos@xxxxxxxxxx> Cc: Amir Goldstein <amir73il@xxxxxxxxx> Cc: Bernd Schubert <bschubert@xxxxxxx> Cc: <linux-fsdevel@xxxxxxxxxxxxxxx> Signed-off-by: Alexander Mikhalitsyn <aleksandr.mikhalitsyn@xxxxxxxxxxxxx> --- fs/namespace.c | 3 ++- include/linux/fs.h | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/fs/namespace.c b/fs/namespace.c index fbf0e596fcd3..02eb47b3d728 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -4300,7 +4300,8 @@ static int can_idmap_mount(const struct mount_kattr *kattr, struct mount *mnt) return -EPERM; /* The underlying filesystem doesn't support idmapped mounts yet. */ - if (!(m->mnt_sb->s_type->fs_flags & FS_ALLOW_IDMAP)) + if (!(m->mnt_sb->s_type->fs_flags & FS_ALLOW_IDMAP) || + (m->mnt_sb->s_type->allow_idmap && !m->mnt_sb->s_type->allow_idmap(m->mnt_sb))) return -EINVAL; /* We're not controlling the superblock. */ diff --git a/include/linux/fs.h b/include/linux/fs.h index 98b7a7a8c42e..f2e373b5420a 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2377,6 +2377,7 @@ struct file_system_type { #define FS_RENAME_DOES_D_MOVE 32768 /* FS will handle d_move() during rename() internally. */ int (*init_fs_context)(struct fs_context *); const struct fs_parameter_spec *parameters; + bool (*allow_idmap)(struct super_block *); struct dentry *(*mount) (struct file_system_type *, int, const char *, void *); void (*kill_sb) (struct super_block *); -- 2.34.1