Skip to content

Commit

Permalink
anolis: fuse: add a mount option to set fs magic value
Browse files Browse the repository at this point in the history
ANBZ: torvalds#377

Add a mount option to allow backend daemon set fs magic value.

Applications identify file system type by fsmgic listed in 'linux/magic.h'.
All FUSE-Based filesystems return the value 'FUSE_SUPER_MAGIC' regardless
of huge difference between them.

By the time this patch is applied, a mechanism is provided that front-end
applications could distinguish different FUSE-Based user-space filesystems
by traditional statfs(2) and make use of their respective advantages.

One practical scenario is Alibaba Cloud's Database file System(DBFS) which
is FUSE-based and supports multiple types of storage engines. Transfer
unique fs magic for each engine to front-end enables applications to select
appropriate instance for different model. For example, MyFS engine with
magic number 'alibaba::dbfs::MYFS_SUPER_MAGIC' is suitable for oltp while
LFS engine with 'alibaba::dbfs::LFS_SUPER_MAGIC' benefit olap.

FUSE-Based filesystem uses this option should deal with conflicts with
values defined in 'linux/magic.h' and other FUSE-Based filesystems.

Signed-off-by: sanyulh <[email protected]>
Reviewed-by: Joseph Qi <[email protected]>
Reviewed-by: Gao Xiang <[email protected]>
Reviewed-by: Jeffle Xu <[email protected]>
  • Loading branch information
