From: Darrick J. Wong <djwong@xxxxxxxxxx> Provide a new mount option so that fuse servers can actually set the root nodeid. Signed-off-by: "Darrick J. Wong" <djwong@xxxxxxxxxx> --- fs/fuse/fuse_i.h | 2 ++ fs/fuse/inode.c | 11 +++++++++++ 2 files changed, 13 insertions(+) diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 66cf8dcf9216e7..a81138da1e55f6 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -601,6 +601,7 @@ struct fuse_fs_context { int fd; struct file *file; unsigned int rootmode; + u64 root_nodeid; kuid_t user_id; kgid_t group_id; bool is_bdev:1; @@ -614,6 +615,7 @@ struct fuse_fs_context { bool no_control:1; bool no_force_umount:1; bool legacy_opts_show:1; + bool root_nodeid_present:1; enum fuse_dax_mode dax_mode; unsigned int max_read; unsigned int blksize; diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index f2d519c0f737e6..18dc9492d19174 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -785,6 +785,7 @@ enum { OPT_ALLOW_OTHER, OPT_MAX_READ, OPT_BLKSIZE, + OPT_ROOT_NODEID, OPT_ERR }; @@ -799,6 +800,7 @@ static const struct fs_parameter_spec fuse_fs_parameters[] = { fsparam_u32 ("max_read", OPT_MAX_READ), fsparam_u32 ("blksize", OPT_BLKSIZE), fsparam_string ("subtype", OPT_SUBTYPE), + fsparam_u64 ("root_nodeid", OPT_ROOT_NODEID), {} }; @@ -894,6 +896,11 @@ static int fuse_parse_param(struct fs_context *fsc, struct fs_parameter *param) ctx->blksize = result.uint_32; break; + case OPT_ROOT_NODEID: + ctx->root_nodeid = result.uint_64; + ctx->root_nodeid_present = true; + break; + default: return -EINVAL; } @@ -929,6 +936,8 @@ static int fuse_show_options(struct seq_file *m, struct dentry *root) seq_printf(m, ",max_read=%u", fc->max_read); if (sb->s_bdev && sb->s_blocksize != FUSE_DEFAULT_BLKSIZE) seq_printf(m, ",blksize=%lu", sb->s_blocksize); + if (fc->root_nodeid && fc->root_nodeid != FUSE_ROOT_ID) + seq_printf(m, ",root_nodeid=%llu", fc->root_nodeid); } #ifdef CONFIG_FUSE_DAX if (fc->dax_mode == FUSE_DAX_ALWAYS) @@ -1879,6 +1888,8 @@ int fuse_fill_super_common(struct super_block *sb, struct fuse_fs_context *ctx) sb->s_flags |= SB_POSIXACL; fc->default_permissions = ctx->default_permissions; + if (ctx->root_nodeid_present) + fc->root_nodeid = ctx->root_nodeid; fc->allow_other = ctx->allow_other; fc->user_id = ctx->user_id; fc->group_id = ctx->group_id;