Merge c9d35ee049
("Merge branch 'merge.nfs-fs_parse.1' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs") into android-mainline
Tiny steps to deal with merge issues in sdcardfs due to fs param passing api changes. Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: I03ba8763e8cc324c25fb6316c363b59957103474
This commit is contained in:
@@ -427,7 +427,6 @@ returned.
|
|||||||
fs_value_is_string, Value is a string
|
fs_value_is_string, Value is a string
|
||||||
fs_value_is_blob, Value is a binary blob
|
fs_value_is_blob, Value is a binary blob
|
||||||
fs_value_is_filename, Value is a filename* + dirfd
|
fs_value_is_filename, Value is a filename* + dirfd
|
||||||
fs_value_is_filename_empty, Value is a filename* + dirfd + AT_EMPTY_PATH
|
|
||||||
fs_value_is_file, Value is an open file (file*)
|
fs_value_is_file, Value is an open file (file*)
|
||||||
|
|
||||||
If there is a value, that value is stored in a union in the struct in one
|
If there is a value, that value is stored in a union in the struct in one
|
||||||
@@ -519,7 +518,6 @@ Parameters are described using structures defined in linux/fs_parser.h.
|
|||||||
There's a core description struct that links everything together:
|
There's a core description struct that links everything together:
|
||||||
|
|
||||||
struct fs_parameter_description {
|
struct fs_parameter_description {
|
||||||
const char name[16];
|
|
||||||
const struct fs_parameter_spec *specs;
|
const struct fs_parameter_spec *specs;
|
||||||
const struct fs_parameter_enum *enums;
|
const struct fs_parameter_enum *enums;
|
||||||
};
|
};
|
||||||
@@ -535,19 +533,13 @@ For example:
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const struct fs_parameter_description afs_fs_parameters = {
|
static const struct fs_parameter_description afs_fs_parameters = {
|
||||||
.name = "kAFS",
|
|
||||||
.specs = afs_param_specs,
|
.specs = afs_param_specs,
|
||||||
.enums = afs_param_enums,
|
.enums = afs_param_enums,
|
||||||
};
|
};
|
||||||
|
|
||||||
The members are as follows:
|
The members are as follows:
|
||||||
|
|
||||||
(1) const char name[16];
|
(1) const struct fs_parameter_specification *specs;
|
||||||
|
|
||||||
The name to be used in error messages generated by the parse helper
|
|
||||||
functions.
|
|
||||||
|
|
||||||
(2) const struct fs_parameter_specification *specs;
|
|
||||||
|
|
||||||
Table of parameter specifications, terminated with a null entry, where the
|
Table of parameter specifications, terminated with a null entry, where the
|
||||||
entries are of type:
|
entries are of type:
|
||||||
@@ -626,7 +618,7 @@ The members are as follows:
|
|||||||
of arguments to specify the type and the flags for anything that doesn't
|
of arguments to specify the type and the flags for anything that doesn't
|
||||||
match one of the above macros.
|
match one of the above macros.
|
||||||
|
|
||||||
(6) const struct fs_parameter_enum *enums;
|
(2) const struct fs_parameter_enum *enums;
|
||||||
|
|
||||||
Table of enum value names to integer mappings, terminated with a null
|
Table of enum value names to integer mappings, terminated with a null
|
||||||
entry. This is of type:
|
entry. This is of type:
|
||||||
|
@@ -583,7 +583,7 @@ enum {
|
|||||||
Opt_uid, Opt_gid, Opt_mode, Opt_debug,
|
Opt_uid, Opt_gid, Opt_mode, Opt_debug,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct fs_parameter_spec spufs_param_specs[] = {
|
static const struct fs_parameter_spec spufs_fs_parameters[] = {
|
||||||
fsparam_u32 ("gid", Opt_gid),
|
fsparam_u32 ("gid", Opt_gid),
|
||||||
fsparam_u32oct ("mode", Opt_mode),
|
fsparam_u32oct ("mode", Opt_mode),
|
||||||
fsparam_u32 ("uid", Opt_uid),
|
fsparam_u32 ("uid", Opt_uid),
|
||||||
@@ -591,11 +591,6 @@ static const struct fs_parameter_spec spufs_param_specs[] = {
|
|||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct fs_parameter_description spufs_fs_parameters = {
|
|
||||||
.name = "spufs",
|
|
||||||
.specs = spufs_param_specs,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int spufs_show_options(struct seq_file *m, struct dentry *root)
|
static int spufs_show_options(struct seq_file *m, struct dentry *root)
|
||||||
{
|
{
|
||||||
struct spufs_sb_info *sbi = spufs_get_sb_info(root->d_sb);
|
struct spufs_sb_info *sbi = spufs_get_sb_info(root->d_sb);
|
||||||
@@ -623,7 +618,7 @@ static int spufs_parse_param(struct fs_context *fc, struct fs_parameter *param)
|
|||||||
kgid_t gid;
|
kgid_t gid;
|
||||||
int opt;
|
int opt;
|
||||||
|
|
||||||
opt = fs_parse(fc, &spufs_fs_parameters, param, &result);
|
opt = fs_parse(fc, spufs_fs_parameters, param, &result);
|
||||||
if (opt < 0)
|
if (opt < 0)
|
||||||
return opt;
|
return opt;
|
||||||
|
|
||||||
@@ -774,7 +769,7 @@ static struct file_system_type spufs_type = {
|
|||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.name = "spufs",
|
.name = "spufs",
|
||||||
.init_fs_context = spufs_init_fs_context,
|
.init_fs_context = spufs_init_fs_context,
|
||||||
.parameters = &spufs_fs_parameters,
|
.parameters = spufs_fs_parameters,
|
||||||
.kill_sb = kill_litter_super,
|
.kill_sb = kill_litter_super,
|
||||||
};
|
};
|
||||||
MODULE_ALIAS_FS("spufs");
|
MODULE_ALIAS_FS("spufs");
|
||||||
|
@@ -209,17 +209,12 @@ static int hypfs_release(struct inode *inode, struct file *filp)
|
|||||||
|
|
||||||
enum { Opt_uid, Opt_gid, };
|
enum { Opt_uid, Opt_gid, };
|
||||||
|
|
||||||
static const struct fs_parameter_spec hypfs_param_specs[] = {
|
static const struct fs_parameter_spec hypfs_fs_parameters[] = {
|
||||||
fsparam_u32("gid", Opt_gid),
|
fsparam_u32("gid", Opt_gid),
|
||||||
fsparam_u32("uid", Opt_uid),
|
fsparam_u32("uid", Opt_uid),
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct fs_parameter_description hypfs_fs_parameters = {
|
|
||||||
.name = "hypfs",
|
|
||||||
.specs = hypfs_param_specs,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int hypfs_parse_param(struct fs_context *fc, struct fs_parameter *param)
|
static int hypfs_parse_param(struct fs_context *fc, struct fs_parameter *param)
|
||||||
{
|
{
|
||||||
struct hypfs_sb_info *hypfs_info = fc->s_fs_info;
|
struct hypfs_sb_info *hypfs_info = fc->s_fs_info;
|
||||||
@@ -228,7 +223,7 @@ static int hypfs_parse_param(struct fs_context *fc, struct fs_parameter *param)
|
|||||||
kgid_t gid;
|
kgid_t gid;
|
||||||
int opt;
|
int opt;
|
||||||
|
|
||||||
opt = fs_parse(fc, &hypfs_fs_parameters, param, &result);
|
opt = fs_parse(fc, hypfs_fs_parameters, param, &result);
|
||||||
if (opt < 0)
|
if (opt < 0)
|
||||||
return opt;
|
return opt;
|
||||||
|
|
||||||
@@ -455,7 +450,7 @@ static struct file_system_type hypfs_type = {
|
|||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.name = "s390_hypfs",
|
.name = "s390_hypfs",
|
||||||
.init_fs_context = hypfs_init_fs_context,
|
.init_fs_context = hypfs_init_fs_context,
|
||||||
.parameters = &hypfs_fs_parameters,
|
.parameters = hypfs_fs_parameters,
|
||||||
.kill_sb = hypfs_kill_super
|
.kill_sb = hypfs_kill_super
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -2127,25 +2127,20 @@ enum rdt_param {
|
|||||||
nr__rdt_params
|
nr__rdt_params
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct fs_parameter_spec rdt_param_specs[] = {
|
static const struct fs_parameter_spec rdt_fs_parameters[] = {
|
||||||
fsparam_flag("cdp", Opt_cdp),
|
fsparam_flag("cdp", Opt_cdp),
|
||||||
fsparam_flag("cdpl2", Opt_cdpl2),
|
fsparam_flag("cdpl2", Opt_cdpl2),
|
||||||
fsparam_flag("mba_MBps", Opt_mba_mbps),
|
fsparam_flag("mba_MBps", Opt_mba_mbps),
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct fs_parameter_description rdt_fs_parameters = {
|
|
||||||
.name = "rdt",
|
|
||||||
.specs = rdt_param_specs,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int rdt_parse_param(struct fs_context *fc, struct fs_parameter *param)
|
static int rdt_parse_param(struct fs_context *fc, struct fs_parameter *param)
|
||||||
{
|
{
|
||||||
struct rdt_fs_context *ctx = rdt_fc2context(fc);
|
struct rdt_fs_context *ctx = rdt_fc2context(fc);
|
||||||
struct fs_parse_result result;
|
struct fs_parse_result result;
|
||||||
int opt;
|
int opt;
|
||||||
|
|
||||||
opt = fs_parse(fc, &rdt_fs_parameters, param, &result);
|
opt = fs_parse(fc, rdt_fs_parameters, param, &result);
|
||||||
if (opt < 0)
|
if (opt < 0)
|
||||||
return opt;
|
return opt;
|
||||||
|
|
||||||
@@ -2378,7 +2373,7 @@ static void rdt_kill_sb(struct super_block *sb)
|
|||||||
static struct file_system_type rdt_fs_type = {
|
static struct file_system_type rdt_fs_type = {
|
||||||
.name = "resctrl",
|
.name = "resctrl",
|
||||||
.init_fs_context = rdt_init_fs_context,
|
.init_fs_context = rdt_init_fs_context,
|
||||||
.parameters = &rdt_fs_parameters,
|
.parameters = rdt_fs_parameters,
|
||||||
.kill_sb = rdt_kill_sb,
|
.kill_sb = rdt_kill_sb,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -67,10 +67,10 @@ static struct file_system_type internal_fs_type = {
|
|||||||
.name = "devtmpfs",
|
.name = "devtmpfs",
|
||||||
#ifdef CONFIG_TMPFS
|
#ifdef CONFIG_TMPFS
|
||||||
.init_fs_context = shmem_init_fs_context,
|
.init_fs_context = shmem_init_fs_context,
|
||||||
.parameters = &shmem_fs_parameters,
|
.parameters = shmem_fs_parameters,
|
||||||
#else
|
#else
|
||||||
.init_fs_context = ramfs_init_fs_context,
|
.init_fs_context = ramfs_init_fs_context,
|
||||||
.parameters = &ramfs_fs_parameters,
|
.parameters = ramfs_fs_parameters,
|
||||||
#endif
|
#endif
|
||||||
.kill_sb = kill_litter_super,
|
.kill_sb = kill_litter_super,
|
||||||
};
|
};
|
||||||
|
@@ -848,7 +848,7 @@ enum {
|
|||||||
Opt_notrim,
|
Opt_notrim,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct fs_parameter_spec rbd_param_specs[] = {
|
static const struct fs_parameter_spec rbd_parameters[] = {
|
||||||
fsparam_u32 ("alloc_size", Opt_alloc_size),
|
fsparam_u32 ("alloc_size", Opt_alloc_size),
|
||||||
fsparam_flag ("exclusive", Opt_exclusive),
|
fsparam_flag ("exclusive", Opt_exclusive),
|
||||||
fsparam_flag ("lock_on_read", Opt_lock_on_read),
|
fsparam_flag ("lock_on_read", Opt_lock_on_read),
|
||||||
@@ -863,11 +863,6 @@ static const struct fs_parameter_spec rbd_param_specs[] = {
|
|||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct fs_parameter_description rbd_parameters = {
|
|
||||||
.name = "rbd",
|
|
||||||
.specs = rbd_param_specs,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct rbd_options {
|
struct rbd_options {
|
||||||
int queue_depth;
|
int queue_depth;
|
||||||
int alloc_size;
|
int alloc_size;
|
||||||
@@ -6353,19 +6348,19 @@ static int rbd_parse_param(struct fs_parameter *param,
|
|||||||
{
|
{
|
||||||
struct rbd_options *opt = pctx->opts;
|
struct rbd_options *opt = pctx->opts;
|
||||||
struct fs_parse_result result;
|
struct fs_parse_result result;
|
||||||
|
struct p_log log = {.prefix = "rbd"};
|
||||||
int token, ret;
|
int token, ret;
|
||||||
|
|
||||||
ret = ceph_parse_param(param, pctx->copts, NULL);
|
ret = ceph_parse_param(param, pctx->copts, NULL);
|
||||||
if (ret != -ENOPARAM)
|
if (ret != -ENOPARAM)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
token = fs_parse(NULL, &rbd_parameters, param, &result);
|
token = __fs_parse(&log, rbd_parameters, param, &result);
|
||||||
dout("%s fs_parse '%s' token %d\n", __func__, param->key, token);
|
dout("%s fs_parse '%s' token %d\n", __func__, param->key, token);
|
||||||
if (token < 0) {
|
if (token < 0) {
|
||||||
if (token == -ENOPARAM) {
|
if (token == -ENOPARAM)
|
||||||
return invalf(NULL, "rbd: Unknown parameter '%s'",
|
return inval_plog(&log, "Unknown parameter '%s'",
|
||||||
param->key);
|
param->key);
|
||||||
}
|
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6378,9 +6373,8 @@ static int rbd_parse_param(struct fs_parameter *param,
|
|||||||
case Opt_alloc_size:
|
case Opt_alloc_size:
|
||||||
if (result.uint_32 < SECTOR_SIZE)
|
if (result.uint_32 < SECTOR_SIZE)
|
||||||
goto out_of_range;
|
goto out_of_range;
|
||||||
if (!is_power_of_2(result.uint_32)) {
|
if (!is_power_of_2(result.uint_32))
|
||||||
return invalf(NULL, "rbd: alloc_size must be a power of 2");
|
return inval_plog(&log, "alloc_size must be a power of 2");
|
||||||
}
|
|
||||||
opt->alloc_size = result.uint_32;
|
opt->alloc_size = result.uint_32;
|
||||||
break;
|
break;
|
||||||
case Opt_lock_timeout:
|
case Opt_lock_timeout:
|
||||||
@@ -6416,7 +6410,7 @@ static int rbd_parse_param(struct fs_parameter *param,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
out_of_range:
|
out_of_range:
|
||||||
return invalf(NULL, "rbd: %s out of range", param->key);
|
return inval_plog(&log, "%s out of range", param->key);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -6433,7 +6427,7 @@ static int rbd_parse_options(char *options, struct rbd_parse_opts_ctx *pctx)
|
|||||||
if (*key) {
|
if (*key) {
|
||||||
struct fs_parameter param = {
|
struct fs_parameter param = {
|
||||||
.key = key,
|
.key = key,
|
||||||
.type = fs_value_is_string,
|
.type = fs_value_is_flag,
|
||||||
};
|
};
|
||||||
char *value = strchr(key, '=');
|
char *value = strchr(key, '=');
|
||||||
size_t v_len = 0;
|
size_t v_len = 0;
|
||||||
@@ -6443,14 +6437,11 @@ static int rbd_parse_options(char *options, struct rbd_parse_opts_ctx *pctx)
|
|||||||
continue;
|
continue;
|
||||||
*value++ = 0;
|
*value++ = 0;
|
||||||
v_len = strlen(value);
|
v_len = strlen(value);
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (v_len > 0) {
|
|
||||||
param.string = kmemdup_nul(value, v_len,
|
param.string = kmemdup_nul(value, v_len,
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (!param.string)
|
if (!param.string)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
param.type = fs_value_is_string;
|
||||||
}
|
}
|
||||||
param.size = v_len;
|
param.size = v_len;
|
||||||
|
|
||||||
|
@@ -1488,7 +1488,7 @@ enum {
|
|||||||
Opt_gid,
|
Opt_gid,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct fs_parameter_spec ffs_fs_param_specs[] = {
|
static const struct fs_parameter_spec ffs_fs_fs_parameters[] = {
|
||||||
fsparam_bool ("no_disconnect", Opt_no_disconnect),
|
fsparam_bool ("no_disconnect", Opt_no_disconnect),
|
||||||
fsparam_u32 ("rmode", Opt_rmode),
|
fsparam_u32 ("rmode", Opt_rmode),
|
||||||
fsparam_u32 ("fmode", Opt_fmode),
|
fsparam_u32 ("fmode", Opt_fmode),
|
||||||
@@ -1498,11 +1498,6 @@ static const struct fs_parameter_spec ffs_fs_param_specs[] = {
|
|||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct fs_parameter_description ffs_fs_fs_parameters = {
|
|
||||||
.name = "kAFS",
|
|
||||||
.specs = ffs_fs_param_specs,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int ffs_fs_parse_param(struct fs_context *fc, struct fs_parameter *param)
|
static int ffs_fs_parse_param(struct fs_context *fc, struct fs_parameter *param)
|
||||||
{
|
{
|
||||||
struct ffs_sb_fill_data *data = fc->fs_private;
|
struct ffs_sb_fill_data *data = fc->fs_private;
|
||||||
@@ -1511,7 +1506,7 @@ static int ffs_fs_parse_param(struct fs_context *fc, struct fs_parameter *param)
|
|||||||
|
|
||||||
ENTER();
|
ENTER();
|
||||||
|
|
||||||
opt = fs_parse(fc, &ffs_fs_fs_parameters, param, &result);
|
opt = fs_parse(fc, ffs_fs_fs_parameters, param, &result);
|
||||||
if (opt < 0)
|
if (opt < 0)
|
||||||
return opt;
|
return opt;
|
||||||
|
|
||||||
@@ -1643,7 +1638,7 @@ static struct file_system_type ffs_fs_type = {
|
|||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.name = "functionfs",
|
.name = "functionfs",
|
||||||
.init_fs_context = ffs_fs_init_fs_context,
|
.init_fs_context = ffs_fs_init_fs_context,
|
||||||
.parameters = &ffs_fs_fs_parameters,
|
.parameters = ffs_fs_fs_parameters,
|
||||||
.kill_sb = ffs_fs_kill_sb,
|
.kill_sb = ffs_fs_kill_sb,
|
||||||
};
|
};
|
||||||
MODULE_ALIAS_FS("functionfs");
|
MODULE_ALIAS_FS("functionfs");
|
||||||
|
@@ -38,13 +38,13 @@ static int afs_statfs(struct dentry *dentry, struct kstatfs *buf);
|
|||||||
static int afs_show_devname(struct seq_file *m, struct dentry *root);
|
static int afs_show_devname(struct seq_file *m, struct dentry *root);
|
||||||
static int afs_show_options(struct seq_file *m, struct dentry *root);
|
static int afs_show_options(struct seq_file *m, struct dentry *root);
|
||||||
static int afs_init_fs_context(struct fs_context *fc);
|
static int afs_init_fs_context(struct fs_context *fc);
|
||||||
static const struct fs_parameter_description afs_fs_parameters;
|
static const struct fs_parameter_spec afs_fs_parameters[];
|
||||||
|
|
||||||
struct file_system_type afs_fs_type = {
|
struct file_system_type afs_fs_type = {
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.name = "afs",
|
.name = "afs",
|
||||||
.init_fs_context = afs_init_fs_context,
|
.init_fs_context = afs_init_fs_context,
|
||||||
.parameters = &afs_fs_parameters,
|
.parameters = afs_fs_parameters,
|
||||||
.kill_sb = afs_kill_super,
|
.kill_sb = afs_kill_super,
|
||||||
.fs_flags = FS_RENAME_DOES_D_MOVE,
|
.fs_flags = FS_RENAME_DOES_D_MOVE,
|
||||||
};
|
};
|
||||||
@@ -73,28 +73,22 @@ enum afs_param {
|
|||||||
Opt_source,
|
Opt_source,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct fs_parameter_spec afs_param_specs[] = {
|
static const struct constant_table afs_param_flock[] = {
|
||||||
|
{"local", afs_flock_mode_local },
|
||||||
|
{"openafs", afs_flock_mode_openafs },
|
||||||
|
{"strict", afs_flock_mode_strict },
|
||||||
|
{"write", afs_flock_mode_write },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct fs_parameter_spec afs_fs_parameters[] = {
|
||||||
fsparam_flag ("autocell", Opt_autocell),
|
fsparam_flag ("autocell", Opt_autocell),
|
||||||
fsparam_flag ("dyn", Opt_dyn),
|
fsparam_flag ("dyn", Opt_dyn),
|
||||||
fsparam_enum ("flock", Opt_flock),
|
fsparam_enum ("flock", Opt_flock, afs_param_flock),
|
||||||
fsparam_string("source", Opt_source),
|
fsparam_string("source", Opt_source),
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct fs_parameter_enum afs_param_enums[] = {
|
|
||||||
{ Opt_flock, "local", afs_flock_mode_local },
|
|
||||||
{ Opt_flock, "openafs", afs_flock_mode_openafs },
|
|
||||||
{ Opt_flock, "strict", afs_flock_mode_strict },
|
|
||||||
{ Opt_flock, "write", afs_flock_mode_write },
|
|
||||||
{}
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct fs_parameter_description afs_fs_parameters = {
|
|
||||||
.name = "kAFS",
|
|
||||||
.specs = afs_param_specs,
|
|
||||||
.enums = afs_param_enums,
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* initialise the filesystem
|
* initialise the filesystem
|
||||||
*/
|
*/
|
||||||
@@ -323,7 +317,7 @@ static int afs_parse_param(struct fs_context *fc, struct fs_parameter *param)
|
|||||||
struct afs_fs_context *ctx = fc->fs_private;
|
struct afs_fs_context *ctx = fc->fs_private;
|
||||||
int opt;
|
int opt;
|
||||||
|
|
||||||
opt = fs_parse(fc, &afs_fs_parameters, param, &result);
|
opt = fs_parse(fc, afs_fs_parameters, param, &result);
|
||||||
if (opt < 0)
|
if (opt < 0)
|
||||||
return opt;
|
return opt;
|
||||||
|
|
||||||
|
@@ -67,7 +67,7 @@ int ceph_fscache_register_fs(struct ceph_fs_client* fsc, struct fs_context *fc)
|
|||||||
if (uniq_len && memcmp(ent->uniquifier, fscache_uniq, uniq_len))
|
if (uniq_len && memcmp(ent->uniquifier, fscache_uniq, uniq_len))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
errorf(fc, "ceph: fscache cookie already registered for fsid %pU, use fsc=<uniquifier> option",
|
errorfc(fc, "fscache cookie already registered for fsid %pU, use fsc=<uniquifier> option",
|
||||||
fsid);
|
fsid);
|
||||||
err = -EBUSY;
|
err = -EBUSY;
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
@@ -96,7 +96,7 @@ int ceph_fscache_register_fs(struct ceph_fs_client* fsc, struct fs_context *fc)
|
|||||||
list_add_tail(&ent->list, &ceph_fscache_list);
|
list_add_tail(&ent->list, &ceph_fscache_list);
|
||||||
} else {
|
} else {
|
||||||
kfree(ent);
|
kfree(ent);
|
||||||
errorf(fc, "ceph: unable to register fscache cookie for fsid %pU",
|
errorfc(fc, "unable to register fscache cookie for fsid %pU",
|
||||||
fsid);
|
fsid);
|
||||||
/* all other fs ignore this error */
|
/* all other fs ignore this error */
|
||||||
}
|
}
|
||||||
|
@@ -162,13 +162,13 @@ enum ceph_recover_session_mode {
|
|||||||
ceph_recover_session_clean
|
ceph_recover_session_clean
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct fs_parameter_enum ceph_mount_param_enums[] = {
|
static const struct constant_table ceph_param_recover[] = {
|
||||||
{ Opt_recover_session, "no", ceph_recover_session_no },
|
{ "no", ceph_recover_session_no },
|
||||||
{ Opt_recover_session, "clean", ceph_recover_session_clean },
|
{ "clean", ceph_recover_session_clean },
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct fs_parameter_spec ceph_mount_param_specs[] = {
|
static const struct fs_parameter_spec ceph_mount_parameters[] = {
|
||||||
fsparam_flag_no ("acl", Opt_acl),
|
fsparam_flag_no ("acl", Opt_acl),
|
||||||
fsparam_flag_no ("asyncreaddir", Opt_asyncreaddir),
|
fsparam_flag_no ("asyncreaddir", Opt_asyncreaddir),
|
||||||
fsparam_s32 ("caps_max", Opt_caps_max),
|
fsparam_s32 ("caps_max", Opt_caps_max),
|
||||||
@@ -178,8 +178,8 @@ static const struct fs_parameter_spec ceph_mount_param_specs[] = {
|
|||||||
fsparam_flag_no ("copyfrom", Opt_copyfrom),
|
fsparam_flag_no ("copyfrom", Opt_copyfrom),
|
||||||
fsparam_flag_no ("dcache", Opt_dcache),
|
fsparam_flag_no ("dcache", Opt_dcache),
|
||||||
fsparam_flag_no ("dirstat", Opt_dirstat),
|
fsparam_flag_no ("dirstat", Opt_dirstat),
|
||||||
__fsparam (fs_param_is_string, "fsc", Opt_fscache,
|
fsparam_flag_no ("fsc", Opt_fscache), // fsc|nofsc
|
||||||
fs_param_neg_with_no | fs_param_v_optional),
|
fsparam_string ("fsc", Opt_fscache), // fsc=...
|
||||||
fsparam_flag_no ("ino32", Opt_ino32),
|
fsparam_flag_no ("ino32", Opt_ino32),
|
||||||
fsparam_string ("mds_namespace", Opt_mds_namespace),
|
fsparam_string ("mds_namespace", Opt_mds_namespace),
|
||||||
fsparam_flag_no ("poolperm", Opt_poolperm),
|
fsparam_flag_no ("poolperm", Opt_poolperm),
|
||||||
@@ -188,7 +188,7 @@ static const struct fs_parameter_spec ceph_mount_param_specs[] = {
|
|||||||
fsparam_flag_no ("rbytes", Opt_rbytes),
|
fsparam_flag_no ("rbytes", Opt_rbytes),
|
||||||
fsparam_u32 ("readdir_max_bytes", Opt_readdir_max_bytes),
|
fsparam_u32 ("readdir_max_bytes", Opt_readdir_max_bytes),
|
||||||
fsparam_u32 ("readdir_max_entries", Opt_readdir_max_entries),
|
fsparam_u32 ("readdir_max_entries", Opt_readdir_max_entries),
|
||||||
fsparam_enum ("recover_session", Opt_recover_session),
|
fsparam_enum ("recover_session", Opt_recover_session, ceph_param_recover),
|
||||||
fsparam_flag_no ("require_active_mds", Opt_require_active_mds),
|
fsparam_flag_no ("require_active_mds", Opt_require_active_mds),
|
||||||
fsparam_u32 ("rsize", Opt_rsize),
|
fsparam_u32 ("rsize", Opt_rsize),
|
||||||
fsparam_string ("snapdirname", Opt_snapdirname),
|
fsparam_string ("snapdirname", Opt_snapdirname),
|
||||||
@@ -197,12 +197,6 @@ static const struct fs_parameter_spec ceph_mount_param_specs[] = {
|
|||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct fs_parameter_description ceph_mount_parameters = {
|
|
||||||
.name = "ceph",
|
|
||||||
.specs = ceph_mount_param_specs,
|
|
||||||
.enums = ceph_mount_param_enums,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ceph_parse_opts_ctx {
|
struct ceph_parse_opts_ctx {
|
||||||
struct ceph_options *copts;
|
struct ceph_options *copts;
|
||||||
struct ceph_mount_options *opts;
|
struct ceph_mount_options *opts;
|
||||||
@@ -226,7 +220,7 @@ static int ceph_parse_source(struct fs_parameter *param, struct fs_context *fc)
|
|||||||
|
|
||||||
dout("%s '%s'\n", __func__, dev_name);
|
dout("%s '%s'\n", __func__, dev_name);
|
||||||
if (!dev_name || !*dev_name)
|
if (!dev_name || !*dev_name)
|
||||||
return invalf(fc, "ceph: Empty source");
|
return invalfc(fc, "Empty source");
|
||||||
|
|
||||||
dev_name_end = strchr(dev_name, '/');
|
dev_name_end = strchr(dev_name, '/');
|
||||||
if (dev_name_end) {
|
if (dev_name_end) {
|
||||||
@@ -245,14 +239,14 @@ static int ceph_parse_source(struct fs_parameter *param, struct fs_context *fc)
|
|||||||
|
|
||||||
dev_name_end--; /* back up to ':' separator */
|
dev_name_end--; /* back up to ':' separator */
|
||||||
if (dev_name_end < dev_name || *dev_name_end != ':')
|
if (dev_name_end < dev_name || *dev_name_end != ':')
|
||||||
return invalf(fc, "ceph: No path or : separator in source");
|
return invalfc(fc, "No path or : separator in source");
|
||||||
|
|
||||||
dout("device name '%.*s'\n", (int)(dev_name_end - dev_name), dev_name);
|
dout("device name '%.*s'\n", (int)(dev_name_end - dev_name), dev_name);
|
||||||
if (fsopt->server_path)
|
if (fsopt->server_path)
|
||||||
dout("server path '%s'\n", fsopt->server_path);
|
dout("server path '%s'\n", fsopt->server_path);
|
||||||
|
|
||||||
ret = ceph_parse_mon_ips(param->string, dev_name_end - dev_name,
|
ret = ceph_parse_mon_ips(param->string, dev_name_end - dev_name,
|
||||||
pctx->copts, fc);
|
pctx->copts, fc->log.log);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@@ -270,11 +264,11 @@ static int ceph_parse_mount_param(struct fs_context *fc,
|
|||||||
unsigned int mode;
|
unsigned int mode;
|
||||||
int token, ret;
|
int token, ret;
|
||||||
|
|
||||||
ret = ceph_parse_param(param, pctx->copts, fc);
|
ret = ceph_parse_param(param, pctx->copts, fc->log.log);
|
||||||
if (ret != -ENOPARAM)
|
if (ret != -ENOPARAM)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
token = fs_parse(fc, &ceph_mount_parameters, param, &result);
|
token = fs_parse(fc, ceph_mount_parameters, param, &result);
|
||||||
dout("%s fs_parse '%s' token %d\n", __func__, param->key, token);
|
dout("%s fs_parse '%s' token %d\n", __func__, param->key, token);
|
||||||
if (token < 0)
|
if (token < 0)
|
||||||
return token;
|
return token;
|
||||||
@@ -301,7 +295,7 @@ static int ceph_parse_mount_param(struct fs_context *fc,
|
|||||||
break;
|
break;
|
||||||
case Opt_source:
|
case Opt_source:
|
||||||
if (fc->source)
|
if (fc->source)
|
||||||
return invalf(fc, "ceph: Multiple sources specified");
|
return invalfc(fc, "Multiple sources specified");
|
||||||
return ceph_parse_source(param, fc);
|
return ceph_parse_source(param, fc);
|
||||||
case Opt_wsize:
|
case Opt_wsize:
|
||||||
if (result.uint_32 < PAGE_SIZE ||
|
if (result.uint_32 < PAGE_SIZE ||
|
||||||
@@ -392,7 +386,7 @@ static int ceph_parse_mount_param(struct fs_context *fc,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#else
|
#else
|
||||||
return invalf(fc, "ceph: fscache support is disabled");
|
return invalfc(fc, "fscache support is disabled");
|
||||||
#endif
|
#endif
|
||||||
case Opt_poolperm:
|
case Opt_poolperm:
|
||||||
if (!result.negated)
|
if (!result.negated)
|
||||||
@@ -423,7 +417,7 @@ static int ceph_parse_mount_param(struct fs_context *fc,
|
|||||||
#ifdef CONFIG_CEPH_FS_POSIX_ACL
|
#ifdef CONFIG_CEPH_FS_POSIX_ACL
|
||||||
fc->sb_flags |= SB_POSIXACL;
|
fc->sb_flags |= SB_POSIXACL;
|
||||||
#else
|
#else
|
||||||
return invalf(fc, "ceph: POSIX ACL support is disabled");
|
return invalfc(fc, "POSIX ACL support is disabled");
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
fc->sb_flags &= ~SB_POSIXACL;
|
fc->sb_flags &= ~SB_POSIXACL;
|
||||||
@@ -435,7 +429,7 @@ static int ceph_parse_mount_param(struct fs_context *fc,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
out_of_range:
|
out_of_range:
|
||||||
return invalf(fc, "ceph: %s out of range", param->key);
|
return invalfc(fc, "%s out of range", param->key);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void destroy_mount_options(struct ceph_mount_options *args)
|
static void destroy_mount_options(struct ceph_mount_options *args)
|
||||||
@@ -1101,7 +1095,7 @@ static int ceph_get_tree(struct fs_context *fc)
|
|||||||
dout("ceph_get_tree\n");
|
dout("ceph_get_tree\n");
|
||||||
|
|
||||||
if (!fc->source)
|
if (!fc->source)
|
||||||
return invalf(fc, "ceph: No source");
|
return invalfc(fc, "No source");
|
||||||
|
|
||||||
#ifdef CONFIG_CEPH_FS_POSIX_ACL
|
#ifdef CONFIG_CEPH_FS_POSIX_ACL
|
||||||
fc->sb_flags |= SB_POSIXACL;
|
fc->sb_flags |= SB_POSIXACL;
|
||||||
|
@@ -534,7 +534,7 @@ static int cramfs_read_super(struct super_block *sb, struct fs_context *fc,
|
|||||||
/* check for wrong endianness */
|
/* check for wrong endianness */
|
||||||
if (super->magic == CRAMFS_MAGIC_WEND) {
|
if (super->magic == CRAMFS_MAGIC_WEND) {
|
||||||
if (!silent)
|
if (!silent)
|
||||||
errorf(fc, "cramfs: wrong endianness");
|
errorfc(fc, "wrong endianness");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -546,22 +546,22 @@ static int cramfs_read_super(struct super_block *sb, struct fs_context *fc,
|
|||||||
mutex_unlock(&read_mutex);
|
mutex_unlock(&read_mutex);
|
||||||
if (super->magic != CRAMFS_MAGIC) {
|
if (super->magic != CRAMFS_MAGIC) {
|
||||||
if (super->magic == CRAMFS_MAGIC_WEND && !silent)
|
if (super->magic == CRAMFS_MAGIC_WEND && !silent)
|
||||||
errorf(fc, "cramfs: wrong endianness");
|
errorfc(fc, "wrong endianness");
|
||||||
else if (!silent)
|
else if (!silent)
|
||||||
errorf(fc, "cramfs: wrong magic");
|
errorfc(fc, "wrong magic");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get feature flags first */
|
/* get feature flags first */
|
||||||
if (super->flags & ~CRAMFS_SUPPORTED_FLAGS) {
|
if (super->flags & ~CRAMFS_SUPPORTED_FLAGS) {
|
||||||
errorf(fc, "cramfs: unsupported filesystem features");
|
errorfc(fc, "unsupported filesystem features");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check that the root inode is in a sane state */
|
/* Check that the root inode is in a sane state */
|
||||||
if (!S_ISDIR(super->root.mode)) {
|
if (!S_ISDIR(super->root.mode)) {
|
||||||
errorf(fc, "cramfs: root is not a directory");
|
errorfc(fc, "root is not a directory");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
/* correct strange, hard-coded permissions of mkcramfs */
|
/* correct strange, hard-coded permissions of mkcramfs */
|
||||||
@@ -580,12 +580,12 @@ static int cramfs_read_super(struct super_block *sb, struct fs_context *fc,
|
|||||||
sbi->magic = super->magic;
|
sbi->magic = super->magic;
|
||||||
sbi->flags = super->flags;
|
sbi->flags = super->flags;
|
||||||
if (root_offset == 0)
|
if (root_offset == 0)
|
||||||
infof(fc, "cramfs: empty filesystem");
|
infofc(fc, "empty filesystem");
|
||||||
else if (!(super->flags & CRAMFS_FLAG_SHIFTED_ROOT_OFFSET) &&
|
else if (!(super->flags & CRAMFS_FLAG_SHIFTED_ROOT_OFFSET) &&
|
||||||
((root_offset != sizeof(struct cramfs_super)) &&
|
((root_offset != sizeof(struct cramfs_super)) &&
|
||||||
(root_offset != 512 + sizeof(struct cramfs_super))))
|
(root_offset != 512 + sizeof(struct cramfs_super))))
|
||||||
{
|
{
|
||||||
errorf(fc, "cramfs: bad root offset %lu", root_offset);
|
errorfc(fc, "bad root offset %lu", root_offset);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -74,7 +74,8 @@ int register_filesystem(struct file_system_type * fs)
|
|||||||
int res = 0;
|
int res = 0;
|
||||||
struct file_system_type ** p;
|
struct file_system_type ** p;
|
||||||
|
|
||||||
if (fs->parameters && !fs_validate_description(fs->parameters))
|
if (fs->parameters &&
|
||||||
|
!fs_validate_description(fs->name, fs->parameters))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
BUG_ON(strchr(fs->name, '.'));
|
BUG_ON(strchr(fs->name, '.'));
|
||||||
|
@@ -45,6 +45,7 @@ static const struct constant_table common_set_sb_flag[] = {
|
|||||||
{ "posixacl", SB_POSIXACL },
|
{ "posixacl", SB_POSIXACL },
|
||||||
{ "ro", SB_RDONLY },
|
{ "ro", SB_RDONLY },
|
||||||
{ "sync", SB_SYNCHRONOUS },
|
{ "sync", SB_SYNCHRONOUS },
|
||||||
|
{ },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct constant_table common_clear_sb_flag[] = {
|
static const struct constant_table common_clear_sb_flag[] = {
|
||||||
@@ -53,6 +54,7 @@ static const struct constant_table common_clear_sb_flag[] = {
|
|||||||
{ "nomand", SB_MANDLOCK },
|
{ "nomand", SB_MANDLOCK },
|
||||||
{ "rw", SB_RDONLY },
|
{ "rw", SB_RDONLY },
|
||||||
{ "silent", SB_SILENT },
|
{ "silent", SB_SILENT },
|
||||||
|
{ },
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *const forbidden_sb_flag[] = {
|
static const char *const forbidden_sb_flag[] = {
|
||||||
@@ -175,14 +177,15 @@ int vfs_parse_fs_string(struct fs_context *fc, const char *key,
|
|||||||
|
|
||||||
struct fs_parameter param = {
|
struct fs_parameter param = {
|
||||||
.key = key,
|
.key = key,
|
||||||
.type = fs_value_is_string,
|
.type = fs_value_is_flag,
|
||||||
.size = v_size,
|
.size = v_size,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (v_size > 0) {
|
if (value) {
|
||||||
param.string = kmemdup_nul(value, v_size, GFP_KERNEL);
|
param.string = kmemdup_nul(value, v_size, GFP_KERNEL);
|
||||||
if (!param.string)
|
if (!param.string)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
param.type = fs_value_is_string;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = vfs_parse_fs_param(fc, ¶m);
|
ret = vfs_parse_fs_param(fc, ¶m);
|
||||||
@@ -268,6 +271,7 @@ static struct fs_context *alloc_fs_context(struct file_system_type *fs_type,
|
|||||||
fc->fs_type = get_filesystem(fs_type);
|
fc->fs_type = get_filesystem(fs_type);
|
||||||
fc->cred = get_current_cred();
|
fc->cred = get_current_cred();
|
||||||
fc->net_ns = get_net(current->nsproxy->net_ns);
|
fc->net_ns = get_net(current->nsproxy->net_ns);
|
||||||
|
fc->log.prefix = fs_type->name;
|
||||||
|
|
||||||
mutex_init(&fc->uapi_mutex);
|
mutex_init(&fc->uapi_mutex);
|
||||||
|
|
||||||
@@ -361,8 +365,8 @@ struct fs_context *vfs_dup_fs_context(struct fs_context *src_fc)
|
|||||||
get_net(fc->net_ns);
|
get_net(fc->net_ns);
|
||||||
get_user_ns(fc->user_ns);
|
get_user_ns(fc->user_ns);
|
||||||
get_cred(fc->cred);
|
get_cred(fc->cred);
|
||||||
if (fc->log)
|
if (fc->log.log)
|
||||||
refcount_inc(&fc->log->usage);
|
refcount_inc(&fc->log.log->usage);
|
||||||
|
|
||||||
/* Can't call put until we've called ->dup */
|
/* Can't call put until we've called ->dup */
|
||||||
ret = fc->ops->dup(fc, src_fc);
|
ret = fc->ops->dup(fc, src_fc);
|
||||||
@@ -385,64 +389,33 @@ EXPORT_SYMBOL(vfs_dup_fs_context);
|
|||||||
* @fc: The filesystem context to log to.
|
* @fc: The filesystem context to log to.
|
||||||
* @fmt: The format of the buffer.
|
* @fmt: The format of the buffer.
|
||||||
*/
|
*/
|
||||||
void logfc(struct fs_context *fc, const char *fmt, ...)
|
void logfc(struct fc_log *log, const char *prefix, char level, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
static const char store_failure[] = "OOM: Can't store error string";
|
|
||||||
struct fc_log *log = fc ? fc->log : NULL;
|
|
||||||
const char *p;
|
|
||||||
va_list va;
|
va_list va;
|
||||||
char *q;
|
struct va_format vaf = {.fmt = fmt, .va = &va};
|
||||||
u8 freeable;
|
|
||||||
|
|
||||||
va_start(va, fmt);
|
va_start(va, fmt);
|
||||||
if (!strchr(fmt, '%')) {
|
|
||||||
p = fmt;
|
|
||||||
goto unformatted_string;
|
|
||||||
}
|
|
||||||
if (strcmp(fmt, "%s") == 0) {
|
|
||||||
p = va_arg(va, const char *);
|
|
||||||
goto unformatted_string;
|
|
||||||
}
|
|
||||||
|
|
||||||
q = kvasprintf(GFP_KERNEL, fmt, va);
|
|
||||||
copied_string:
|
|
||||||
if (!q)
|
|
||||||
goto store_failure;
|
|
||||||
freeable = 1;
|
|
||||||
goto store_string;
|
|
||||||
|
|
||||||
unformatted_string:
|
|
||||||
if ((unsigned long)p >= (unsigned long)__start_rodata &&
|
|
||||||
(unsigned long)p < (unsigned long)__end_rodata)
|
|
||||||
goto const_string;
|
|
||||||
if (log && within_module_core((unsigned long)p, log->owner))
|
|
||||||
goto const_string;
|
|
||||||
q = kstrdup(p, GFP_KERNEL);
|
|
||||||
goto copied_string;
|
|
||||||
|
|
||||||
store_failure:
|
|
||||||
p = store_failure;
|
|
||||||
const_string:
|
|
||||||
q = (char *)p;
|
|
||||||
freeable = 0;
|
|
||||||
store_string:
|
|
||||||
if (!log) {
|
if (!log) {
|
||||||
switch (fmt[0]) {
|
switch (level) {
|
||||||
case 'w':
|
case 'w':
|
||||||
printk(KERN_WARNING "%s\n", q + 2);
|
printk(KERN_WARNING "%s%s%pV\n", prefix ? prefix : "",
|
||||||
|
prefix ? ": " : "", &vaf);
|
||||||
break;
|
break;
|
||||||
case 'e':
|
case 'e':
|
||||||
printk(KERN_ERR "%s\n", q + 2);
|
printk(KERN_ERR "%s%s%pV\n", prefix ? prefix : "",
|
||||||
|
prefix ? ": " : "", &vaf);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printk(KERN_NOTICE "%s\n", q + 2);
|
printk(KERN_NOTICE "%s%s%pV\n", prefix ? prefix : "",
|
||||||
|
prefix ? ": " : "", &vaf);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (freeable)
|
|
||||||
kfree(q);
|
|
||||||
} else {
|
} else {
|
||||||
unsigned int logsize = ARRAY_SIZE(log->buffer);
|
unsigned int logsize = ARRAY_SIZE(log->buffer);
|
||||||
u8 index;
|
u8 index;
|
||||||
|
char *q = kasprintf(GFP_KERNEL, "%c %s%s%pV\n", level,
|
||||||
|
prefix ? prefix : "",
|
||||||
|
prefix ? ": " : "", &vaf);
|
||||||
|
|
||||||
index = log->head & (logsize - 1);
|
index = log->head & (logsize - 1);
|
||||||
BUILD_BUG_ON(sizeof(log->head) != sizeof(u8) ||
|
BUILD_BUG_ON(sizeof(log->head) != sizeof(u8) ||
|
||||||
@@ -454,9 +427,11 @@ store_string:
|
|||||||
log->tail++;
|
log->tail++;
|
||||||
}
|
}
|
||||||
|
|
||||||
log->buffer[index] = q;
|
log->buffer[index] = q ? q : "OOM: Can't store error string";
|
||||||
|
if (q)
|
||||||
|
log->need_free |= 1 << index;
|
||||||
|
else
|
||||||
log->need_free &= ~(1 << index);
|
log->need_free &= ~(1 << index);
|
||||||
log->need_free |= freeable << index;
|
|
||||||
log->head++;
|
log->head++;
|
||||||
}
|
}
|
||||||
va_end(va);
|
va_end(va);
|
||||||
@@ -468,12 +443,12 @@ EXPORT_SYMBOL(logfc);
|
|||||||
*/
|
*/
|
||||||
static void put_fc_log(struct fs_context *fc)
|
static void put_fc_log(struct fs_context *fc)
|
||||||
{
|
{
|
||||||
struct fc_log *log = fc->log;
|
struct fc_log *log = fc->log.log;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (log) {
|
if (log) {
|
||||||
if (refcount_dec_and_test(&log->usage)) {
|
if (refcount_dec_and_test(&log->usage)) {
|
||||||
fc->log = NULL;
|
fc->log.log = NULL;
|
||||||
for (i = 0; i <= 7; i++)
|
for (i = 0; i <= 7; i++)
|
||||||
if (log->need_free & (1 << i))
|
if (log->need_free & (1 << i))
|
||||||
kfree(log->buffer[i]);
|
kfree(log->buffer[i]);
|
||||||
|
439
fs/fs_parser.c
439
fs/fs_parser.c
@@ -20,42 +20,66 @@ static const struct constant_table bool_names[] = {
|
|||||||
{ "no", false },
|
{ "no", false },
|
||||||
{ "true", true },
|
{ "true", true },
|
||||||
{ "yes", true },
|
{ "yes", true },
|
||||||
|
{ },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct constant_table *
|
||||||
|
__lookup_constant(const struct constant_table *tbl, const char *name)
|
||||||
|
{
|
||||||
|
for ( ; tbl->name; tbl++)
|
||||||
|
if (strcmp(name, tbl->name) == 0)
|
||||||
|
return tbl;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* lookup_constant - Look up a constant by name in an ordered table
|
* lookup_constant - Look up a constant by name in an ordered table
|
||||||
* @tbl: The table of constants to search.
|
* @tbl: The table of constants to search.
|
||||||
* @tbl_size: The size of the table.
|
|
||||||
* @name: The name to look up.
|
* @name: The name to look up.
|
||||||
* @not_found: The value to return if the name is not found.
|
* @not_found: The value to return if the name is not found.
|
||||||
*/
|
*/
|
||||||
int __lookup_constant(const struct constant_table *tbl, size_t tbl_size,
|
int lookup_constant(const struct constant_table *tbl, const char *name, int not_found)
|
||||||
const char *name, int not_found)
|
|
||||||
{
|
{
|
||||||
unsigned int i;
|
const struct constant_table *p = __lookup_constant(tbl, name);
|
||||||
|
|
||||||
for (i = 0; i < tbl_size; i++)
|
return p ? p->value : not_found;
|
||||||
if (strcmp(name, tbl[i].name) == 0)
|
}
|
||||||
return tbl[i].value;
|
EXPORT_SYMBOL(lookup_constant);
|
||||||
|
|
||||||
return not_found;
|
static inline bool is_flag(const struct fs_parameter_spec *p)
|
||||||
|
{
|
||||||
|
return p->type == NULL;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(__lookup_constant);
|
|
||||||
|
|
||||||
static const struct fs_parameter_spec *fs_lookup_key(
|
static const struct fs_parameter_spec *fs_lookup_key(
|
||||||
const struct fs_parameter_description *desc,
|
const struct fs_parameter_spec *desc,
|
||||||
const char *name)
|
struct fs_parameter *param, bool *negated)
|
||||||
{
|
{
|
||||||
const struct fs_parameter_spec *p;
|
const struct fs_parameter_spec *p, *other = NULL;
|
||||||
|
const char *name = param->key;
|
||||||
|
bool want_flag = param->type == fs_value_is_flag;
|
||||||
|
|
||||||
if (!desc->specs)
|
*negated = false;
|
||||||
return NULL;
|
for (p = desc; p->name; p++) {
|
||||||
|
if (strcmp(p->name, name) != 0)
|
||||||
for (p = desc->specs; p->name; p++)
|
continue;
|
||||||
if (strcmp(p->name, name) == 0)
|
if (likely(is_flag(p) == want_flag))
|
||||||
return p;
|
return p;
|
||||||
|
other = p;
|
||||||
return NULL;
|
}
|
||||||
|
if (want_flag) {
|
||||||
|
if (name[0] == 'n' && name[1] == 'o' && name[2]) {
|
||||||
|
for (p = desc; p->name; p++) {
|
||||||
|
if (strcmp(p->name, name + 2) != 0)
|
||||||
|
continue;
|
||||||
|
if (!(p->flags & fs_param_neg_with_no))
|
||||||
|
continue;
|
||||||
|
*negated = true;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return other;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -76,172 +100,38 @@ static const struct fs_parameter_spec *fs_lookup_key(
|
|||||||
* unknown parameters are okay and -EINVAL if there was a conversion issue or
|
* unknown parameters are okay and -EINVAL if there was a conversion issue or
|
||||||
* the parameter wasn't recognised and unknowns aren't okay.
|
* the parameter wasn't recognised and unknowns aren't okay.
|
||||||
*/
|
*/
|
||||||
int fs_parse(struct fs_context *fc,
|
int __fs_parse(struct p_log *log,
|
||||||
const struct fs_parameter_description *desc,
|
const struct fs_parameter_spec *desc,
|
||||||
struct fs_parameter *param,
|
struct fs_parameter *param,
|
||||||
struct fs_parse_result *result)
|
struct fs_parse_result *result)
|
||||||
{
|
{
|
||||||
const struct fs_parameter_spec *p;
|
const struct fs_parameter_spec *p;
|
||||||
const struct fs_parameter_enum *e;
|
|
||||||
int ret = -ENOPARAM, b;
|
|
||||||
|
|
||||||
result->has_value = !!param->string;
|
|
||||||
result->negated = false;
|
|
||||||
result->uint_64 = 0;
|
result->uint_64 = 0;
|
||||||
|
|
||||||
p = fs_lookup_key(desc, param->key);
|
p = fs_lookup_key(desc, param, &result->negated);
|
||||||
if (!p) {
|
|
||||||
/* If we didn't find something that looks like "noxxx", see if
|
|
||||||
* "xxx" takes the "no"-form negative - but only if there
|
|
||||||
* wasn't an value.
|
|
||||||
*/
|
|
||||||
if (result->has_value)
|
|
||||||
goto unknown_parameter;
|
|
||||||
if (param->key[0] != 'n' || param->key[1] != 'o' || !param->key[2])
|
|
||||||
goto unknown_parameter;
|
|
||||||
|
|
||||||
p = fs_lookup_key(desc, param->key + 2);
|
|
||||||
if (!p)
|
if (!p)
|
||||||
goto unknown_parameter;
|
return -ENOPARAM;
|
||||||
if (!(p->flags & fs_param_neg_with_no))
|
|
||||||
goto unknown_parameter;
|
|
||||||
result->boolean = false;
|
|
||||||
result->negated = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p->flags & fs_param_deprecated)
|
if (p->flags & fs_param_deprecated)
|
||||||
warnf(fc, "%s: Deprecated parameter '%s'",
|
warn_plog(log, "Deprecated parameter '%s'", param->key);
|
||||||
desc->name, param->key);
|
|
||||||
|
|
||||||
if (result->negated)
|
|
||||||
goto okay;
|
|
||||||
|
|
||||||
/* Certain parameter types only take a string and convert it. */
|
|
||||||
switch (p->type) {
|
|
||||||
case __fs_param_wasnt_defined:
|
|
||||||
return -EINVAL;
|
|
||||||
case fs_param_is_u32:
|
|
||||||
case fs_param_is_u32_octal:
|
|
||||||
case fs_param_is_u32_hex:
|
|
||||||
case fs_param_is_s32:
|
|
||||||
case fs_param_is_u64:
|
|
||||||
case fs_param_is_enum:
|
|
||||||
case fs_param_is_string:
|
|
||||||
if (param->type != fs_value_is_string)
|
|
||||||
goto bad_value;
|
|
||||||
if (!result->has_value) {
|
|
||||||
if (p->flags & fs_param_v_optional)
|
|
||||||
goto okay;
|
|
||||||
goto bad_value;
|
|
||||||
}
|
|
||||||
/* Fall through */
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Try to turn the type we were given into the type desired by the
|
/* Try to turn the type we were given into the type desired by the
|
||||||
* parameter and give an error if we can't.
|
* parameter and give an error if we can't.
|
||||||
*/
|
*/
|
||||||
switch (p->type) {
|
if (is_flag(p)) {
|
||||||
case fs_param_is_flag:
|
if (param->type != fs_value_is_flag)
|
||||||
if (param->type != fs_value_is_flag &&
|
return inval_plog(log, "Unexpected value for '%s'",
|
||||||
(param->type != fs_value_is_string || result->has_value))
|
param->key);
|
||||||
return invalf(fc, "%s: Unexpected value for '%s'",
|
result->boolean = !result->negated;
|
||||||
desc->name, param->key);
|
} else {
|
||||||
result->boolean = true;
|
int ret = p->type(log, p, param, result);
|
||||||
goto okay;
|
if (ret)
|
||||||
|
return ret;
|
||||||
case fs_param_is_bool:
|
|
||||||
switch (param->type) {
|
|
||||||
case fs_value_is_flag:
|
|
||||||
result->boolean = true;
|
|
||||||
goto okay;
|
|
||||||
case fs_value_is_string:
|
|
||||||
if (param->size == 0) {
|
|
||||||
result->boolean = true;
|
|
||||||
goto okay;
|
|
||||||
}
|
}
|
||||||
b = lookup_constant(bool_names, param->string, -1);
|
|
||||||
if (b == -1)
|
|
||||||
goto bad_value;
|
|
||||||
result->boolean = b;
|
|
||||||
goto okay;
|
|
||||||
default:
|
|
||||||
goto bad_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
case fs_param_is_u32:
|
|
||||||
ret = kstrtouint(param->string, 0, &result->uint_32);
|
|
||||||
goto maybe_okay;
|
|
||||||
case fs_param_is_u32_octal:
|
|
||||||
ret = kstrtouint(param->string, 8, &result->uint_32);
|
|
||||||
goto maybe_okay;
|
|
||||||
case fs_param_is_u32_hex:
|
|
||||||
ret = kstrtouint(param->string, 16, &result->uint_32);
|
|
||||||
goto maybe_okay;
|
|
||||||
case fs_param_is_s32:
|
|
||||||
ret = kstrtoint(param->string, 0, &result->int_32);
|
|
||||||
goto maybe_okay;
|
|
||||||
case fs_param_is_u64:
|
|
||||||
ret = kstrtoull(param->string, 0, &result->uint_64);
|
|
||||||
goto maybe_okay;
|
|
||||||
|
|
||||||
case fs_param_is_enum:
|
|
||||||
for (e = desc->enums; e->name[0]; e++) {
|
|
||||||
if (e->opt == p->opt &&
|
|
||||||
strcmp(e->name, param->string) == 0) {
|
|
||||||
result->uint_32 = e->value;
|
|
||||||
goto okay;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
goto bad_value;
|
|
||||||
|
|
||||||
case fs_param_is_string:
|
|
||||||
goto okay;
|
|
||||||
case fs_param_is_blob:
|
|
||||||
if (param->type != fs_value_is_blob)
|
|
||||||
goto bad_value;
|
|
||||||
goto okay;
|
|
||||||
|
|
||||||
case fs_param_is_fd: {
|
|
||||||
switch (param->type) {
|
|
||||||
case fs_value_is_string:
|
|
||||||
if (!result->has_value)
|
|
||||||
goto bad_value;
|
|
||||||
|
|
||||||
ret = kstrtouint(param->string, 0, &result->uint_32);
|
|
||||||
break;
|
|
||||||
case fs_value_is_file:
|
|
||||||
result->uint_32 = param->dirfd;
|
|
||||||
ret = 0;
|
|
||||||
default:
|
|
||||||
goto bad_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result->uint_32 > INT_MAX)
|
|
||||||
goto bad_value;
|
|
||||||
goto maybe_okay;
|
|
||||||
}
|
|
||||||
|
|
||||||
case fs_param_is_blockdev:
|
|
||||||
case fs_param_is_path:
|
|
||||||
goto okay;
|
|
||||||
default:
|
|
||||||
BUG();
|
|
||||||
}
|
|
||||||
|
|
||||||
maybe_okay:
|
|
||||||
if (ret < 0)
|
|
||||||
goto bad_value;
|
|
||||||
okay:
|
|
||||||
return p->opt;
|
return p->opt;
|
||||||
|
|
||||||
bad_value:
|
|
||||||
return invalf(fc, "%s: Bad value for '%s'", desc->name, param->key);
|
|
||||||
unknown_parameter:
|
|
||||||
return -ENOPARAM;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(fs_parse);
|
EXPORT_SYMBOL(__fs_parse);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fs_lookup_param - Look up a path referred to by a parameter
|
* fs_lookup_param - Look up a path referred to by a parameter
|
||||||
@@ -267,9 +157,6 @@ int fs_lookup_param(struct fs_context *fc,
|
|||||||
return PTR_ERR(f);
|
return PTR_ERR(f);
|
||||||
put_f = true;
|
put_f = true;
|
||||||
break;
|
break;
|
||||||
case fs_value_is_filename_empty:
|
|
||||||
flags = LOOKUP_EMPTY;
|
|
||||||
/* Fall through */
|
|
||||||
case fs_value_is_filename:
|
case fs_value_is_filename:
|
||||||
f = param->name;
|
f = param->name;
|
||||||
put_f = false;
|
put_f = false;
|
||||||
@@ -302,6 +189,124 @@ out:
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(fs_lookup_param);
|
EXPORT_SYMBOL(fs_lookup_param);
|
||||||
|
|
||||||
|
int fs_param_bad_value(struct p_log *log, struct fs_parameter *param)
|
||||||
|
{
|
||||||
|
return inval_plog(log, "Bad value for '%s'", param->key);
|
||||||
|
}
|
||||||
|
|
||||||
|
int fs_param_is_bool(struct p_log *log, const struct fs_parameter_spec *p,
|
||||||
|
struct fs_parameter *param, struct fs_parse_result *result)
|
||||||
|
{
|
||||||
|
int b;
|
||||||
|
if (param->type != fs_value_is_string)
|
||||||
|
return fs_param_bad_value(log, param);
|
||||||
|
b = lookup_constant(bool_names, param->string, -1);
|
||||||
|
if (b == -1)
|
||||||
|
return fs_param_bad_value(log, param);
|
||||||
|
result->boolean = b;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(fs_param_is_bool);
|
||||||
|
|
||||||
|
int fs_param_is_u32(struct p_log *log, const struct fs_parameter_spec *p,
|
||||||
|
struct fs_parameter *param, struct fs_parse_result *result)
|
||||||
|
{
|
||||||
|
int base = (unsigned long)p->data;
|
||||||
|
if (param->type != fs_value_is_string ||
|
||||||
|
kstrtouint(param->string, base, &result->uint_32) < 0)
|
||||||
|
return fs_param_bad_value(log, param);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(fs_param_is_u32);
|
||||||
|
|
||||||
|
int fs_param_is_s32(struct p_log *log, const struct fs_parameter_spec *p,
|
||||||
|
struct fs_parameter *param, struct fs_parse_result *result)
|
||||||
|
{
|
||||||
|
if (param->type != fs_value_is_string ||
|
||||||
|
kstrtoint(param->string, 0, &result->int_32) < 0)
|
||||||
|
return fs_param_bad_value(log, param);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(fs_param_is_s32);
|
||||||
|
|
||||||
|
int fs_param_is_u64(struct p_log *log, const struct fs_parameter_spec *p,
|
||||||
|
struct fs_parameter *param, struct fs_parse_result *result)
|
||||||
|
{
|
||||||
|
if (param->type != fs_value_is_string ||
|
||||||
|
kstrtoull(param->string, 0, &result->uint_64) < 0)
|
||||||
|
return fs_param_bad_value(log, param);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(fs_param_is_u64);
|
||||||
|
|
||||||
|
int fs_param_is_enum(struct p_log *log, const struct fs_parameter_spec *p,
|
||||||
|
struct fs_parameter *param, struct fs_parse_result *result)
|
||||||
|
{
|
||||||
|
const struct constant_table *c;
|
||||||
|
if (param->type != fs_value_is_string)
|
||||||
|
return fs_param_bad_value(log, param);
|
||||||
|
c = __lookup_constant(p->data, param->string);
|
||||||
|
if (!c)
|
||||||
|
return fs_param_bad_value(log, param);
|
||||||
|
result->uint_32 = c->value;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(fs_param_is_enum);
|
||||||
|
|
||||||
|
int fs_param_is_string(struct p_log *log, const struct fs_parameter_spec *p,
|
||||||
|
struct fs_parameter *param, struct fs_parse_result *result)
|
||||||
|
{
|
||||||
|
if (param->type != fs_value_is_string || !*param->string)
|
||||||
|
return fs_param_bad_value(log, param);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(fs_param_is_string);
|
||||||
|
|
||||||
|
int fs_param_is_blob(struct p_log *log, const struct fs_parameter_spec *p,
|
||||||
|
struct fs_parameter *param, struct fs_parse_result *result)
|
||||||
|
{
|
||||||
|
if (param->type != fs_value_is_blob)
|
||||||
|
return fs_param_bad_value(log, param);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(fs_param_is_blob);
|
||||||
|
|
||||||
|
int fs_param_is_fd(struct p_log *log, const struct fs_parameter_spec *p,
|
||||||
|
struct fs_parameter *param, struct fs_parse_result *result)
|
||||||
|
{
|
||||||
|
switch (param->type) {
|
||||||
|
case fs_value_is_string:
|
||||||
|
if (kstrtouint(param->string, 0, &result->uint_32) < 0)
|
||||||
|
break;
|
||||||
|
if (result->uint_32 <= INT_MAX)
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
case fs_value_is_file:
|
||||||
|
result->uint_32 = param->dirfd;
|
||||||
|
if (result->uint_32 <= INT_MAX)
|
||||||
|
return 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return fs_param_bad_value(log, param);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(fs_param_is_fd);
|
||||||
|
|
||||||
|
int fs_param_is_blockdev(struct p_log *log, const struct fs_parameter_spec *p,
|
||||||
|
struct fs_parameter *param, struct fs_parse_result *result)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(fs_param_is_blockdev);
|
||||||
|
|
||||||
|
int fs_param_is_path(struct p_log *log, const struct fs_parameter_spec *p,
|
||||||
|
struct fs_parameter *param, struct fs_parse_result *result)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(fs_param_is_path);
|
||||||
|
|
||||||
#ifdef CONFIG_VALIDATE_FS_PARSER
|
#ifdef CONFIG_VALIDATE_FS_PARSER
|
||||||
/**
|
/**
|
||||||
* validate_constant_table - Validate a constant table
|
* validate_constant_table - Validate a constant table
|
||||||
@@ -357,102 +362,26 @@ bool validate_constant_table(const struct constant_table *tbl, size_t tbl_size,
|
|||||||
* fs_validate_description - Validate a parameter description
|
* fs_validate_description - Validate a parameter description
|
||||||
* @desc: The parameter description to validate.
|
* @desc: The parameter description to validate.
|
||||||
*/
|
*/
|
||||||
bool fs_validate_description(const struct fs_parameter_description *desc)
|
bool fs_validate_description(const char *name,
|
||||||
|
const struct fs_parameter_spec *desc)
|
||||||
{
|
{
|
||||||
const struct fs_parameter_spec *param, *p2;
|
const struct fs_parameter_spec *param, *p2;
|
||||||
const struct fs_parameter_enum *e;
|
bool good = true;
|
||||||
const char *name = desc->name;
|
|
||||||
unsigned int nr_params = 0;
|
|
||||||
bool good = true, enums = false;
|
|
||||||
|
|
||||||
pr_notice("*** VALIDATE %s ***\n", name);
|
pr_notice("*** VALIDATE %s ***\n", name);
|
||||||
|
|
||||||
if (!name[0]) {
|
for (param = desc; param->name; param++) {
|
||||||
pr_err("VALIDATE Parser: No name\n");
|
|
||||||
name = "Unknown";
|
|
||||||
good = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (desc->specs) {
|
|
||||||
for (param = desc->specs; param->name; param++) {
|
|
||||||
enum fs_parameter_type t = param->type;
|
|
||||||
|
|
||||||
/* Check that the type is in range */
|
|
||||||
if (t == __fs_param_wasnt_defined ||
|
|
||||||
t >= nr__fs_parameter_type) {
|
|
||||||
pr_err("VALIDATE %s: PARAM[%s] Bad type %u\n",
|
|
||||||
name, param->name, t);
|
|
||||||
good = false;
|
|
||||||
} else if (t == fs_param_is_enum) {
|
|
||||||
enums = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check for duplicate parameter names */
|
/* Check for duplicate parameter names */
|
||||||
for (p2 = desc->specs; p2 < param; p2++) {
|
for (p2 = desc; p2 < param; p2++) {
|
||||||
if (strcmp(param->name, p2->name) == 0) {
|
if (strcmp(param->name, p2->name) == 0) {
|
||||||
|
if (is_flag(param) != is_flag(p2))
|
||||||
|
continue;
|
||||||
pr_err("VALIDATE %s: PARAM[%s]: Duplicate\n",
|
pr_err("VALIDATE %s: PARAM[%s]: Duplicate\n",
|
||||||
name, param->name);
|
name, param->name);
|
||||||
good = false;
|
good = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nr_params = param - desc->specs;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (desc->enums) {
|
|
||||||
if (!nr_params) {
|
|
||||||
pr_err("VALIDATE %s: Enum table but no parameters\n",
|
|
||||||
name);
|
|
||||||
good = false;
|
|
||||||
goto no_enums;
|
|
||||||
}
|
|
||||||
if (!enums) {
|
|
||||||
pr_err("VALIDATE %s: Enum table but no enum-type values\n",
|
|
||||||
name);
|
|
||||||
good = false;
|
|
||||||
goto no_enums;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (e = desc->enums; e->name[0]; e++) {
|
|
||||||
/* Check that all entries in the enum table have at
|
|
||||||
* least one parameter that uses them.
|
|
||||||
*/
|
|
||||||
for (param = desc->specs; param->name; param++) {
|
|
||||||
if (param->opt == e->opt &&
|
|
||||||
param->type != fs_param_is_enum) {
|
|
||||||
pr_err("VALIDATE %s: e[%tu] enum val for %s\n",
|
|
||||||
name, e - desc->enums, param->name);
|
|
||||||
good = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check that all enum-type parameters have at least one enum
|
|
||||||
* value in the enum table.
|
|
||||||
*/
|
|
||||||
for (param = desc->specs; param->name; param++) {
|
|
||||||
if (param->type != fs_param_is_enum)
|
|
||||||
continue;
|
|
||||||
for (e = desc->enums; e->name[0]; e++)
|
|
||||||
if (e->opt == param->opt)
|
|
||||||
break;
|
|
||||||
if (!e->name[0]) {
|
|
||||||
pr_err("VALIDATE %s: PARAM[%s] enum with no values\n",
|
|
||||||
name, param->name);
|
|
||||||
good = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (enums) {
|
|
||||||
pr_err("VALIDATE %s: enum-type values, but no enum table\n",
|
|
||||||
name);
|
|
||||||
good = false;
|
|
||||||
goto no_enums;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
no_enums:
|
|
||||||
return good;
|
return good;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_VALIDATE_FS_PARSER */
|
#endif /* CONFIG_VALIDATE_FS_PARSER */
|
||||||
|
26
fs/fsopen.c
26
fs/fsopen.c
@@ -25,7 +25,7 @@ static ssize_t fscontext_read(struct file *file,
|
|||||||
char __user *_buf, size_t len, loff_t *pos)
|
char __user *_buf, size_t len, loff_t *pos)
|
||||||
{
|
{
|
||||||
struct fs_context *fc = file->private_data;
|
struct fs_context *fc = file->private_data;
|
||||||
struct fc_log *log = fc->log;
|
struct fc_log *log = fc->log.log;
|
||||||
unsigned int logsize = ARRAY_SIZE(log->buffer);
|
unsigned int logsize = ARRAY_SIZE(log->buffer);
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
char *p;
|
char *p;
|
||||||
@@ -97,11 +97,11 @@ static int fscontext_create_fd(struct fs_context *fc, unsigned int o_flags)
|
|||||||
|
|
||||||
static int fscontext_alloc_log(struct fs_context *fc)
|
static int fscontext_alloc_log(struct fs_context *fc)
|
||||||
{
|
{
|
||||||
fc->log = kzalloc(sizeof(*fc->log), GFP_KERNEL);
|
fc->log.log = kzalloc(sizeof(*fc->log.log), GFP_KERNEL);
|
||||||
if (!fc->log)
|
if (!fc->log.log)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
refcount_set(&fc->log->usage, 1);
|
refcount_set(&fc->log.log->usage, 1);
|
||||||
fc->log->owner = fc->fs_type->owner;
|
fc->log.log->owner = fc->fs_type->owner;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -321,6 +321,7 @@ SYSCALL_DEFINE5(fsconfig,
|
|||||||
struct fs_context *fc;
|
struct fs_context *fc;
|
||||||
struct fd f;
|
struct fd f;
|
||||||
int ret;
|
int ret;
|
||||||
|
int lookup_flags = 0;
|
||||||
|
|
||||||
struct fs_parameter param = {
|
struct fs_parameter param = {
|
||||||
.type = fs_value_is_undefined,
|
.type = fs_value_is_undefined,
|
||||||
@@ -409,19 +410,12 @@ SYSCALL_DEFINE5(fsconfig,
|
|||||||
goto out_key;
|
goto out_key;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case FSCONFIG_SET_PATH_EMPTY:
|
||||||
|
lookup_flags = LOOKUP_EMPTY;
|
||||||
|
/* fallthru */
|
||||||
case FSCONFIG_SET_PATH:
|
case FSCONFIG_SET_PATH:
|
||||||
param.type = fs_value_is_filename;
|
param.type = fs_value_is_filename;
|
||||||
param.name = getname_flags(_value, 0, NULL);
|
param.name = getname_flags(_value, lookup_flags, NULL);
|
||||||
if (IS_ERR(param.name)) {
|
|
||||||
ret = PTR_ERR(param.name);
|
|
||||||
goto out_key;
|
|
||||||
}
|
|
||||||
param.dirfd = aux;
|
|
||||||
param.size = strlen(param.name->name);
|
|
||||||
break;
|
|
||||||
case FSCONFIG_SET_PATH_EMPTY:
|
|
||||||
param.type = fs_value_is_filename_empty;
|
|
||||||
param.name = getname_flags(_value, LOOKUP_EMPTY, NULL);
|
|
||||||
if (IS_ERR(param.name)) {
|
if (IS_ERR(param.name)) {
|
||||||
ret = PTR_ERR(param.name);
|
ret = PTR_ERR(param.name);
|
||||||
goto out_key;
|
goto out_key;
|
||||||
|
@@ -448,7 +448,7 @@ enum {
|
|||||||
OPT_ERR
|
OPT_ERR
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct fs_parameter_spec fuse_param_specs[] = {
|
static const struct fs_parameter_spec fuse_fs_parameters[] = {
|
||||||
fsparam_string ("source", OPT_SOURCE),
|
fsparam_string ("source", OPT_SOURCE),
|
||||||
fsparam_u32 ("fd", OPT_FD),
|
fsparam_u32 ("fd", OPT_FD),
|
||||||
fsparam_u32oct ("rootmode", OPT_ROOTMODE),
|
fsparam_u32oct ("rootmode", OPT_ROOTMODE),
|
||||||
@@ -462,32 +462,27 @@ static const struct fs_parameter_spec fuse_param_specs[] = {
|
|||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct fs_parameter_description fuse_fs_parameters = {
|
|
||||||
.name = "fuse",
|
|
||||||
.specs = fuse_param_specs,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int fuse_parse_param(struct fs_context *fc, struct fs_parameter *param)
|
static int fuse_parse_param(struct fs_context *fc, struct fs_parameter *param)
|
||||||
{
|
{
|
||||||
struct fs_parse_result result;
|
struct fs_parse_result result;
|
||||||
struct fuse_fs_context *ctx = fc->fs_private;
|
struct fuse_fs_context *ctx = fc->fs_private;
|
||||||
int opt;
|
int opt;
|
||||||
|
|
||||||
opt = fs_parse(fc, &fuse_fs_parameters, param, &result);
|
opt = fs_parse(fc, fuse_fs_parameters, param, &result);
|
||||||
if (opt < 0)
|
if (opt < 0)
|
||||||
return opt;
|
return opt;
|
||||||
|
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
case OPT_SOURCE:
|
case OPT_SOURCE:
|
||||||
if (fc->source)
|
if (fc->source)
|
||||||
return invalf(fc, "fuse: Multiple sources specified");
|
return invalfc(fc, "Multiple sources specified");
|
||||||
fc->source = param->string;
|
fc->source = param->string;
|
||||||
param->string = NULL;
|
param->string = NULL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OPT_SUBTYPE:
|
case OPT_SUBTYPE:
|
||||||
if (ctx->subtype)
|
if (ctx->subtype)
|
||||||
return invalf(fc, "fuse: Multiple subtypes specified");
|
return invalfc(fc, "Multiple subtypes specified");
|
||||||
ctx->subtype = param->string;
|
ctx->subtype = param->string;
|
||||||
param->string = NULL;
|
param->string = NULL;
|
||||||
return 0;
|
return 0;
|
||||||
@@ -499,7 +494,7 @@ static int fuse_parse_param(struct fs_context *fc, struct fs_parameter *param)
|
|||||||
|
|
||||||
case OPT_ROOTMODE:
|
case OPT_ROOTMODE:
|
||||||
if (!fuse_valid_type(result.uint_32))
|
if (!fuse_valid_type(result.uint_32))
|
||||||
return invalf(fc, "fuse: Invalid rootmode");
|
return invalfc(fc, "Invalid rootmode");
|
||||||
ctx->rootmode = result.uint_32;
|
ctx->rootmode = result.uint_32;
|
||||||
ctx->rootmode_present = true;
|
ctx->rootmode_present = true;
|
||||||
break;
|
break;
|
||||||
@@ -507,14 +502,14 @@ static int fuse_parse_param(struct fs_context *fc, struct fs_parameter *param)
|
|||||||
case OPT_USER_ID:
|
case OPT_USER_ID:
|
||||||
ctx->user_id = make_kuid(fc->user_ns, result.uint_32);
|
ctx->user_id = make_kuid(fc->user_ns, result.uint_32);
|
||||||
if (!uid_valid(ctx->user_id))
|
if (!uid_valid(ctx->user_id))
|
||||||
return invalf(fc, "fuse: Invalid user_id");
|
return invalfc(fc, "Invalid user_id");
|
||||||
ctx->user_id_present = true;
|
ctx->user_id_present = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OPT_GROUP_ID:
|
case OPT_GROUP_ID:
|
||||||
ctx->group_id = make_kgid(fc->user_ns, result.uint_32);
|
ctx->group_id = make_kgid(fc->user_ns, result.uint_32);
|
||||||
if (!gid_valid(ctx->group_id))
|
if (!gid_valid(ctx->group_id))
|
||||||
return invalf(fc, "fuse: Invalid group_id");
|
return invalfc(fc, "Invalid group_id");
|
||||||
ctx->group_id_present = true;
|
ctx->group_id_present = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -532,7 +527,7 @@ static int fuse_parse_param(struct fs_context *fc, struct fs_parameter *param)
|
|||||||
|
|
||||||
case OPT_BLKSIZE:
|
case OPT_BLKSIZE:
|
||||||
if (!ctx->is_bdev)
|
if (!ctx->is_bdev)
|
||||||
return invalf(fc, "fuse: blksize only supported for fuseblk");
|
return invalfc(fc, "blksize only supported for fuseblk");
|
||||||
ctx->blksize = result.uint_32;
|
ctx->blksize = result.uint_32;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -1347,7 +1342,7 @@ static struct file_system_type fuse_fs_type = {
|
|||||||
.name = "fuse",
|
.name = "fuse",
|
||||||
.fs_flags = FS_HAS_SUBTYPE | FS_USERNS_MOUNT,
|
.fs_flags = FS_HAS_SUBTYPE | FS_USERNS_MOUNT,
|
||||||
.init_fs_context = fuse_init_fs_context,
|
.init_fs_context = fuse_init_fs_context,
|
||||||
.parameters = &fuse_fs_parameters,
|
.parameters = fuse_fs_parameters,
|
||||||
.kill_sb = fuse_kill_sb_anon,
|
.kill_sb = fuse_kill_sb_anon,
|
||||||
};
|
};
|
||||||
MODULE_ALIAS_FS("fuse");
|
MODULE_ALIAS_FS("fuse");
|
||||||
@@ -1363,7 +1358,7 @@ static struct file_system_type fuseblk_fs_type = {
|
|||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.name = "fuseblk",
|
.name = "fuseblk",
|
||||||
.init_fs_context = fuse_init_fs_context,
|
.init_fs_context = fuse_init_fs_context,
|
||||||
.parameters = &fuse_fs_parameters,
|
.parameters = fuse_fs_parameters,
|
||||||
.kill_sb = fuse_kill_sb_blk,
|
.kill_sb = fuse_kill_sb_blk,
|
||||||
.fs_flags = FS_REQUIRES_DEV | FS_HAS_SUBTYPE,
|
.fs_flags = FS_REQUIRES_DEV | FS_HAS_SUBTYPE,
|
||||||
};
|
};
|
||||||
|
@@ -1252,6 +1252,7 @@ enum gfs2_param {
|
|||||||
Opt_upgrade,
|
Opt_upgrade,
|
||||||
Opt_acl,
|
Opt_acl,
|
||||||
Opt_quota,
|
Opt_quota,
|
||||||
|
Opt_quota_flag,
|
||||||
Opt_suiddir,
|
Opt_suiddir,
|
||||||
Opt_data,
|
Opt_data,
|
||||||
Opt_meta,
|
Opt_meta,
|
||||||
@@ -1266,17 +1267,11 @@ enum gfs2_param {
|
|||||||
Opt_loccookie,
|
Opt_loccookie,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum opt_quota {
|
static const struct constant_table gfs2_param_quota[] = {
|
||||||
Opt_quota_unset = 0,
|
{"off", GFS2_QUOTA_OFF},
|
||||||
Opt_quota_off,
|
{"account", GFS2_QUOTA_ACCOUNT},
|
||||||
Opt_quota_account,
|
{"on", GFS2_QUOTA_ON},
|
||||||
Opt_quota_on,
|
{}
|
||||||
};
|
|
||||||
|
|
||||||
static const unsigned int opt_quota_values[] = {
|
|
||||||
[Opt_quota_off] = GFS2_QUOTA_OFF,
|
|
||||||
[Opt_quota_account] = GFS2_QUOTA_ACCOUNT,
|
|
||||||
[Opt_quota_on] = GFS2_QUOTA_ON,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum opt_data {
|
enum opt_data {
|
||||||
@@ -1284,12 +1279,24 @@ enum opt_data {
|
|||||||
Opt_data_ordered = GFS2_DATA_ORDERED,
|
Opt_data_ordered = GFS2_DATA_ORDERED,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct constant_table gfs2_param_data[] = {
|
||||||
|
{"writeback", Opt_data_writeback },
|
||||||
|
{"ordered", Opt_data_ordered },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
enum opt_errors {
|
enum opt_errors {
|
||||||
Opt_errors_withdraw = GFS2_ERRORS_WITHDRAW,
|
Opt_errors_withdraw = GFS2_ERRORS_WITHDRAW,
|
||||||
Opt_errors_panic = GFS2_ERRORS_PANIC,
|
Opt_errors_panic = GFS2_ERRORS_PANIC,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct fs_parameter_spec gfs2_param_specs[] = {
|
static const struct constant_table gfs2_param_errors[] = {
|
||||||
|
{"withdraw", Opt_errors_withdraw },
|
||||||
|
{"panic", Opt_errors_panic },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct fs_parameter_spec gfs2_fs_parameters[] = {
|
||||||
fsparam_string ("lockproto", Opt_lockproto),
|
fsparam_string ("lockproto", Opt_lockproto),
|
||||||
fsparam_string ("locktable", Opt_locktable),
|
fsparam_string ("locktable", Opt_locktable),
|
||||||
fsparam_string ("hostdata", Opt_hostdata),
|
fsparam_string ("hostdata", Opt_hostdata),
|
||||||
@@ -1302,11 +1309,11 @@ static const struct fs_parameter_spec gfs2_param_specs[] = {
|
|||||||
fsparam_flag ("upgrade", Opt_upgrade),
|
fsparam_flag ("upgrade", Opt_upgrade),
|
||||||
fsparam_flag_no("acl", Opt_acl),
|
fsparam_flag_no("acl", Opt_acl),
|
||||||
fsparam_flag_no("suiddir", Opt_suiddir),
|
fsparam_flag_no("suiddir", Opt_suiddir),
|
||||||
fsparam_enum ("data", Opt_data),
|
fsparam_enum ("data", Opt_data, gfs2_param_data),
|
||||||
fsparam_flag ("meta", Opt_meta),
|
fsparam_flag ("meta", Opt_meta),
|
||||||
fsparam_flag_no("discard", Opt_discard),
|
fsparam_flag_no("discard", Opt_discard),
|
||||||
fsparam_s32 ("commit", Opt_commit),
|
fsparam_s32 ("commit", Opt_commit),
|
||||||
fsparam_enum ("errors", Opt_errors),
|
fsparam_enum ("errors", Opt_errors, gfs2_param_errors),
|
||||||
fsparam_s32 ("statfs_quantum", Opt_statfs_quantum),
|
fsparam_s32 ("statfs_quantum", Opt_statfs_quantum),
|
||||||
fsparam_s32 ("statfs_percent", Opt_statfs_percent),
|
fsparam_s32 ("statfs_percent", Opt_statfs_percent),
|
||||||
fsparam_s32 ("quota_quantum", Opt_quota_quantum),
|
fsparam_s32 ("quota_quantum", Opt_quota_quantum),
|
||||||
@@ -1314,27 +1321,11 @@ static const struct fs_parameter_spec gfs2_param_specs[] = {
|
|||||||
fsparam_flag_no("rgrplvb", Opt_rgrplvb),
|
fsparam_flag_no("rgrplvb", Opt_rgrplvb),
|
||||||
fsparam_flag_no("loccookie", Opt_loccookie),
|
fsparam_flag_no("loccookie", Opt_loccookie),
|
||||||
/* quota can be a flag or an enum so it gets special treatment */
|
/* quota can be a flag or an enum so it gets special treatment */
|
||||||
__fsparam(fs_param_is_enum, "quota", Opt_quota, fs_param_neg_with_no|fs_param_v_optional),
|
fsparam_flag_no("quota", Opt_quota_flag),
|
||||||
|
fsparam_enum("quota", Opt_quota, gfs2_param_quota),
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct fs_parameter_enum gfs2_param_enums[] = {
|
|
||||||
{ Opt_quota, "off", Opt_quota_off },
|
|
||||||
{ Opt_quota, "account", Opt_quota_account },
|
|
||||||
{ Opt_quota, "on", Opt_quota_on },
|
|
||||||
{ Opt_data, "writeback", Opt_data_writeback },
|
|
||||||
{ Opt_data, "ordered", Opt_data_ordered },
|
|
||||||
{ Opt_errors, "withdraw", Opt_errors_withdraw },
|
|
||||||
{ Opt_errors, "panic", Opt_errors_panic },
|
|
||||||
{}
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct fs_parameter_description gfs2_fs_parameters = {
|
|
||||||
.name = "gfs2",
|
|
||||||
.specs = gfs2_param_specs,
|
|
||||||
.enums = gfs2_param_enums,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Parse a single mount parameter */
|
/* Parse a single mount parameter */
|
||||||
static int gfs2_parse_param(struct fs_context *fc, struct fs_parameter *param)
|
static int gfs2_parse_param(struct fs_context *fc, struct fs_parameter *param)
|
||||||
{
|
{
|
||||||
@@ -1342,7 +1333,7 @@ static int gfs2_parse_param(struct fs_context *fc, struct fs_parameter *param)
|
|||||||
struct fs_parse_result result;
|
struct fs_parse_result result;
|
||||||
int o;
|
int o;
|
||||||
|
|
||||||
o = fs_parse(fc, &gfs2_fs_parameters, param, &result);
|
o = fs_parse(fc, gfs2_fs_parameters, param, &result);
|
||||||
if (o < 0)
|
if (o < 0)
|
||||||
return o;
|
return o;
|
||||||
|
|
||||||
@@ -1370,7 +1361,7 @@ static int gfs2_parse_param(struct fs_context *fc, struct fs_parameter *param)
|
|||||||
break;
|
break;
|
||||||
case Opt_debug:
|
case Opt_debug:
|
||||||
if (result.boolean && args->ar_errors == GFS2_ERRORS_PANIC)
|
if (result.boolean && args->ar_errors == GFS2_ERRORS_PANIC)
|
||||||
return invalf(fc, "gfs2: -o debug and -o errors=panic are mutually exclusive");
|
return invalfc(fc, "-o debug and -o errors=panic are mutually exclusive");
|
||||||
args->ar_debug = result.boolean;
|
args->ar_debug = result.boolean;
|
||||||
break;
|
break;
|
||||||
case Opt_upgrade:
|
case Opt_upgrade:
|
||||||
@@ -1379,17 +1370,11 @@ static int gfs2_parse_param(struct fs_context *fc, struct fs_parameter *param)
|
|||||||
case Opt_acl:
|
case Opt_acl:
|
||||||
args->ar_posix_acl = result.boolean;
|
args->ar_posix_acl = result.boolean;
|
||||||
break;
|
break;
|
||||||
|
case Opt_quota_flag:
|
||||||
|
args->ar_quota = result.negated ? GFS2_QUOTA_OFF : GFS2_QUOTA_ON;
|
||||||
|
break;
|
||||||
case Opt_quota:
|
case Opt_quota:
|
||||||
/* The quota option can be a flag or an enum. A non-zero int_32
|
args->ar_quota = result.int_32;
|
||||||
result means that we have an enum index. Otherwise we have
|
|
||||||
to rely on the 'negated' flag to tell us whether 'quota' or
|
|
||||||
'noquota' was specified. */
|
|
||||||
if (result.negated)
|
|
||||||
args->ar_quota = GFS2_QUOTA_OFF;
|
|
||||||
else if (result.int_32 > 0)
|
|
||||||
args->ar_quota = opt_quota_values[result.int_32];
|
|
||||||
else
|
|
||||||
args->ar_quota = GFS2_QUOTA_ON;
|
|
||||||
break;
|
break;
|
||||||
case Opt_suiddir:
|
case Opt_suiddir:
|
||||||
args->ar_suiddir = result.boolean;
|
args->ar_suiddir = result.boolean;
|
||||||
@@ -1406,27 +1391,27 @@ static int gfs2_parse_param(struct fs_context *fc, struct fs_parameter *param)
|
|||||||
break;
|
break;
|
||||||
case Opt_commit:
|
case Opt_commit:
|
||||||
if (result.int_32 <= 0)
|
if (result.int_32 <= 0)
|
||||||
return invalf(fc, "gfs2: commit mount option requires a positive numeric argument");
|
return invalfc(fc, "commit mount option requires a positive numeric argument");
|
||||||
args->ar_commit = result.int_32;
|
args->ar_commit = result.int_32;
|
||||||
break;
|
break;
|
||||||
case Opt_statfs_quantum:
|
case Opt_statfs_quantum:
|
||||||
if (result.int_32 < 0)
|
if (result.int_32 < 0)
|
||||||
return invalf(fc, "gfs2: statfs_quantum mount option requires a non-negative numeric argument");
|
return invalfc(fc, "statfs_quantum mount option requires a non-negative numeric argument");
|
||||||
args->ar_statfs_quantum = result.int_32;
|
args->ar_statfs_quantum = result.int_32;
|
||||||
break;
|
break;
|
||||||
case Opt_quota_quantum:
|
case Opt_quota_quantum:
|
||||||
if (result.int_32 <= 0)
|
if (result.int_32 <= 0)
|
||||||
return invalf(fc, "gfs2: quota_quantum mount option requires a positive numeric argument");
|
return invalfc(fc, "quota_quantum mount option requires a positive numeric argument");
|
||||||
args->ar_quota_quantum = result.int_32;
|
args->ar_quota_quantum = result.int_32;
|
||||||
break;
|
break;
|
||||||
case Opt_statfs_percent:
|
case Opt_statfs_percent:
|
||||||
if (result.int_32 < 0 || result.int_32 > 100)
|
if (result.int_32 < 0 || result.int_32 > 100)
|
||||||
return invalf(fc, "gfs2: statfs_percent mount option requires a numeric argument between 0 and 100");
|
return invalfc(fc, "statfs_percent mount option requires a numeric argument between 0 and 100");
|
||||||
args->ar_statfs_percent = result.int_32;
|
args->ar_statfs_percent = result.int_32;
|
||||||
break;
|
break;
|
||||||
case Opt_errors:
|
case Opt_errors:
|
||||||
if (args->ar_debug && result.uint_32 == GFS2_ERRORS_PANIC)
|
if (args->ar_debug && result.uint_32 == GFS2_ERRORS_PANIC)
|
||||||
return invalf(fc, "gfs2: -o debug and -o errors=panic are mutually exclusive");
|
return invalfc(fc, "-o debug and -o errors=panic are mutually exclusive");
|
||||||
args->ar_errors = result.uint_32;
|
args->ar_errors = result.uint_32;
|
||||||
break;
|
break;
|
||||||
case Opt_barrier:
|
case Opt_barrier:
|
||||||
@@ -1439,7 +1424,7 @@ static int gfs2_parse_param(struct fs_context *fc, struct fs_parameter *param)
|
|||||||
args->ar_loccookie = result.boolean;
|
args->ar_loccookie = result.boolean;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return invalf(fc, "gfs2: invalid mount option: %s", param->key);
|
return invalfc(fc, "invalid mount option: %s", param->key);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1465,27 +1450,27 @@ static int gfs2_reconfigure(struct fs_context *fc)
|
|||||||
spin_unlock(>->gt_spin);
|
spin_unlock(>->gt_spin);
|
||||||
|
|
||||||
if (strcmp(newargs->ar_lockproto, oldargs->ar_lockproto)) {
|
if (strcmp(newargs->ar_lockproto, oldargs->ar_lockproto)) {
|
||||||
errorf(fc, "gfs2: reconfiguration of locking protocol not allowed");
|
errorfc(fc, "reconfiguration of locking protocol not allowed");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
if (strcmp(newargs->ar_locktable, oldargs->ar_locktable)) {
|
if (strcmp(newargs->ar_locktable, oldargs->ar_locktable)) {
|
||||||
errorf(fc, "gfs2: reconfiguration of lock table not allowed");
|
errorfc(fc, "reconfiguration of lock table not allowed");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
if (strcmp(newargs->ar_hostdata, oldargs->ar_hostdata)) {
|
if (strcmp(newargs->ar_hostdata, oldargs->ar_hostdata)) {
|
||||||
errorf(fc, "gfs2: reconfiguration of host data not allowed");
|
errorfc(fc, "reconfiguration of host data not allowed");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
if (newargs->ar_spectator != oldargs->ar_spectator) {
|
if (newargs->ar_spectator != oldargs->ar_spectator) {
|
||||||
errorf(fc, "gfs2: reconfiguration of spectator mode not allowed");
|
errorfc(fc, "reconfiguration of spectator mode not allowed");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
if (newargs->ar_localflocks != oldargs->ar_localflocks) {
|
if (newargs->ar_localflocks != oldargs->ar_localflocks) {
|
||||||
errorf(fc, "gfs2: reconfiguration of localflocks not allowed");
|
errorfc(fc, "reconfiguration of localflocks not allowed");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
if (newargs->ar_meta != oldargs->ar_meta) {
|
if (newargs->ar_meta != oldargs->ar_meta) {
|
||||||
errorf(fc, "gfs2: switching between gfs2 and gfs2meta not allowed");
|
errorfc(fc, "switching between gfs2 and gfs2meta not allowed");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
if (oldargs->ar_spectator)
|
if (oldargs->ar_spectator)
|
||||||
@@ -1495,11 +1480,11 @@ static int gfs2_reconfigure(struct fs_context *fc)
|
|||||||
if (fc->sb_flags & SB_RDONLY) {
|
if (fc->sb_flags & SB_RDONLY) {
|
||||||
error = gfs2_make_fs_ro(sdp);
|
error = gfs2_make_fs_ro(sdp);
|
||||||
if (error)
|
if (error)
|
||||||
errorf(fc, "gfs2: unable to remount read-only");
|
errorfc(fc, "unable to remount read-only");
|
||||||
} else {
|
} else {
|
||||||
error = gfs2_make_fs_rw(sdp);
|
error = gfs2_make_fs_rw(sdp);
|
||||||
if (error)
|
if (error)
|
||||||
errorf(fc, "gfs2: unable to remount read-write");
|
errorfc(fc, "unable to remount read-write");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sdp->sd_args = *newargs;
|
sdp->sd_args = *newargs;
|
||||||
@@ -1644,7 +1629,7 @@ struct file_system_type gfs2_fs_type = {
|
|||||||
.name = "gfs2",
|
.name = "gfs2",
|
||||||
.fs_flags = FS_REQUIRES_DEV,
|
.fs_flags = FS_REQUIRES_DEV,
|
||||||
.init_fs_context = gfs2_init_fs_context,
|
.init_fs_context = gfs2_init_fs_context,
|
||||||
.parameters = &gfs2_fs_parameters,
|
.parameters = gfs2_fs_parameters,
|
||||||
.kill_sb = gfs2_kill_sb,
|
.kill_sb = gfs2_kill_sb,
|
||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
};
|
};
|
||||||
|
@@ -73,7 +73,7 @@ enum hugetlb_param {
|
|||||||
Opt_uid,
|
Opt_uid,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct fs_parameter_spec hugetlb_param_specs[] = {
|
static const struct fs_parameter_spec hugetlb_fs_parameters[] = {
|
||||||
fsparam_u32 ("gid", Opt_gid),
|
fsparam_u32 ("gid", Opt_gid),
|
||||||
fsparam_string("min_size", Opt_min_size),
|
fsparam_string("min_size", Opt_min_size),
|
||||||
fsparam_u32 ("mode", Opt_mode),
|
fsparam_u32 ("mode", Opt_mode),
|
||||||
@@ -84,11 +84,6 @@ static const struct fs_parameter_spec hugetlb_param_specs[] = {
|
|||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct fs_parameter_description hugetlb_fs_parameters = {
|
|
||||||
.name = "hugetlbfs",
|
|
||||||
.specs = hugetlb_param_specs,
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef CONFIG_NUMA
|
#ifdef CONFIG_NUMA
|
||||||
static inline void hugetlb_set_vma_policy(struct vm_area_struct *vma,
|
static inline void hugetlb_set_vma_policy(struct vm_area_struct *vma,
|
||||||
struct inode *inode, pgoff_t index)
|
struct inode *inode, pgoff_t index)
|
||||||
@@ -1171,7 +1166,7 @@ static int hugetlbfs_parse_param(struct fs_context *fc, struct fs_parameter *par
|
|||||||
unsigned long ps;
|
unsigned long ps;
|
||||||
int opt;
|
int opt;
|
||||||
|
|
||||||
opt = fs_parse(fc, &hugetlb_fs_parameters, param, &result);
|
opt = fs_parse(fc, hugetlb_fs_parameters, param, &result);
|
||||||
if (opt < 0)
|
if (opt < 0)
|
||||||
return opt;
|
return opt;
|
||||||
|
|
||||||
@@ -1233,7 +1228,7 @@ static int hugetlbfs_parse_param(struct fs_context *fc, struct fs_parameter *par
|
|||||||
}
|
}
|
||||||
|
|
||||||
bad_val:
|
bad_val:
|
||||||
return invalf(fc, "hugetlbfs: Bad value '%s' for mount option '%s'\n",
|
return invalfc(fc, "Bad value '%s' for mount option '%s'\n",
|
||||||
param->string, param->key);
|
param->string, param->key);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1358,7 +1353,7 @@ static int hugetlbfs_init_fs_context(struct fs_context *fc)
|
|||||||
static struct file_system_type hugetlbfs_fs_type = {
|
static struct file_system_type hugetlbfs_fs_type = {
|
||||||
.name = "hugetlbfs",
|
.name = "hugetlbfs",
|
||||||
.init_fs_context = hugetlbfs_init_fs_context,
|
.init_fs_context = hugetlbfs_init_fs_context,
|
||||||
.parameters = &hugetlb_fs_parameters,
|
.parameters = hugetlb_fs_parameters,
|
||||||
.kill_sb = kill_litter_super,
|
.kill_sb = kill_litter_super,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -167,27 +167,21 @@ enum {
|
|||||||
Opt_rp_size,
|
Opt_rp_size,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct fs_parameter_spec jffs2_param_specs[] = {
|
static const struct constant_table jffs2_param_compr[] = {
|
||||||
fsparam_enum ("compr", Opt_override_compr),
|
{"none", JFFS2_COMPR_MODE_NONE },
|
||||||
fsparam_u32 ("rp_size", Opt_rp_size),
|
|
||||||
{}
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct fs_parameter_enum jffs2_param_enums[] = {
|
|
||||||
{ Opt_override_compr, "none", JFFS2_COMPR_MODE_NONE },
|
|
||||||
#ifdef CONFIG_JFFS2_LZO
|
#ifdef CONFIG_JFFS2_LZO
|
||||||
{ Opt_override_compr, "lzo", JFFS2_COMPR_MODE_FORCELZO },
|
{"lzo", JFFS2_COMPR_MODE_FORCELZO },
|
||||||
#endif
|
#endif
|
||||||
#ifdef CONFIG_JFFS2_ZLIB
|
#ifdef CONFIG_JFFS2_ZLIB
|
||||||
{ Opt_override_compr, "zlib", JFFS2_COMPR_MODE_FORCEZLIB },
|
{"zlib", JFFS2_COMPR_MODE_FORCEZLIB },
|
||||||
#endif
|
#endif
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct fs_parameter_description jffs2_fs_parameters = {
|
static const struct fs_parameter_spec jffs2_fs_parameters[] = {
|
||||||
.name = "jffs2",
|
fsparam_enum ("compr", Opt_override_compr, jffs2_param_compr),
|
||||||
.specs = jffs2_param_specs,
|
fsparam_u32 ("rp_size", Opt_rp_size),
|
||||||
.enums = jffs2_param_enums,
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
static int jffs2_parse_param(struct fs_context *fc, struct fs_parameter *param)
|
static int jffs2_parse_param(struct fs_context *fc, struct fs_parameter *param)
|
||||||
@@ -196,7 +190,7 @@ static int jffs2_parse_param(struct fs_context *fc, struct fs_parameter *param)
|
|||||||
struct jffs2_sb_info *c = fc->s_fs_info;
|
struct jffs2_sb_info *c = fc->s_fs_info;
|
||||||
int opt;
|
int opt;
|
||||||
|
|
||||||
opt = fs_parse(fc, &jffs2_fs_parameters, param, &result);
|
opt = fs_parse(fc, jffs2_fs_parameters, param, &result);
|
||||||
if (opt < 0)
|
if (opt < 0)
|
||||||
return opt;
|
return opt;
|
||||||
|
|
||||||
@@ -339,7 +333,7 @@ static struct file_system_type jffs2_fs_type = {
|
|||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.name = "jffs2",
|
.name = "jffs2",
|
||||||
.init_fs_context = jffs2_init_fs_context,
|
.init_fs_context = jffs2_init_fs_context,
|
||||||
.parameters = &jffs2_fs_parameters,
|
.parameters = jffs2_fs_parameters,
|
||||||
.kill_sb = jffs2_kill_sb,
|
.kill_sb = jffs2_kill_sb,
|
||||||
};
|
};
|
||||||
MODULE_ALIAS_FS("jffs2");
|
MODULE_ALIAS_FS("jffs2");
|
||||||
|
@@ -45,6 +45,7 @@ enum nfs_param {
|
|||||||
Opt_cto,
|
Opt_cto,
|
||||||
Opt_fg,
|
Opt_fg,
|
||||||
Opt_fscache,
|
Opt_fscache,
|
||||||
|
Opt_fscache_flag,
|
||||||
Opt_hard,
|
Opt_hard,
|
||||||
Opt_intr,
|
Opt_intr,
|
||||||
Opt_local_lock,
|
Opt_local_lock,
|
||||||
@@ -83,7 +84,35 @@ enum nfs_param {
|
|||||||
Opt_wsize,
|
Opt_wsize,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct fs_parameter_spec nfs_param_specs[] = {
|
enum {
|
||||||
|
Opt_local_lock_all,
|
||||||
|
Opt_local_lock_flock,
|
||||||
|
Opt_local_lock_none,
|
||||||
|
Opt_local_lock_posix,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct constant_table nfs_param_enums_local_lock[] = {
|
||||||
|
{ "all", Opt_local_lock_all },
|
||||||
|
{ "flock", Opt_local_lock_flock },
|
||||||
|
{ "none", Opt_local_lock_none },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
Opt_lookupcache_all,
|
||||||
|
Opt_lookupcache_none,
|
||||||
|
Opt_lookupcache_positive,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct constant_table nfs_param_enums_lookupcache[] = {
|
||||||
|
{ "all", Opt_lookupcache_all },
|
||||||
|
{ "none", Opt_lookupcache_none },
|
||||||
|
{ "pos", Opt_lookupcache_positive },
|
||||||
|
{ "positive", Opt_lookupcache_positive },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct fs_parameter_spec nfs_fs_parameters[] = {
|
||||||
fsparam_flag_no("ac", Opt_ac),
|
fsparam_flag_no("ac", Opt_ac),
|
||||||
fsparam_u32 ("acdirmax", Opt_acdirmax),
|
fsparam_u32 ("acdirmax", Opt_acdirmax),
|
||||||
fsparam_u32 ("acdirmin", Opt_acdirmin),
|
fsparam_u32 ("acdirmin", Opt_acdirmin),
|
||||||
@@ -97,14 +126,14 @@ static const struct fs_parameter_spec nfs_param_specs[] = {
|
|||||||
fsparam_string("clientaddr", Opt_clientaddr),
|
fsparam_string("clientaddr", Opt_clientaddr),
|
||||||
fsparam_flag_no("cto", Opt_cto),
|
fsparam_flag_no("cto", Opt_cto),
|
||||||
fsparam_flag ("fg", Opt_fg),
|
fsparam_flag ("fg", Opt_fg),
|
||||||
__fsparam(fs_param_is_string, "fsc", Opt_fscache,
|
fsparam_flag_no("fsc", Opt_fscache_flag),
|
||||||
fs_param_neg_with_no|fs_param_v_optional),
|
fsparam_string("fsc", Opt_fscache),
|
||||||
fsparam_flag ("hard", Opt_hard),
|
fsparam_flag ("hard", Opt_hard),
|
||||||
__fsparam(fs_param_is_flag, "intr", Opt_intr,
|
__fsparam(NULL, "intr", Opt_intr,
|
||||||
fs_param_neg_with_no|fs_param_deprecated),
|
fs_param_neg_with_no|fs_param_deprecated, NULL),
|
||||||
fsparam_enum ("local_lock", Opt_local_lock),
|
fsparam_enum ("local_lock", Opt_local_lock, nfs_param_enums_local_lock),
|
||||||
fsparam_flag_no("lock", Opt_lock),
|
fsparam_flag_no("lock", Opt_lock),
|
||||||
fsparam_enum ("lookupcache", Opt_lookupcache),
|
fsparam_enum ("lookupcache", Opt_lookupcache, nfs_param_enums_lookupcache),
|
||||||
fsparam_flag_no("migration", Opt_migration),
|
fsparam_flag_no("migration", Opt_migration),
|
||||||
fsparam_u32 ("minorversion", Opt_minorversion),
|
fsparam_u32 ("minorversion", Opt_minorversion),
|
||||||
fsparam_string("mountaddr", Opt_mountaddr),
|
fsparam_string("mountaddr", Opt_mountaddr),
|
||||||
@@ -145,37 +174,6 @@ static const struct fs_parameter_spec nfs_param_specs[] = {
|
|||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
|
||||||
Opt_local_lock_all,
|
|
||||||
Opt_local_lock_flock,
|
|
||||||
Opt_local_lock_none,
|
|
||||||
Opt_local_lock_posix,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
|
||||||
Opt_lookupcache_all,
|
|
||||||
Opt_lookupcache_none,
|
|
||||||
Opt_lookupcache_positive,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct fs_parameter_enum nfs_param_enums[] = {
|
|
||||||
{ Opt_local_lock, "all", Opt_local_lock_all },
|
|
||||||
{ Opt_local_lock, "flock", Opt_local_lock_flock },
|
|
||||||
{ Opt_local_lock, "none", Opt_local_lock_none },
|
|
||||||
{ Opt_local_lock, "posix", Opt_local_lock_posix },
|
|
||||||
{ Opt_lookupcache, "all", Opt_lookupcache_all },
|
|
||||||
{ Opt_lookupcache, "none", Opt_lookupcache_none },
|
|
||||||
{ Opt_lookupcache, "pos", Opt_lookupcache_positive },
|
|
||||||
{ Opt_lookupcache, "positive", Opt_lookupcache_positive },
|
|
||||||
{}
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct fs_parameter_description nfs_fs_parameters = {
|
|
||||||
.name = "nfs",
|
|
||||||
.specs = nfs_param_specs,
|
|
||||||
.enums = nfs_param_enums,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
Opt_vers_2,
|
Opt_vers_2,
|
||||||
Opt_vers_3,
|
Opt_vers_3,
|
||||||
@@ -442,7 +440,7 @@ static int nfs_fs_context_parse_param(struct fs_context *fc,
|
|||||||
|
|
||||||
dfprintk(MOUNT, "NFS: parsing nfs mount option '%s'\n", param->key);
|
dfprintk(MOUNT, "NFS: parsing nfs mount option '%s'\n", param->key);
|
||||||
|
|
||||||
opt = fs_parse(fc, &nfs_fs_parameters, param, &result);
|
opt = fs_parse(fc, nfs_fs_parameters, param, &result);
|
||||||
if (opt < 0)
|
if (opt < 0)
|
||||||
return ctx->sloppy ? 1 : opt;
|
return ctx->sloppy ? 1 : opt;
|
||||||
|
|
||||||
@@ -540,14 +538,19 @@ static int nfs_fs_context_parse_param(struct fs_context *fc,
|
|||||||
else
|
else
|
||||||
ctx->flags &= ~NFS_MOUNT_NORESVPORT;
|
ctx->flags &= ~NFS_MOUNT_NORESVPORT;
|
||||||
break;
|
break;
|
||||||
case Opt_fscache:
|
case Opt_fscache_flag:
|
||||||
kfree(ctx->fscache_uniq);
|
|
||||||
ctx->fscache_uniq = param->string;
|
|
||||||
param->string = NULL;
|
|
||||||
if (result.negated)
|
if (result.negated)
|
||||||
ctx->options &= ~NFS_OPTION_FSCACHE;
|
ctx->options &= ~NFS_OPTION_FSCACHE;
|
||||||
else
|
else
|
||||||
ctx->options |= NFS_OPTION_FSCACHE;
|
ctx->options |= NFS_OPTION_FSCACHE;
|
||||||
|
kfree(ctx->fscache_uniq);
|
||||||
|
ctx->fscache_uniq = NULL;
|
||||||
|
break;
|
||||||
|
case Opt_fscache:
|
||||||
|
ctx->options |= NFS_OPTION_FSCACHE;
|
||||||
|
kfree(ctx->fscache_uniq);
|
||||||
|
ctx->fscache_uniq = param->string;
|
||||||
|
param->string = NULL;
|
||||||
break;
|
break;
|
||||||
case Opt_migration:
|
case Opt_migration:
|
||||||
if (result.negated)
|
if (result.negated)
|
||||||
@@ -1415,7 +1418,7 @@ struct file_system_type nfs_fs_type = {
|
|||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.name = "nfs",
|
.name = "nfs",
|
||||||
.init_fs_context = nfs_init_fs_context,
|
.init_fs_context = nfs_init_fs_context,
|
||||||
.parameters = &nfs_fs_parameters,
|
.parameters = nfs_fs_parameters,
|
||||||
.kill_sb = nfs_kill_super,
|
.kill_sb = nfs_kill_super,
|
||||||
.fs_flags = FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA,
|
.fs_flags = FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA,
|
||||||
};
|
};
|
||||||
@@ -1427,7 +1430,7 @@ struct file_system_type nfs4_fs_type = {
|
|||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.name = "nfs4",
|
.name = "nfs4",
|
||||||
.init_fs_context = nfs_init_fs_context,
|
.init_fs_context = nfs_init_fs_context,
|
||||||
.parameters = &nfs_fs_parameters,
|
.parameters = nfs_fs_parameters,
|
||||||
.kill_sb = nfs_kill_super,
|
.kill_sb = nfs_kill_super,
|
||||||
.fs_flags = FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA,
|
.fs_flags = FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA,
|
||||||
};
|
};
|
||||||
|
@@ -41,24 +41,19 @@ enum proc_param {
|
|||||||
Opt_hidepid,
|
Opt_hidepid,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct fs_parameter_spec proc_param_specs[] = {
|
static const struct fs_parameter_spec proc_fs_parameters[] = {
|
||||||
fsparam_u32("gid", Opt_gid),
|
fsparam_u32("gid", Opt_gid),
|
||||||
fsparam_u32("hidepid", Opt_hidepid),
|
fsparam_u32("hidepid", Opt_hidepid),
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct fs_parameter_description proc_fs_parameters = {
|
|
||||||
.name = "proc",
|
|
||||||
.specs = proc_param_specs,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int proc_parse_param(struct fs_context *fc, struct fs_parameter *param)
|
static int proc_parse_param(struct fs_context *fc, struct fs_parameter *param)
|
||||||
{
|
{
|
||||||
struct proc_fs_context *ctx = fc->fs_private;
|
struct proc_fs_context *ctx = fc->fs_private;
|
||||||
struct fs_parse_result result;
|
struct fs_parse_result result;
|
||||||
int opt;
|
int opt;
|
||||||
|
|
||||||
opt = fs_parse(fc, &proc_fs_parameters, param, &result);
|
opt = fs_parse(fc, proc_fs_parameters, param, &result);
|
||||||
if (opt < 0)
|
if (opt < 0)
|
||||||
return opt;
|
return opt;
|
||||||
|
|
||||||
@@ -71,7 +66,7 @@ static int proc_parse_param(struct fs_context *fc, struct fs_parameter *param)
|
|||||||
ctx->hidepid = result.uint_32;
|
ctx->hidepid = result.uint_32;
|
||||||
if (ctx->hidepid < HIDEPID_OFF ||
|
if (ctx->hidepid < HIDEPID_OFF ||
|
||||||
ctx->hidepid > HIDEPID_INVISIBLE)
|
ctx->hidepid > HIDEPID_INVISIBLE)
|
||||||
return invalf(fc, "proc: hidepid value must be between 0 and 2.\n");
|
return invalfc(fc, "hidepid value must be between 0 and 2.\n");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -207,7 +202,7 @@ static void proc_kill_sb(struct super_block *sb)
|
|||||||
static struct file_system_type proc_fs_type = {
|
static struct file_system_type proc_fs_type = {
|
||||||
.name = "proc",
|
.name = "proc",
|
||||||
.init_fs_context = proc_init_fs_context,
|
.init_fs_context = proc_init_fs_context,
|
||||||
.parameters = &proc_fs_parameters,
|
.parameters = proc_fs_parameters,
|
||||||
.kill_sb = proc_kill_sb,
|
.kill_sb = proc_kill_sb,
|
||||||
.fs_flags = FS_USERNS_MOUNT | FS_DISALLOW_NOTIFY_PERM,
|
.fs_flags = FS_USERNS_MOUNT | FS_DISALLOW_NOTIFY_PERM,
|
||||||
};
|
};
|
||||||
|
@@ -181,23 +181,18 @@ enum ramfs_param {
|
|||||||
Opt_mode,
|
Opt_mode,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct fs_parameter_spec ramfs_param_specs[] = {
|
const struct fs_parameter_spec ramfs_fs_parameters[] = {
|
||||||
fsparam_u32oct("mode", Opt_mode),
|
fsparam_u32oct("mode", Opt_mode),
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct fs_parameter_description ramfs_fs_parameters = {
|
|
||||||
.name = "ramfs",
|
|
||||||
.specs = ramfs_param_specs,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int ramfs_parse_param(struct fs_context *fc, struct fs_parameter *param)
|
static int ramfs_parse_param(struct fs_context *fc, struct fs_parameter *param)
|
||||||
{
|
{
|
||||||
struct fs_parse_result result;
|
struct fs_parse_result result;
|
||||||
struct ramfs_fs_info *fsi = fc->s_fs_info;
|
struct ramfs_fs_info *fsi = fc->s_fs_info;
|
||||||
int opt;
|
int opt;
|
||||||
|
|
||||||
opt = fs_parse(fc, &ramfs_fs_parameters, param, &result);
|
opt = fs_parse(fc, ramfs_fs_parameters, param, &result);
|
||||||
if (opt < 0) {
|
if (opt < 0) {
|
||||||
/*
|
/*
|
||||||
* We might like to report bad mount options here;
|
* We might like to report bad mount options here;
|
||||||
@@ -278,7 +273,7 @@ static void ramfs_kill_sb(struct super_block *sb)
|
|||||||
static struct file_system_type ramfs_fs_type = {
|
static struct file_system_type ramfs_fs_type = {
|
||||||
.name = "ramfs",
|
.name = "ramfs",
|
||||||
.init_fs_context = ramfs_init_fs_context,
|
.init_fs_context = ramfs_init_fs_context,
|
||||||
.parameters = &ramfs_fs_parameters,
|
.parameters = ramfs_fs_parameters,
|
||||||
.kill_sb = ramfs_kill_sb,
|
.kill_sb = ramfs_kill_sb,
|
||||||
.fs_flags = FS_USERNS_MOUNT,
|
.fs_flags = FS_USERNS_MOUNT,
|
||||||
};
|
};
|
||||||
|
@@ -62,7 +62,7 @@ enum {
|
|||||||
Opt_discard, Opt_nodiscard, Opt_dax,
|
Opt_discard, Opt_nodiscard, Opt_dax,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct fs_parameter_spec xfs_param_specs[] = {
|
static const struct fs_parameter_spec xfs_fs_parameters[] = {
|
||||||
fsparam_u32("logbufs", Opt_logbufs),
|
fsparam_u32("logbufs", Opt_logbufs),
|
||||||
fsparam_string("logbsize", Opt_logbsize),
|
fsparam_string("logbsize", Opt_logbsize),
|
||||||
fsparam_string("logdev", Opt_logdev),
|
fsparam_string("logdev", Opt_logdev),
|
||||||
@@ -106,11 +106,6 @@ static const struct fs_parameter_spec xfs_param_specs[] = {
|
|||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct fs_parameter_description xfs_fs_parameters = {
|
|
||||||
.name = "xfs",
|
|
||||||
.specs = xfs_param_specs,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct proc_xfs_info {
|
struct proc_xfs_info {
|
||||||
uint64_t flag;
|
uint64_t flag;
|
||||||
char *str;
|
char *str;
|
||||||
@@ -1120,7 +1115,7 @@ xfs_fc_parse_param(
|
|||||||
int size = 0;
|
int size = 0;
|
||||||
int opt;
|
int opt;
|
||||||
|
|
||||||
opt = fs_parse(fc, &xfs_fs_parameters, param, &result);
|
opt = fs_parse(fc, xfs_fs_parameters, param, &result);
|
||||||
if (opt < 0)
|
if (opt < 0)
|
||||||
return opt;
|
return opt;
|
||||||
|
|
||||||
@@ -1782,7 +1777,7 @@ static struct file_system_type xfs_fs_type = {
|
|||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.name = "xfs",
|
.name = "xfs",
|
||||||
.init_fs_context = xfs_init_fs_context,
|
.init_fs_context = xfs_init_fs_context,
|
||||||
.parameters = &xfs_fs_parameters,
|
.parameters = xfs_fs_parameters,
|
||||||
.kill_sb = kill_block_super,
|
.kill_sb = kill_block_super,
|
||||||
.fs_flags = FS_REQUIRES_DEV,
|
.fs_flags = FS_REQUIRES_DEV,
|
||||||
};
|
};
|
||||||
|
@@ -281,11 +281,12 @@ extern int ceph_check_fsid(struct ceph_client *client, struct ceph_fsid *fsid);
|
|||||||
extern void *ceph_kvmalloc(size_t size, gfp_t flags);
|
extern void *ceph_kvmalloc(size_t size, gfp_t flags);
|
||||||
|
|
||||||
struct fs_parameter;
|
struct fs_parameter;
|
||||||
|
struct fc_log;
|
||||||
struct ceph_options *ceph_alloc_options(void);
|
struct ceph_options *ceph_alloc_options(void);
|
||||||
int ceph_parse_mon_ips(const char *buf, size_t len, struct ceph_options *opt,
|
int ceph_parse_mon_ips(const char *buf, size_t len, struct ceph_options *opt,
|
||||||
struct fs_context *fc);
|
struct fc_log *l);
|
||||||
int ceph_parse_param(struct fs_parameter *param, struct ceph_options *opt,
|
int ceph_parse_param(struct fs_parameter *param, struct ceph_options *opt,
|
||||||
struct fs_context *fc);
|
struct fc_log *l);
|
||||||
int ceph_print_client_options(struct seq_file *m, struct ceph_client *client,
|
int ceph_print_client_options(struct seq_file *m, struct ceph_client *client,
|
||||||
bool show_all);
|
bool show_all);
|
||||||
extern void ceph_destroy_options(struct ceph_options *opt);
|
extern void ceph_destroy_options(struct ceph_options *opt);
|
||||||
|
@@ -67,7 +67,7 @@ struct fscrypt_operations;
|
|||||||
struct fsverity_info;
|
struct fsverity_info;
|
||||||
struct fsverity_operations;
|
struct fsverity_operations;
|
||||||
struct fs_context;
|
struct fs_context;
|
||||||
struct fs_parameter_description;
|
struct fs_parameter_spec;
|
||||||
|
|
||||||
extern void __init inode_init(void);
|
extern void __init inode_init(void);
|
||||||
extern void __init inode_init_early(void);
|
extern void __init inode_init_early(void);
|
||||||
@@ -2252,7 +2252,7 @@ struct file_system_type {
|
|||||||
#define FS_DISALLOW_NOTIFY_PERM 16 /* Disable fanotify permission events */
|
#define FS_DISALLOW_NOTIFY_PERM 16 /* Disable fanotify permission events */
|
||||||
#define FS_RENAME_DOES_D_MOVE 32768 /* FS will handle d_move() during rename() internally. */
|
#define FS_RENAME_DOES_D_MOVE 32768 /* FS will handle d_move() during rename() internally. */
|
||||||
int (*init_fs_context)(struct fs_context *);
|
int (*init_fs_context)(struct fs_context *);
|
||||||
const struct fs_parameter_description *parameters;
|
const struct fs_parameter_spec *parameters;
|
||||||
struct dentry *(*mount) (struct file_system_type *, int,
|
struct dentry *(*mount) (struct file_system_type *, int,
|
||||||
const char *, void *);
|
const char *, void *);
|
||||||
void *(*alloc_mnt_data) (void);
|
void *(*alloc_mnt_data) (void);
|
||||||
|
@@ -54,7 +54,6 @@ enum fs_value_type {
|
|||||||
fs_value_is_string, /* Value is a string */
|
fs_value_is_string, /* Value is a string */
|
||||||
fs_value_is_blob, /* Value is a binary blob */
|
fs_value_is_blob, /* Value is a binary blob */
|
||||||
fs_value_is_filename, /* Value is a filename* + dirfd */
|
fs_value_is_filename, /* Value is a filename* + dirfd */
|
||||||
fs_value_is_filename_empty, /* Value is a filename* + dirfd + AT_EMPTY_PATH */
|
|
||||||
fs_value_is_file, /* Value is a file* */
|
fs_value_is_file, /* Value is a file* */
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -74,6 +73,11 @@ struct fs_parameter {
|
|||||||
int dirfd;
|
int dirfd;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct p_log {
|
||||||
|
const char *prefix;
|
||||||
|
struct fc_log *log;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Filesystem context for holding the parameters used in the creation or
|
* Filesystem context for holding the parameters used in the creation or
|
||||||
* reconfiguration of a superblock.
|
* reconfiguration of a superblock.
|
||||||
@@ -93,7 +97,7 @@ struct fs_context {
|
|||||||
struct user_namespace *user_ns; /* The user namespace for this mount */
|
struct user_namespace *user_ns; /* The user namespace for this mount */
|
||||||
struct net *net_ns; /* The network namespace for this mount */
|
struct net *net_ns; /* The network namespace for this mount */
|
||||||
const struct cred *cred; /* The mounter's credentials */
|
const struct cred *cred; /* The mounter's credentials */
|
||||||
struct fc_log *log; /* Logging buffer */
|
struct p_log log; /* Logging buffer */
|
||||||
const char *source; /* The source name (eg. dev path) */
|
const char *source; /* The source name (eg. dev path) */
|
||||||
void *security; /* Linux S&M options */
|
void *security; /* Linux S&M options */
|
||||||
void *s_fs_info; /* Proposed s_fs_info */
|
void *s_fs_info; /* Proposed s_fs_info */
|
||||||
@@ -182,9 +186,13 @@ struct fc_log {
|
|||||||
char *buffer[8];
|
char *buffer[8];
|
||||||
};
|
};
|
||||||
|
|
||||||
extern __attribute__((format(printf, 2, 3)))
|
extern __attribute__((format(printf, 4, 5)))
|
||||||
void logfc(struct fs_context *fc, const char *fmt, ...);
|
void logfc(struct fc_log *log, const char *prefix, char level, const char *fmt, ...);
|
||||||
|
|
||||||
|
#define __logfc(fc, l, fmt, ...) logfc((fc)->log.log, NULL, \
|
||||||
|
l, fmt, ## __VA_ARGS__)
|
||||||
|
#define __plog(p, l, fmt, ...) logfc((p)->log, (p)->prefix, \
|
||||||
|
l, fmt, ## __VA_ARGS__)
|
||||||
/**
|
/**
|
||||||
* infof - Store supplementary informational message
|
* infof - Store supplementary informational message
|
||||||
* @fc: The context in which to log the informational message
|
* @fc: The context in which to log the informational message
|
||||||
@@ -193,7 +201,9 @@ void logfc(struct fs_context *fc, const char *fmt, ...);
|
|||||||
* Store the supplementary informational message for the process if the process
|
* Store the supplementary informational message for the process if the process
|
||||||
* has enabled the facility.
|
* has enabled the facility.
|
||||||
*/
|
*/
|
||||||
#define infof(fc, fmt, ...) ({ logfc(fc, "i "fmt, ## __VA_ARGS__); })
|
#define infof(fc, fmt, ...) __logfc(fc, 'i', fmt, ## __VA_ARGS__)
|
||||||
|
#define info_plog(p, fmt, ...) __plog(p, 'i', fmt, ## __VA_ARGS__)
|
||||||
|
#define infofc(p, fmt, ...) __plog((&(fc)->log), 'i', fmt, ## __VA_ARGS__)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* warnf - Store supplementary warning message
|
* warnf - Store supplementary warning message
|
||||||
@@ -203,7 +213,9 @@ void logfc(struct fs_context *fc, const char *fmt, ...);
|
|||||||
* Store the supplementary warning message for the process if the process has
|
* Store the supplementary warning message for the process if the process has
|
||||||
* enabled the facility.
|
* enabled the facility.
|
||||||
*/
|
*/
|
||||||
#define warnf(fc, fmt, ...) ({ logfc(fc, "w "fmt, ## __VA_ARGS__); })
|
#define warnf(fc, fmt, ...) __logfc(fc, 'w', fmt, ## __VA_ARGS__)
|
||||||
|
#define warn_plog(p, fmt, ...) __plog(p, 'w', fmt, ## __VA_ARGS__)
|
||||||
|
#define warnfc(fc, fmt, ...) __plog((&(fc)->log), 'w', fmt, ## __VA_ARGS__)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* errorf - Store supplementary error message
|
* errorf - Store supplementary error message
|
||||||
@@ -213,7 +225,9 @@ void logfc(struct fs_context *fc, const char *fmt, ...);
|
|||||||
* Store the supplementary error message for the process if the process has
|
* Store the supplementary error message for the process if the process has
|
||||||
* enabled the facility.
|
* enabled the facility.
|
||||||
*/
|
*/
|
||||||
#define errorf(fc, fmt, ...) ({ logfc(fc, "e "fmt, ## __VA_ARGS__); })
|
#define errorf(fc, fmt, ...) __logfc(fc, 'e', fmt, ## __VA_ARGS__)
|
||||||
|
#define error_plog(p, fmt, ...) __plog(p, 'e', fmt, ## __VA_ARGS__)
|
||||||
|
#define errorfc(fc, fmt, ...) __plog((&(fc)->log), 'e', fmt, ## __VA_ARGS__)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* invalf - Store supplementary invalid argument error message
|
* invalf - Store supplementary invalid argument error message
|
||||||
@@ -223,6 +237,8 @@ void logfc(struct fs_context *fc, const char *fmt, ...);
|
|||||||
* Store the supplementary error message for the process if the process has
|
* Store the supplementary error message for the process if the process has
|
||||||
* enabled the facility and return -EINVAL.
|
* enabled the facility and return -EINVAL.
|
||||||
*/
|
*/
|
||||||
#define invalf(fc, fmt, ...) ({ errorf(fc, fmt, ## __VA_ARGS__); -EINVAL; })
|
#define invalf(fc, fmt, ...) (errorf(fc, fmt, ## __VA_ARGS__), -EINVAL)
|
||||||
|
#define inval_plog(p, fmt, ...) (error_plog(p, fmt, ## __VA_ARGS__), -EINVAL)
|
||||||
|
#define invalfc(fc, fmt, ...) (errorfc(fc, fmt, ## __VA_ARGS__), -EINVAL)
|
||||||
|
|
||||||
#endif /* _LINUX_FS_CONTEXT_H */
|
#endif /* _LINUX_FS_CONTEXT_H */
|
||||||
|
@@ -17,26 +17,18 @@ struct constant_table {
|
|||||||
int value;
|
int value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct fs_parameter_spec;
|
||||||
|
struct fs_parse_result;
|
||||||
|
typedef int fs_param_type(struct p_log *,
|
||||||
|
const struct fs_parameter_spec *,
|
||||||
|
struct fs_parameter *,
|
||||||
|
struct fs_parse_result *);
|
||||||
/*
|
/*
|
||||||
* The type of parameter expected.
|
* The type of parameter expected.
|
||||||
*/
|
*/
|
||||||
enum fs_parameter_type {
|
fs_param_type fs_param_is_bool, fs_param_is_u32, fs_param_is_s32, fs_param_is_u64,
|
||||||
__fs_param_wasnt_defined,
|
fs_param_is_enum, fs_param_is_string, fs_param_is_blob, fs_param_is_blockdev,
|
||||||
fs_param_is_flag,
|
fs_param_is_path, fs_param_is_fd;
|
||||||
fs_param_is_bool,
|
|
||||||
fs_param_is_u32,
|
|
||||||
fs_param_is_u32_octal,
|
|
||||||
fs_param_is_u32_hex,
|
|
||||||
fs_param_is_s32,
|
|
||||||
fs_param_is_u64,
|
|
||||||
fs_param_is_enum,
|
|
||||||
fs_param_is_string,
|
|
||||||
fs_param_is_blob,
|
|
||||||
fs_param_is_blockdev,
|
|
||||||
fs_param_is_path,
|
|
||||||
fs_param_is_fd,
|
|
||||||
nr__fs_parameter_type,
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Specification of the type of value a parameter wants.
|
* Specification of the type of value a parameter wants.
|
||||||
@@ -46,25 +38,13 @@ enum fs_parameter_type {
|
|||||||
*/
|
*/
|
||||||
struct fs_parameter_spec {
|
struct fs_parameter_spec {
|
||||||
const char *name;
|
const char *name;
|
||||||
|
fs_param_type *type; /* The desired parameter type */
|
||||||
u8 opt; /* Option number (returned by fs_parse()) */
|
u8 opt; /* Option number (returned by fs_parse()) */
|
||||||
enum fs_parameter_type type:8; /* The desired parameter type */
|
|
||||||
unsigned short flags;
|
unsigned short flags;
|
||||||
#define fs_param_v_optional 0x0001 /* The value is optional */
|
|
||||||
#define fs_param_neg_with_no 0x0002 /* "noxxx" is negative param */
|
#define fs_param_neg_with_no 0x0002 /* "noxxx" is negative param */
|
||||||
#define fs_param_neg_with_empty 0x0004 /* "xxx=" is negative param */
|
#define fs_param_neg_with_empty 0x0004 /* "xxx=" is negative param */
|
||||||
#define fs_param_deprecated 0x0008 /* The param is deprecated */
|
#define fs_param_deprecated 0x0008 /* The param is deprecated */
|
||||||
};
|
const void *data;
|
||||||
|
|
||||||
struct fs_parameter_enum {
|
|
||||||
u8 opt; /* Option number (as fs_parameter_spec::opt) */
|
|
||||||
char name[14];
|
|
||||||
u8 value;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct fs_parameter_description {
|
|
||||||
const char name[16]; /* Name for logging purposes */
|
|
||||||
const struct fs_parameter_spec *specs; /* List of param specifications */
|
|
||||||
const struct fs_parameter_enum *enums; /* Enum values */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -72,7 +52,6 @@ struct fs_parameter_description {
|
|||||||
*/
|
*/
|
||||||
struct fs_parse_result {
|
struct fs_parse_result {
|
||||||
bool negated; /* T if param was "noxxx" */
|
bool negated; /* T if param was "noxxx" */
|
||||||
bool has_value; /* T if value supplied to param */
|
|
||||||
union {
|
union {
|
||||||
bool boolean; /* For spec_bool */
|
bool boolean; /* For spec_bool */
|
||||||
int int_32; /* For spec_s32/spec_enum */
|
int int_32; /* For spec_s32/spec_enum */
|
||||||
@@ -81,28 +60,37 @@ struct fs_parse_result {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
extern int fs_parse(struct fs_context *fc,
|
extern int __fs_parse(struct p_log *log,
|
||||||
const struct fs_parameter_description *desc,
|
const struct fs_parameter_spec *desc,
|
||||||
struct fs_parameter *value,
|
struct fs_parameter *value,
|
||||||
struct fs_parse_result *result);
|
struct fs_parse_result *result);
|
||||||
|
|
||||||
|
static inline int fs_parse(struct fs_context *fc,
|
||||||
|
const struct fs_parameter_spec *desc,
|
||||||
|
struct fs_parameter *param,
|
||||||
|
struct fs_parse_result *result)
|
||||||
|
{
|
||||||
|
return __fs_parse(&fc->log, desc, param, result);
|
||||||
|
}
|
||||||
|
|
||||||
extern int fs_lookup_param(struct fs_context *fc,
|
extern int fs_lookup_param(struct fs_context *fc,
|
||||||
struct fs_parameter *param,
|
struct fs_parameter *param,
|
||||||
bool want_bdev,
|
bool want_bdev,
|
||||||
struct path *_path);
|
struct path *_path);
|
||||||
|
|
||||||
extern int __lookup_constant(const struct constant_table tbl[], size_t tbl_size,
|
extern int lookup_constant(const struct constant_table tbl[], const char *name, int not_found);
|
||||||
const char *name, int not_found);
|
|
||||||
#define lookup_constant(t, n, nf) __lookup_constant(t, ARRAY_SIZE(t), (n), (nf))
|
|
||||||
|
|
||||||
#ifdef CONFIG_VALIDATE_FS_PARSER
|
#ifdef CONFIG_VALIDATE_FS_PARSER
|
||||||
extern bool validate_constant_table(const struct constant_table *tbl, size_t tbl_size,
|
extern bool validate_constant_table(const struct constant_table *tbl, size_t tbl_size,
|
||||||
int low, int high, int special);
|
int low, int high, int special);
|
||||||
extern bool fs_validate_description(const struct fs_parameter_description *desc);
|
extern bool fs_validate_description(const char *name,
|
||||||
|
const struct fs_parameter_spec *desc);
|
||||||
#else
|
#else
|
||||||
static inline bool validate_constant_table(const struct constant_table *tbl, size_t tbl_size,
|
static inline bool validate_constant_table(const struct constant_table *tbl, size_t tbl_size,
|
||||||
int low, int high, int special)
|
int low, int high, int special)
|
||||||
{ return true; }
|
{ return true; }
|
||||||
static inline bool fs_validate_description(const struct fs_parameter_description *desc)
|
static inline bool fs_validate_description(const char *name,
|
||||||
|
const struct fs_parameter_spec *desc)
|
||||||
{ return true; }
|
{ return true; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -115,33 +103,32 @@ static inline bool fs_validate_description(const struct fs_parameter_description
|
|||||||
* work, but any such case is probably a sign that new helper is needed.
|
* work, but any such case is probably a sign that new helper is needed.
|
||||||
* Helpers will remain stable; low-level implementation may change.
|
* Helpers will remain stable; low-level implementation may change.
|
||||||
*/
|
*/
|
||||||
#define __fsparam(TYPE, NAME, OPT, FLAGS) \
|
#define __fsparam(TYPE, NAME, OPT, FLAGS, DATA) \
|
||||||
{ \
|
{ \
|
||||||
.name = NAME, \
|
.name = NAME, \
|
||||||
.opt = OPT, \
|
.opt = OPT, \
|
||||||
.type = TYPE, \
|
.type = TYPE, \
|
||||||
.flags = FLAGS \
|
.flags = FLAGS, \
|
||||||
|
.data = DATA \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define fsparam_flag(NAME, OPT) __fsparam(fs_param_is_flag, NAME, OPT, 0)
|
#define fsparam_flag(NAME, OPT) __fsparam(NULL, NAME, OPT, 0, NULL)
|
||||||
#define fsparam_flag_no(NAME, OPT) \
|
#define fsparam_flag_no(NAME, OPT) \
|
||||||
__fsparam(fs_param_is_flag, NAME, OPT, \
|
__fsparam(NULL, NAME, OPT, fs_param_neg_with_no, NULL)
|
||||||
fs_param_neg_with_no)
|
#define fsparam_bool(NAME, OPT) __fsparam(fs_param_is_bool, NAME, OPT, 0, NULL)
|
||||||
#define fsparam_bool(NAME, OPT) __fsparam(fs_param_is_bool, NAME, OPT, 0)
|
#define fsparam_u32(NAME, OPT) __fsparam(fs_param_is_u32, NAME, OPT, 0, NULL)
|
||||||
#define fsparam_u32(NAME, OPT) __fsparam(fs_param_is_u32, NAME, OPT, 0)
|
|
||||||
#define fsparam_u32oct(NAME, OPT) \
|
#define fsparam_u32oct(NAME, OPT) \
|
||||||
__fsparam(fs_param_is_u32_octal, NAME, OPT, 0)
|
__fsparam(fs_param_is_u32, NAME, OPT, 0, (void *)8)
|
||||||
#define fsparam_u32hex(NAME, OPT) \
|
#define fsparam_u32hex(NAME, OPT) \
|
||||||
__fsparam(fs_param_is_u32_hex, NAME, OPT, 0)
|
__fsparam(fs_param_is_u32_hex, NAME, OPT, 0, (void *16))
|
||||||
#define fsparam_s32(NAME, OPT) __fsparam(fs_param_is_s32, NAME, OPT, 0)
|
#define fsparam_s32(NAME, OPT) __fsparam(fs_param_is_s32, NAME, OPT, 0, NULL)
|
||||||
#define fsparam_u64(NAME, OPT) __fsparam(fs_param_is_u64, NAME, OPT, 0)
|
#define fsparam_u64(NAME, OPT) __fsparam(fs_param_is_u64, NAME, OPT, 0, NULL)
|
||||||
#define fsparam_enum(NAME, OPT) __fsparam(fs_param_is_enum, NAME, OPT, 0)
|
#define fsparam_enum(NAME, OPT, array) __fsparam(fs_param_is_enum, NAME, OPT, 0, array)
|
||||||
#define fsparam_string(NAME, OPT) \
|
#define fsparam_string(NAME, OPT) \
|
||||||
__fsparam(fs_param_is_string, NAME, OPT, 0)
|
__fsparam(fs_param_is_string, NAME, OPT, 0, NULL)
|
||||||
#define fsparam_blob(NAME, OPT) __fsparam(fs_param_is_blob, NAME, OPT, 0)
|
#define fsparam_blob(NAME, OPT) __fsparam(fs_param_is_blob, NAME, OPT, 0, NULL)
|
||||||
#define fsparam_bdev(NAME, OPT) __fsparam(fs_param_is_blockdev, NAME, OPT, 0)
|
#define fsparam_bdev(NAME, OPT) __fsparam(fs_param_is_blockdev, NAME, OPT, 0, NULL)
|
||||||
#define fsparam_path(NAME, OPT) __fsparam(fs_param_is_path, NAME, OPT, 0)
|
#define fsparam_path(NAME, OPT) __fsparam(fs_param_is_path, NAME, OPT, 0, NULL)
|
||||||
#define fsparam_fd(NAME, OPT) __fsparam(fs_param_is_fd, NAME, OPT, 0)
|
#define fsparam_fd(NAME, OPT) __fsparam(fs_param_is_fd, NAME, OPT, 0, NULL)
|
||||||
|
|
||||||
|
|
||||||
#endif /* _LINUX_FS_PARSER_H */
|
#endif /* _LINUX_FS_PARSER_H */
|
||||||
|
@@ -2,6 +2,8 @@
|
|||||||
#ifndef _LINUX_RAMFS_H
|
#ifndef _LINUX_RAMFS_H
|
||||||
#define _LINUX_RAMFS_H
|
#define _LINUX_RAMFS_H
|
||||||
|
|
||||||
|
#include <linux/fs_parser.h> // bleh...
|
||||||
|
|
||||||
struct inode *ramfs_get_inode(struct super_block *sb, const struct inode *dir,
|
struct inode *ramfs_get_inode(struct super_block *sb, const struct inode *dir,
|
||||||
umode_t mode, dev_t dev);
|
umode_t mode, dev_t dev);
|
||||||
extern int ramfs_init_fs_context(struct fs_context *fc);
|
extern int ramfs_init_fs_context(struct fs_context *fc);
|
||||||
@@ -16,7 +18,7 @@ ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize)
|
|||||||
extern int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize);
|
extern int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern const struct fs_parameter_description ramfs_fs_parameters;
|
extern const struct fs_parameter_spec ramfs_fs_parameters[];
|
||||||
extern const struct file_operations ramfs_file_operations;
|
extern const struct file_operations ramfs_file_operations;
|
||||||
extern const struct vm_operations_struct generic_file_vm_ops;
|
extern const struct vm_operations_struct generic_file_vm_ops;
|
||||||
|
|
||||||
|
@@ -8,6 +8,7 @@
|
|||||||
#include <linux/pagemap.h>
|
#include <linux/pagemap.h>
|
||||||
#include <linux/percpu_counter.h>
|
#include <linux/percpu_counter.h>
|
||||||
#include <linux/xattr.h>
|
#include <linux/xattr.h>
|
||||||
|
#include <linux/fs_parser.h>
|
||||||
|
|
||||||
/* inode in-kernel data */
|
/* inode in-kernel data */
|
||||||
|
|
||||||
@@ -49,7 +50,7 @@ static inline struct shmem_inode_info *SHMEM_I(struct inode *inode)
|
|||||||
/*
|
/*
|
||||||
* Functions in mm/shmem.c called directly from elsewhere:
|
* Functions in mm/shmem.c called directly from elsewhere:
|
||||||
*/
|
*/
|
||||||
extern const struct fs_parameter_description shmem_fs_parameters;
|
extern const struct fs_parameter_spec shmem_fs_parameters[];
|
||||||
extern int shmem_init(void);
|
extern int shmem_init(void);
|
||||||
extern int shmem_init_fs_context(struct fs_context *fc);
|
extern int shmem_init_fs_context(struct fs_context *fc);
|
||||||
extern struct file *shmem_file_setup(const char *name,
|
extern struct file *shmem_file_setup(const char *name,
|
||||||
|
@@ -569,16 +569,11 @@ enum {
|
|||||||
OPT_MODE,
|
OPT_MODE,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct fs_parameter_spec bpf_param_specs[] = {
|
static const struct fs_parameter_spec bpf_fs_parameters[] = {
|
||||||
fsparam_u32oct ("mode", OPT_MODE),
|
fsparam_u32oct ("mode", OPT_MODE),
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct fs_parameter_description bpf_fs_parameters = {
|
|
||||||
.name = "bpf",
|
|
||||||
.specs = bpf_param_specs,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct bpf_mount_opts {
|
struct bpf_mount_opts {
|
||||||
umode_t mode;
|
umode_t mode;
|
||||||
};
|
};
|
||||||
@@ -589,7 +584,7 @@ static int bpf_parse_param(struct fs_context *fc, struct fs_parameter *param)
|
|||||||
struct fs_parse_result result;
|
struct fs_parse_result result;
|
||||||
int opt;
|
int opt;
|
||||||
|
|
||||||
opt = fs_parse(fc, &bpf_fs_parameters, param, &result);
|
opt = fs_parse(fc, bpf_fs_parameters, param, &result);
|
||||||
if (opt < 0)
|
if (opt < 0)
|
||||||
/* We might like to report bad mount options here, but
|
/* We might like to report bad mount options here, but
|
||||||
* traditionally we've ignored all mount options, so we'd
|
* traditionally we've ignored all mount options, so we'd
|
||||||
@@ -665,7 +660,7 @@ static struct file_system_type bpf_fs_type = {
|
|||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.name = "bpf",
|
.name = "bpf",
|
||||||
.init_fs_context = bpf_init_fs_context,
|
.init_fs_context = bpf_init_fs_context,
|
||||||
.parameters = &bpf_fs_parameters,
|
.parameters = bpf_fs_parameters,
|
||||||
.kill_sb = kill_litter_super,
|
.kill_sb = kill_litter_super,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
#include <linux/workqueue.h>
|
#include <linux/workqueue.h>
|
||||||
#include <linux/list.h>
|
#include <linux/list.h>
|
||||||
#include <linux/refcount.h>
|
#include <linux/refcount.h>
|
||||||
#include <linux/fs_context.h>
|
#include <linux/fs_parser.h>
|
||||||
|
|
||||||
#define TRACE_CGROUP_PATH_LEN 1024
|
#define TRACE_CGROUP_PATH_LEN 1024
|
||||||
extern spinlock_t trace_cgroup_path_lock;
|
extern spinlock_t trace_cgroup_path_lock;
|
||||||
@@ -265,7 +265,7 @@ extern const struct proc_ns_operations cgroupns_operations;
|
|||||||
*/
|
*/
|
||||||
extern struct cftype cgroup1_base_files[];
|
extern struct cftype cgroup1_base_files[];
|
||||||
extern struct kernfs_syscall_ops cgroup1_kf_syscall_ops;
|
extern struct kernfs_syscall_ops cgroup1_kf_syscall_ops;
|
||||||
extern const struct fs_parameter_description cgroup1_fs_parameters;
|
extern const struct fs_parameter_spec cgroup1_fs_parameters[];
|
||||||
|
|
||||||
int proc_cgroupstats_show(struct seq_file *m, void *v);
|
int proc_cgroupstats_show(struct seq_file *m, void *v);
|
||||||
bool cgroup1_ssid_disabled(int ssid);
|
bool cgroup1_ssid_disabled(int ssid);
|
||||||
|
@@ -18,8 +18,6 @@
|
|||||||
|
|
||||||
#include <trace/events/cgroup.h>
|
#include <trace/events/cgroup.h>
|
||||||
|
|
||||||
#define cg_invalf(fc, fmt, ...) invalf(fc, fmt, ## __VA_ARGS__)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* pidlists linger the following amount before being destroyed. The goal
|
* pidlists linger the following amount before being destroyed. The goal
|
||||||
* is avoiding frequent destruction in the middle of consecutive read calls
|
* is avoiding frequent destruction in the middle of consecutive read calls
|
||||||
@@ -888,7 +886,7 @@ enum cgroup1_param {
|
|||||||
Opt_xattr,
|
Opt_xattr,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct fs_parameter_spec cgroup1_param_specs[] = {
|
const struct fs_parameter_spec cgroup1_fs_parameters[] = {
|
||||||
fsparam_flag ("all", Opt_all),
|
fsparam_flag ("all", Opt_all),
|
||||||
fsparam_flag ("clone_children", Opt_clone_children),
|
fsparam_flag ("clone_children", Opt_clone_children),
|
||||||
fsparam_flag ("cpuset_v2_mode", Opt_cpuset_v2_mode),
|
fsparam_flag ("cpuset_v2_mode", Opt_cpuset_v2_mode),
|
||||||
@@ -900,11 +898,6 @@ static const struct fs_parameter_spec cgroup1_param_specs[] = {
|
|||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct fs_parameter_description cgroup1_fs_parameters = {
|
|
||||||
.name = "cgroup1",
|
|
||||||
.specs = cgroup1_param_specs,
|
|
||||||
};
|
|
||||||
|
|
||||||
int cgroup1_parse_param(struct fs_context *fc, struct fs_parameter *param)
|
int cgroup1_parse_param(struct fs_context *fc, struct fs_parameter *param)
|
||||||
{
|
{
|
||||||
struct cgroup_fs_context *ctx = cgroup_fc2context(fc);
|
struct cgroup_fs_context *ctx = cgroup_fc2context(fc);
|
||||||
@@ -912,7 +905,7 @@ int cgroup1_parse_param(struct fs_context *fc, struct fs_parameter *param)
|
|||||||
struct fs_parse_result result;
|
struct fs_parse_result result;
|
||||||
int opt, i;
|
int opt, i;
|
||||||
|
|
||||||
opt = fs_parse(fc, &cgroup1_fs_parameters, param, &result);
|
opt = fs_parse(fc, cgroup1_fs_parameters, param, &result);
|
||||||
if (opt == -ENOPARAM) {
|
if (opt == -ENOPARAM) {
|
||||||
if (strcmp(param->key, "source") == 0) {
|
if (strcmp(param->key, "source") == 0) {
|
||||||
fc->source = param->string;
|
fc->source = param->string;
|
||||||
@@ -925,7 +918,7 @@ int cgroup1_parse_param(struct fs_context *fc, struct fs_parameter *param)
|
|||||||
ctx->subsys_mask |= (1 << i);
|
ctx->subsys_mask |= (1 << i);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return cg_invalf(fc, "cgroup1: Unknown subsys name '%s'", param->key);
|
return invalfc(fc, "Unknown subsys name '%s'", param->key);
|
||||||
}
|
}
|
||||||
if (opt < 0)
|
if (opt < 0)
|
||||||
return opt;
|
return opt;
|
||||||
@@ -953,7 +946,7 @@ int cgroup1_parse_param(struct fs_context *fc, struct fs_parameter *param)
|
|||||||
case Opt_release_agent:
|
case Opt_release_agent:
|
||||||
/* Specifying two release agents is forbidden */
|
/* Specifying two release agents is forbidden */
|
||||||
if (ctx->release_agent)
|
if (ctx->release_agent)
|
||||||
return cg_invalf(fc, "cgroup1: release_agent respecified");
|
return invalfc(fc, "release_agent respecified");
|
||||||
ctx->release_agent = param->string;
|
ctx->release_agent = param->string;
|
||||||
param->string = NULL;
|
param->string = NULL;
|
||||||
break;
|
break;
|
||||||
@@ -963,9 +956,9 @@ int cgroup1_parse_param(struct fs_context *fc, struct fs_parameter *param)
|
|||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
/* Can't specify an empty name */
|
/* Can't specify an empty name */
|
||||||
if (!param->size)
|
if (!param->size)
|
||||||
return cg_invalf(fc, "cgroup1: Empty name");
|
return invalfc(fc, "Empty name");
|
||||||
if (param->size > MAX_CGROUP_ROOT_NAMELEN - 1)
|
if (param->size > MAX_CGROUP_ROOT_NAMELEN - 1)
|
||||||
return cg_invalf(fc, "cgroup1: Name too long");
|
return invalfc(fc, "Name too long");
|
||||||
/* Must match [\w.-]+ */
|
/* Must match [\w.-]+ */
|
||||||
for (i = 0; i < param->size; i++) {
|
for (i = 0; i < param->size; i++) {
|
||||||
char c = param->string[i];
|
char c = param->string[i];
|
||||||
@@ -973,11 +966,11 @@ int cgroup1_parse_param(struct fs_context *fc, struct fs_parameter *param)
|
|||||||
continue;
|
continue;
|
||||||
if ((c == '.') || (c == '-') || (c == '_'))
|
if ((c == '.') || (c == '-') || (c == '_'))
|
||||||
continue;
|
continue;
|
||||||
return cg_invalf(fc, "cgroup1: Invalid name");
|
return invalfc(fc, "Invalid name");
|
||||||
}
|
}
|
||||||
/* Specifying two names is forbidden */
|
/* Specifying two names is forbidden */
|
||||||
if (ctx->name)
|
if (ctx->name)
|
||||||
return cg_invalf(fc, "cgroup1: name respecified");
|
return invalfc(fc, "name respecified");
|
||||||
ctx->name = param->string;
|
ctx->name = param->string;
|
||||||
param->string = NULL;
|
param->string = NULL;
|
||||||
break;
|
break;
|
||||||
@@ -1012,7 +1005,7 @@ static int check_cgroupfs_options(struct fs_context *fc)
|
|||||||
if (ctx->all_ss) {
|
if (ctx->all_ss) {
|
||||||
/* Mutually exclusive option 'all' + subsystem name */
|
/* Mutually exclusive option 'all' + subsystem name */
|
||||||
if (ctx->subsys_mask)
|
if (ctx->subsys_mask)
|
||||||
return cg_invalf(fc, "cgroup1: subsys name conflicts with all");
|
return invalfc(fc, "subsys name conflicts with all");
|
||||||
/* 'all' => select all the subsystems */
|
/* 'all' => select all the subsystems */
|
||||||
ctx->subsys_mask = enabled;
|
ctx->subsys_mask = enabled;
|
||||||
}
|
}
|
||||||
@@ -1022,7 +1015,7 @@ static int check_cgroupfs_options(struct fs_context *fc)
|
|||||||
* empty hierarchies must have a name).
|
* empty hierarchies must have a name).
|
||||||
*/
|
*/
|
||||||
if (!ctx->subsys_mask && !ctx->name)
|
if (!ctx->subsys_mask && !ctx->name)
|
||||||
return cg_invalf(fc, "cgroup1: Need name or subsystem set");
|
return invalfc(fc, "Need name or subsystem set");
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Option noprefix was introduced just for backward compatibility
|
* Option noprefix was introduced just for backward compatibility
|
||||||
@@ -1030,11 +1023,11 @@ static int check_cgroupfs_options(struct fs_context *fc)
|
|||||||
* the cpuset subsystem.
|
* the cpuset subsystem.
|
||||||
*/
|
*/
|
||||||
if ((ctx->flags & CGRP_ROOT_NOPREFIX) && (ctx->subsys_mask & mask))
|
if ((ctx->flags & CGRP_ROOT_NOPREFIX) && (ctx->subsys_mask & mask))
|
||||||
return cg_invalf(fc, "cgroup1: noprefix used incorrectly");
|
return invalfc(fc, "noprefix used incorrectly");
|
||||||
|
|
||||||
/* Can't specify "none" and some subsystems */
|
/* Can't specify "none" and some subsystems */
|
||||||
if (ctx->subsys_mask && ctx->none)
|
if (ctx->subsys_mask && ctx->none)
|
||||||
return cg_invalf(fc, "cgroup1: none used incorrectly");
|
return invalfc(fc, "none used incorrectly");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1064,7 +1057,7 @@ int cgroup1_reconfigure(struct fs_context *fc)
|
|||||||
/* Don't allow flags or name to change at remount */
|
/* Don't allow flags or name to change at remount */
|
||||||
if ((ctx->flags ^ root->flags) ||
|
if ((ctx->flags ^ root->flags) ||
|
||||||
(ctx->name && strcmp(ctx->name, root->name))) {
|
(ctx->name && strcmp(ctx->name, root->name))) {
|
||||||
cg_invalf(fc, "option or name mismatch, new: 0x%x \"%s\", old: 0x%x \"%s\"",
|
errorfc(fc, "option or name mismatch, new: 0x%x \"%s\", old: 0x%x \"%s\"",
|
||||||
ctx->flags, ctx->name ?: "", root->flags, root->name);
|
ctx->flags, ctx->name ?: "", root->flags, root->name);
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
@@ -1181,7 +1174,7 @@ static int cgroup1_root_to_use(struct fs_context *fc)
|
|||||||
* can't create new one without subsys specification.
|
* can't create new one without subsys specification.
|
||||||
*/
|
*/
|
||||||
if (!ctx->subsys_mask && !ctx->none)
|
if (!ctx->subsys_mask && !ctx->none)
|
||||||
return cg_invalf(fc, "cgroup1: No subsys list or none specified");
|
return invalfc(fc, "No subsys list or none specified");
|
||||||
|
|
||||||
/* Hierarchies may only be created in the initial cgroup namespace. */
|
/* Hierarchies may only be created in the initial cgroup namespace. */
|
||||||
if (ctx->ns != &init_cgroup_ns)
|
if (ctx->ns != &init_cgroup_ns)
|
||||||
|
@@ -1816,24 +1816,19 @@ enum cgroup2_param {
|
|||||||
nr__cgroup2_params
|
nr__cgroup2_params
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct fs_parameter_spec cgroup2_param_specs[] = {
|
static const struct fs_parameter_spec cgroup2_fs_parameters[] = {
|
||||||
fsparam_flag("nsdelegate", Opt_nsdelegate),
|
fsparam_flag("nsdelegate", Opt_nsdelegate),
|
||||||
fsparam_flag("memory_localevents", Opt_memory_localevents),
|
fsparam_flag("memory_localevents", Opt_memory_localevents),
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct fs_parameter_description cgroup2_fs_parameters = {
|
|
||||||
.name = "cgroup2",
|
|
||||||
.specs = cgroup2_param_specs,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int cgroup2_parse_param(struct fs_context *fc, struct fs_parameter *param)
|
static int cgroup2_parse_param(struct fs_context *fc, struct fs_parameter *param)
|
||||||
{
|
{
|
||||||
struct cgroup_fs_context *ctx = cgroup_fc2context(fc);
|
struct cgroup_fs_context *ctx = cgroup_fc2context(fc);
|
||||||
struct fs_parse_result result;
|
struct fs_parse_result result;
|
||||||
int opt;
|
int opt;
|
||||||
|
|
||||||
opt = fs_parse(fc, &cgroup2_fs_parameters, param, &result);
|
opt = fs_parse(fc, cgroup2_fs_parameters, param, &result);
|
||||||
if (opt < 0)
|
if (opt < 0)
|
||||||
return opt;
|
return opt;
|
||||||
|
|
||||||
@@ -2156,7 +2151,7 @@ static void cgroup_kill_sb(struct super_block *sb)
|
|||||||
struct file_system_type cgroup_fs_type = {
|
struct file_system_type cgroup_fs_type = {
|
||||||
.name = "cgroup",
|
.name = "cgroup",
|
||||||
.init_fs_context = cgroup_init_fs_context,
|
.init_fs_context = cgroup_init_fs_context,
|
||||||
.parameters = &cgroup1_fs_parameters,
|
.parameters = cgroup1_fs_parameters,
|
||||||
.kill_sb = cgroup_kill_sb,
|
.kill_sb = cgroup_kill_sb,
|
||||||
.fs_flags = FS_USERNS_MOUNT,
|
.fs_flags = FS_USERNS_MOUNT,
|
||||||
};
|
};
|
||||||
@@ -2164,7 +2159,7 @@ struct file_system_type cgroup_fs_type = {
|
|||||||
static struct file_system_type cgroup2_fs_type = {
|
static struct file_system_type cgroup2_fs_type = {
|
||||||
.name = "cgroup2",
|
.name = "cgroup2",
|
||||||
.init_fs_context = cgroup_init_fs_context,
|
.init_fs_context = cgroup_init_fs_context,
|
||||||
.parameters = &cgroup2_fs_parameters,
|
.parameters = cgroup2_fs_parameters,
|
||||||
.kill_sb = cgroup_kill_sb,
|
.kill_sb = cgroup_kill_sb,
|
||||||
.fs_flags = FS_USERNS_MOUNT,
|
.fs_flags = FS_USERNS_MOUNT,
|
||||||
};
|
};
|
||||||
|
40
mm/shmem.c
40
mm/shmem.c
@@ -3382,9 +3382,19 @@ enum shmem_param {
|
|||||||
Opt_uid,
|
Opt_uid,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct fs_parameter_spec shmem_param_specs[] = {
|
static const struct constant_table shmem_param_enums_huge[] = {
|
||||||
|
{"never", SHMEM_HUGE_NEVER },
|
||||||
|
{"always", SHMEM_HUGE_ALWAYS },
|
||||||
|
{"within_size", SHMEM_HUGE_WITHIN_SIZE },
|
||||||
|
{"advise", SHMEM_HUGE_ADVISE },
|
||||||
|
{"deny", SHMEM_HUGE_DENY },
|
||||||
|
{"force", SHMEM_HUGE_FORCE },
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
const struct fs_parameter_spec shmem_fs_parameters[] = {
|
||||||
fsparam_u32 ("gid", Opt_gid),
|
fsparam_u32 ("gid", Opt_gid),
|
||||||
fsparam_enum ("huge", Opt_huge),
|
fsparam_enum ("huge", Opt_huge, shmem_param_enums_huge),
|
||||||
fsparam_u32oct("mode", Opt_mode),
|
fsparam_u32oct("mode", Opt_mode),
|
||||||
fsparam_string("mpol", Opt_mpol),
|
fsparam_string("mpol", Opt_mpol),
|
||||||
fsparam_string("nr_blocks", Opt_nr_blocks),
|
fsparam_string("nr_blocks", Opt_nr_blocks),
|
||||||
@@ -3394,20 +3404,6 @@ static const struct fs_parameter_spec shmem_param_specs[] = {
|
|||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct fs_parameter_enum shmem_param_enums[] = {
|
|
||||||
{ Opt_huge, "never", SHMEM_HUGE_NEVER },
|
|
||||||
{ Opt_huge, "always", SHMEM_HUGE_ALWAYS },
|
|
||||||
{ Opt_huge, "within_size", SHMEM_HUGE_WITHIN_SIZE },
|
|
||||||
{ Opt_huge, "advise", SHMEM_HUGE_ADVISE },
|
|
||||||
{}
|
|
||||||
};
|
|
||||||
|
|
||||||
const struct fs_parameter_description shmem_fs_parameters = {
|
|
||||||
.name = "tmpfs",
|
|
||||||
.specs = shmem_param_specs,
|
|
||||||
.enums = shmem_param_enums,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int shmem_parse_one(struct fs_context *fc, struct fs_parameter *param)
|
static int shmem_parse_one(struct fs_context *fc, struct fs_parameter *param)
|
||||||
{
|
{
|
||||||
struct shmem_options *ctx = fc->fs_private;
|
struct shmem_options *ctx = fc->fs_private;
|
||||||
@@ -3416,7 +3412,7 @@ static int shmem_parse_one(struct fs_context *fc, struct fs_parameter *param)
|
|||||||
char *rest;
|
char *rest;
|
||||||
int opt;
|
int opt;
|
||||||
|
|
||||||
opt = fs_parse(fc, &shmem_fs_parameters, param, &result);
|
opt = fs_parse(fc, shmem_fs_parameters, param, &result);
|
||||||
if (opt < 0)
|
if (opt < 0)
|
||||||
return opt;
|
return opt;
|
||||||
|
|
||||||
@@ -3480,9 +3476,9 @@ static int shmem_parse_one(struct fs_context *fc, struct fs_parameter *param)
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
unsupported_parameter:
|
unsupported_parameter:
|
||||||
return invalf(fc, "tmpfs: Unsupported parameter '%s'", param->key);
|
return invalfc(fc, "Unsupported parameter '%s'", param->key);
|
||||||
bad_value:
|
bad_value:
|
||||||
return invalf(fc, "tmpfs: Bad value for '%s'", param->key);
|
return invalfc(fc, "Bad value for '%s'", param->key);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int shmem_parse_options(struct fs_context *fc, void *data)
|
static int shmem_parse_options(struct fs_context *fc, void *data)
|
||||||
@@ -3588,7 +3584,7 @@ static int shmem_reconfigure(struct fs_context *fc)
|
|||||||
return 0;
|
return 0;
|
||||||
out:
|
out:
|
||||||
spin_unlock(&sbinfo->stat_lock);
|
spin_unlock(&sbinfo->stat_lock);
|
||||||
return invalf(fc, "tmpfs: %s", err);
|
return invalfc(fc, "%s", err);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int shmem_show_options(struct seq_file *seq, struct dentry *root)
|
static int shmem_show_options(struct seq_file *seq, struct dentry *root)
|
||||||
@@ -3890,7 +3886,7 @@ static struct file_system_type shmem_fs_type = {
|
|||||||
.name = "tmpfs",
|
.name = "tmpfs",
|
||||||
.init_fs_context = shmem_init_fs_context,
|
.init_fs_context = shmem_init_fs_context,
|
||||||
#ifdef CONFIG_TMPFS
|
#ifdef CONFIG_TMPFS
|
||||||
.parameters = &shmem_fs_parameters,
|
.parameters = shmem_fs_parameters,
|
||||||
#endif
|
#endif
|
||||||
.kill_sb = kill_litter_super,
|
.kill_sb = kill_litter_super,
|
||||||
.fs_flags = FS_USERNS_MOUNT,
|
.fs_flags = FS_USERNS_MOUNT,
|
||||||
@@ -4036,7 +4032,7 @@ bool shmem_huge_enabled(struct vm_area_struct *vma)
|
|||||||
static struct file_system_type shmem_fs_type = {
|
static struct file_system_type shmem_fs_type = {
|
||||||
.name = "tmpfs",
|
.name = "tmpfs",
|
||||||
.init_fs_context = ramfs_init_fs_context,
|
.init_fs_context = ramfs_init_fs_context,
|
||||||
.parameters = &ramfs_fs_parameters,
|
.parameters = ramfs_fs_parameters,
|
||||||
.kill_sb = kill_litter_super,
|
.kill_sb = kill_litter_super,
|
||||||
.fs_flags = FS_USERNS_MOUNT,
|
.fs_flags = FS_USERNS_MOUNT,
|
||||||
};
|
};
|
||||||
|
@@ -269,7 +269,7 @@ enum {
|
|||||||
Opt_abort_on_full,
|
Opt_abort_on_full,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct fs_parameter_spec ceph_param_specs[] = {
|
static const struct fs_parameter_spec ceph_parameters[] = {
|
||||||
fsparam_flag ("abort_on_full", Opt_abort_on_full),
|
fsparam_flag ("abort_on_full", Opt_abort_on_full),
|
||||||
fsparam_flag_no ("cephx_require_signatures", Opt_cephx_require_signatures),
|
fsparam_flag_no ("cephx_require_signatures", Opt_cephx_require_signatures),
|
||||||
fsparam_flag_no ("cephx_sign_messages", Opt_cephx_sign_messages),
|
fsparam_flag_no ("cephx_sign_messages", Opt_cephx_sign_messages),
|
||||||
@@ -283,18 +283,13 @@ static const struct fs_parameter_spec ceph_param_specs[] = {
|
|||||||
fsparam_u32 ("osd_request_timeout", Opt_osd_request_timeout),
|
fsparam_u32 ("osd_request_timeout", Opt_osd_request_timeout),
|
||||||
fsparam_u32 ("osdkeepalive", Opt_osdkeepalivetimeout),
|
fsparam_u32 ("osdkeepalive", Opt_osdkeepalivetimeout),
|
||||||
__fsparam (fs_param_is_s32, "osdtimeout", Opt_osdtimeout,
|
__fsparam (fs_param_is_s32, "osdtimeout", Opt_osdtimeout,
|
||||||
fs_param_deprecated),
|
fs_param_deprecated, NULL),
|
||||||
fsparam_string ("secret", Opt_secret),
|
fsparam_string ("secret", Opt_secret),
|
||||||
fsparam_flag_no ("share", Opt_share),
|
fsparam_flag_no ("share", Opt_share),
|
||||||
fsparam_flag_no ("tcp_nodelay", Opt_tcp_nodelay),
|
fsparam_flag_no ("tcp_nodelay", Opt_tcp_nodelay),
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct fs_parameter_description ceph_parameters = {
|
|
||||||
.name = "libceph",
|
|
||||||
.specs = ceph_param_specs,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ceph_options *ceph_alloc_options(void)
|
struct ceph_options *ceph_alloc_options(void)
|
||||||
{
|
{
|
||||||
struct ceph_options *opt;
|
struct ceph_options *opt;
|
||||||
@@ -337,7 +332,7 @@ EXPORT_SYMBOL(ceph_destroy_options);
|
|||||||
|
|
||||||
/* get secret from key store */
|
/* get secret from key store */
|
||||||
static int get_secret(struct ceph_crypto_key *dst, const char *name,
|
static int get_secret(struct ceph_crypto_key *dst, const char *name,
|
||||||
struct fs_context *fc)
|
struct p_log *log)
|
||||||
{
|
{
|
||||||
struct key *ukey;
|
struct key *ukey;
|
||||||
int key_err;
|
int key_err;
|
||||||
@@ -351,19 +346,19 @@ static int get_secret(struct ceph_crypto_key *dst, const char *name,
|
|||||||
key_err = PTR_ERR(ukey);
|
key_err = PTR_ERR(ukey);
|
||||||
switch (key_err) {
|
switch (key_err) {
|
||||||
case -ENOKEY:
|
case -ENOKEY:
|
||||||
errorf(fc, "libceph: Failed due to key not found: %s",
|
error_plog(log, "Failed due to key not found: %s",
|
||||||
name);
|
name);
|
||||||
break;
|
break;
|
||||||
case -EKEYEXPIRED:
|
case -EKEYEXPIRED:
|
||||||
errorf(fc, "libceph: Failed due to expired key: %s",
|
error_plog(log, "Failed due to expired key: %s",
|
||||||
name);
|
name);
|
||||||
break;
|
break;
|
||||||
case -EKEYREVOKED:
|
case -EKEYREVOKED:
|
||||||
errorf(fc, "libceph: Failed due to revoked key: %s",
|
error_plog(log, "Failed due to revoked key: %s",
|
||||||
name);
|
name);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
errorf(fc, "libceph: Failed due to key error %d: %s",
|
error_plog(log, "Failed due to key error %d: %s",
|
||||||
key_err, name);
|
key_err, name);
|
||||||
}
|
}
|
||||||
err = -EPERM;
|
err = -EPERM;
|
||||||
@@ -383,15 +378,16 @@ out:
|
|||||||
}
|
}
|
||||||
|
|
||||||
int ceph_parse_mon_ips(const char *buf, size_t len, struct ceph_options *opt,
|
int ceph_parse_mon_ips(const char *buf, size_t len, struct ceph_options *opt,
|
||||||
struct fs_context *fc)
|
struct fc_log *l)
|
||||||
{
|
{
|
||||||
|
struct p_log log = {.prefix = "libceph", .log = l};
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* ip1[:port1][,ip2[:port2]...] */
|
/* ip1[:port1][,ip2[:port2]...] */
|
||||||
ret = ceph_parse_ips(buf, buf + len, opt->mon_addr, CEPH_MAX_MON,
|
ret = ceph_parse_ips(buf, buf + len, opt->mon_addr, CEPH_MAX_MON,
|
||||||
&opt->num_mon);
|
&opt->num_mon);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
errorf(fc, "libceph: Failed to parse monitor IPs: %d", ret);
|
error_plog(&log, "Failed to parse monitor IPs: %d", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -400,12 +396,13 @@ int ceph_parse_mon_ips(const char *buf, size_t len, struct ceph_options *opt,
|
|||||||
EXPORT_SYMBOL(ceph_parse_mon_ips);
|
EXPORT_SYMBOL(ceph_parse_mon_ips);
|
||||||
|
|
||||||
int ceph_parse_param(struct fs_parameter *param, struct ceph_options *opt,
|
int ceph_parse_param(struct fs_parameter *param, struct ceph_options *opt,
|
||||||
struct fs_context *fc)
|
struct fc_log *l)
|
||||||
{
|
{
|
||||||
struct fs_parse_result result;
|
struct fs_parse_result result;
|
||||||
int token, err;
|
int token, err;
|
||||||
|
struct p_log log = {.prefix = "libceph", .log = l};
|
||||||
|
|
||||||
token = fs_parse(fc, &ceph_parameters, param, &result);
|
token = __fs_parse(&log, ceph_parameters, param, &result);
|
||||||
dout("%s fs_parse '%s' token %d\n", __func__, param->key, token);
|
dout("%s fs_parse '%s' token %d\n", __func__, param->key, token);
|
||||||
if (token < 0)
|
if (token < 0)
|
||||||
return token;
|
return token;
|
||||||
@@ -417,7 +414,7 @@ int ceph_parse_param(struct fs_parameter *param, struct ceph_options *opt,
|
|||||||
&opt->my_addr,
|
&opt->my_addr,
|
||||||
1, NULL);
|
1, NULL);
|
||||||
if (err) {
|
if (err) {
|
||||||
errorf(fc, "libceph: Failed to parse ip: %d", err);
|
error_plog(&log, "Failed to parse ip: %d", err);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
opt->flags |= CEPH_OPT_MYIP;
|
opt->flags |= CEPH_OPT_MYIP;
|
||||||
@@ -426,7 +423,7 @@ int ceph_parse_param(struct fs_parameter *param, struct ceph_options *opt,
|
|||||||
case Opt_fsid:
|
case Opt_fsid:
|
||||||
err = parse_fsid(param->string, &opt->fsid);
|
err = parse_fsid(param->string, &opt->fsid);
|
||||||
if (err) {
|
if (err) {
|
||||||
errorf(fc, "libceph: Failed to parse fsid: %d", err);
|
error_plog(&log, "Failed to parse fsid: %d", err);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
opt->flags |= CEPH_OPT_FSID;
|
opt->flags |= CEPH_OPT_FSID;
|
||||||
@@ -445,7 +442,7 @@ int ceph_parse_param(struct fs_parameter *param, struct ceph_options *opt,
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
err = ceph_crypto_key_unarmor(opt->key, param->string);
|
err = ceph_crypto_key_unarmor(opt->key, param->string);
|
||||||
if (err) {
|
if (err) {
|
||||||
errorf(fc, "libceph: Failed to parse secret: %d", err);
|
error_plog(&log, "Failed to parse secret: %d", err);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -456,10 +453,10 @@ int ceph_parse_param(struct fs_parameter *param, struct ceph_options *opt,
|
|||||||
opt->key = kzalloc(sizeof(*opt->key), GFP_KERNEL);
|
opt->key = kzalloc(sizeof(*opt->key), GFP_KERNEL);
|
||||||
if (!opt->key)
|
if (!opt->key)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
return get_secret(opt->key, param->string, fc);
|
return get_secret(opt->key, param->string, &log);
|
||||||
|
|
||||||
case Opt_osdtimeout:
|
case Opt_osdtimeout:
|
||||||
warnf(fc, "libceph: Ignoring osdtimeout");
|
warn_plog(&log, "Ignoring osdtimeout");
|
||||||
break;
|
break;
|
||||||
case Opt_osdkeepalivetimeout:
|
case Opt_osdkeepalivetimeout:
|
||||||
/* 0 isn't well defined right now, reject it */
|
/* 0 isn't well defined right now, reject it */
|
||||||
@@ -530,7 +527,7 @@ int ceph_parse_param(struct fs_parameter *param, struct ceph_options *opt,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
out_of_range:
|
out_of_range:
|
||||||
return invalf(fc, "libceph: %s out of range", param->key);
|
return inval_plog(&log, "%s out of range", param->key);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(ceph_parse_param);
|
EXPORT_SYMBOL(ceph_parse_param);
|
||||||
|
|
||||||
|
@@ -2781,7 +2781,7 @@ static int selinux_fs_context_dup(struct fs_context *fc,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct fs_parameter_spec selinux_param_specs[] = {
|
static const struct fs_parameter_spec selinux_fs_parameters[] = {
|
||||||
fsparam_string(CONTEXT_STR, Opt_context),
|
fsparam_string(CONTEXT_STR, Opt_context),
|
||||||
fsparam_string(DEFCONTEXT_STR, Opt_defcontext),
|
fsparam_string(DEFCONTEXT_STR, Opt_defcontext),
|
||||||
fsparam_string(FSCONTEXT_STR, Opt_fscontext),
|
fsparam_string(FSCONTEXT_STR, Opt_fscontext),
|
||||||
@@ -2790,18 +2790,13 @@ static const struct fs_parameter_spec selinux_param_specs[] = {
|
|||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct fs_parameter_description selinux_fs_parameters = {
|
|
||||||
.name = "SELinux",
|
|
||||||
.specs = selinux_param_specs,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int selinux_fs_context_parse_param(struct fs_context *fc,
|
static int selinux_fs_context_parse_param(struct fs_context *fc,
|
||||||
struct fs_parameter *param)
|
struct fs_parameter *param)
|
||||||
{
|
{
|
||||||
struct fs_parse_result result;
|
struct fs_parse_result result;
|
||||||
int opt, rc;
|
int opt, rc;
|
||||||
|
|
||||||
opt = fs_parse(fc, &selinux_fs_parameters, param, &result);
|
opt = fs_parse(fc, selinux_fs_parameters, param, &result);
|
||||||
if (opt < 0)
|
if (opt < 0)
|
||||||
return opt;
|
return opt;
|
||||||
|
|
||||||
@@ -7166,7 +7161,7 @@ static __init int selinux_init(void)
|
|||||||
else
|
else
|
||||||
pr_debug("SELinux: Starting in permissive mode\n");
|
pr_debug("SELinux: Starting in permissive mode\n");
|
||||||
|
|
||||||
fs_validate_description(&selinux_fs_parameters);
|
fs_validate_description("selinux", selinux_fs_parameters);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -679,7 +679,7 @@ static int smack_fs_context_dup(struct fs_context *fc,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct fs_parameter_spec smack_param_specs[] = {
|
static const struct fs_parameter_spec smack_fs_parameters[] = {
|
||||||
fsparam_string("smackfsdef", Opt_fsdefault),
|
fsparam_string("smackfsdef", Opt_fsdefault),
|
||||||
fsparam_string("smackfsdefault", Opt_fsdefault),
|
fsparam_string("smackfsdefault", Opt_fsdefault),
|
||||||
fsparam_string("smackfsfloor", Opt_fsfloor),
|
fsparam_string("smackfsfloor", Opt_fsfloor),
|
||||||
@@ -689,11 +689,6 @@ static const struct fs_parameter_spec smack_param_specs[] = {
|
|||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct fs_parameter_description smack_fs_parameters = {
|
|
||||||
.name = "smack",
|
|
||||||
.specs = smack_param_specs,
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* smack_fs_context_parse_param - Parse a single mount parameter
|
* smack_fs_context_parse_param - Parse a single mount parameter
|
||||||
* @fc: The new filesystem context being constructed.
|
* @fc: The new filesystem context being constructed.
|
||||||
@@ -708,7 +703,7 @@ static int smack_fs_context_parse_param(struct fs_context *fc,
|
|||||||
struct fs_parse_result result;
|
struct fs_parse_result result;
|
||||||
int opt, rc;
|
int opt, rc;
|
||||||
|
|
||||||
opt = fs_parse(fc, &smack_fs_parameters, param, &result);
|
opt = fs_parse(fc, smack_fs_parameters, param, &result);
|
||||||
if (opt < 0)
|
if (opt < 0)
|
||||||
return opt;
|
return opt;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user