sanyulh authored and josephhz committed Feb 9, 2022
1 parent b4c22e6 commit 4a0229c
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 4 deletions.
7 changes: 7 additions & 0 deletions fs/fuse/fuse_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ struct fuse_mount_data {
enum fuse_dax_mode dax_mode;
unsigned max_read;
unsigned blksize;
unsigned long fs_magic;

/* DAX device, may be NULL */
struct dax_device *dax_dev;
Expand Down Expand Up @@ -626,6 +627,9 @@ struct fuse_conn {
/** The user namespace for this mount */
struct user_namespace *user_ns;

/** The fs super magic for this mount */
unsigned long fs_magic;

/** Maximum read size */
unsigned max_read;

Expand Down Expand Up @@ -812,6 +816,9 @@ struct fuse_conn {
/* Does the filesystem support per-file DAX? */
unsigned int perfile_dax:1;

/* Does the filesystem has its own magic? */
unsigned int conn_fs_magic:1;

/** The number of requests waiting for completion */
atomic_t num_waiting;

Expand Down
39 changes: 35 additions & 4 deletions fs/fuse/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -415,9 +415,10 @@ static void fuse_put_super(struct super_block *sb)
fuse_conn_put(fc);
}

static void convert_fuse_statfs(struct kstatfs *stbuf, struct fuse_kstatfs *attr)
static void convert_fuse_statfs(struct fuse_conn *fc, struct kstatfs *stbuf,
struct fuse_kstatfs *attr)
{
stbuf->f_type = FUSE_SUPER_MAGIC;
stbuf->f_type = fc->conn_fs_magic ? fc->fs_magic : FUSE_SUPER_MAGIC;
stbuf->f_bsize = attr->bsize;
stbuf->f_frsize = attr->frsize;
stbuf->f_blocks = attr->blocks;
Expand All @@ -438,7 +439,7 @@ static int fuse_statfs(struct dentry *dentry, struct kstatfs *buf)
int err;

if (!fuse_allow_current_process(fc)) {
buf->f_type = FUSE_SUPER_MAGIC;
buf->f_type = fc->conn_fs_magic ? fc->fs_magic : FUSE_SUPER_MAGIC;
return 0;
}

Expand All @@ -451,7 +452,7 @@ static int fuse_statfs(struct dentry *dentry, struct kstatfs *buf)
args.out.args[0].value = &outarg;
err = fuse_simple_request(fc, &args);
if (!err)
convert_fuse_statfs(buf, &outarg.st);
convert_fuse_statfs(fc, buf, &outarg.st);
return err;
}

Expand All @@ -465,6 +466,7 @@ enum {
OPT_ALLOW_OTHER,
OPT_MAX_READ,
OPT_BLKSIZE,
OPT_FS_MAGIC,
OPT_DAX,
OPT_DAX_ALWAYS,
OPT_DAX_NEVER,
Expand All @@ -482,13 +484,27 @@ static const match_table_t tokens = {
{OPT_ALLOW_OTHER, "allow_other"},
{OPT_MAX_READ, "max_read=%u"},
{OPT_BLKSIZE, "blksize=%u"},
{OPT_FS_MAGIC, "fs_magic=%u"},
{OPT_DAX, "dax"},
{OPT_DAX_ALWAYS, "dax=always"},
{OPT_DAX_NEVER, "dax=never"},
{OPT_DAX_INODE, "dax=inode"},
{OPT_ERR, NULL}
};

static int fuse_match_ul(substring_t *s, unsigned long *res)
{
char *buf;
int err = -ENOMEM;

buf = match_strdup(s);
if (buf) {
err = kstrtoul(buf, 0, res);
kfree(buf);
}
return err;
}

static int fuse_match_uint(substring_t *s, unsigned int *res)
{
int err = -ENOMEM;
Expand All @@ -507,6 +523,7 @@ int parse_fuse_opt(char *opt, struct fuse_mount_data *d, int is_bdev,
memset(d, 0, sizeof(struct fuse_mount_data));
d->max_read = ~0;
d->blksize = FUSE_DEFAULT_BLKSIZE;
d->fs_magic = FUSE_SUPER_MAGIC;

if (is_virtiofs) {
d->rootmode = S_IFDIR;
Expand All @@ -518,6 +535,7 @@ int parse_fuse_opt(char *opt, struct fuse_mount_data *d, int is_bdev,
int token;
int value;
unsigned uv;
unsigned long ulv;
substring_t args[MAX_OPT_ARGS];
if (!*p)
continue;
Expand Down Expand Up @@ -583,6 +601,12 @@ int parse_fuse_opt(char *opt, struct fuse_mount_data *d, int is_bdev,
d->blksize = value;
break;

case OPT_FS_MAGIC:
if (fuse_match_ul(&args[0], &ulv))
return 0;
d->fs_magic = ulv;
break;

case OPT_DAX:
case OPT_DAX_ALWAYS:
d->dax_mode = FUSE_DAX_ALWAYS;
Expand Down Expand Up @@ -628,6 +652,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->conn_fs_magic)
seq_printf(m, ",fsmagic=%lu", fc->fs_magic);
#ifdef CONFIG_FUSE_DAX
if (fc->dax_mode == FUSE_DAX_ALWAYS)
seq_puts(m, ",dax=always");
Expand Down Expand Up @@ -693,6 +719,7 @@ void fuse_conn_init(struct fuse_conn *fc, struct user_namespace *user_ns,
fc->user_ns = get_user_ns(user_ns);
fc->max_pages = FUSE_DEFAULT_MAX_PAGES_PER_REQ;
fc->max_pages_limit = FUSE_MAX_MAX_PAGES;
fc->conn_fs_magic = 0;
}
EXPORT_SYMBOL_GPL(fuse_conn_init);

Expand Down Expand Up @@ -1254,6 +1281,10 @@ int fuse_fill_super_common(struct super_block *sb,
fc->group_id = mount_data->group_id;
fc->max_read = max_t(unsigned, 4096, mount_data->max_read);

fc->fs_magic = mount_data->fs_magic;
if (fc->fs_magic != FUSE_SUPER_MAGIC)
fc->conn_fs_magic = 1;

/* Used by get_root_inode() */
sb->s_fs_info = fc;

Expand Down

0 comments on commit 4a0229c

Please sign in to comment.