|
@@ -1289,8 +1289,6 @@ static int cgroup_show_options(struct seq_file *seq,
|
|
|
for_each_subsys(ss, ssid)
|
|
|
if (root->subsys_mask & (1 << ssid))
|
|
|
seq_printf(seq, ",%s", ss->name);
|
|
|
- if (root->flags & CGRP_ROOT_SANE_BEHAVIOR)
|
|
|
- seq_puts(seq, ",sane_behavior");
|
|
|
if (root->flags & CGRP_ROOT_NOPREFIX)
|
|
|
seq_puts(seq, ",noprefix");
|
|
|
if (root->flags & CGRP_ROOT_XATTR)
|
|
@@ -1324,6 +1322,7 @@ static int parse_cgroupfs_options(char *data, struct cgroup_sb_opts *opts)
|
|
|
bool all_ss = false, one_ss = false;
|
|
|
unsigned int mask = -1U;
|
|
|
struct cgroup_subsys *ss;
|
|
|
+ int nr_opts = 0;
|
|
|
int i;
|
|
|
|
|
|
#ifdef CONFIG_CPUSETS
|
|
@@ -1333,6 +1332,8 @@ static int parse_cgroupfs_options(char *data, struct cgroup_sb_opts *opts)
|
|
|
memset(opts, 0, sizeof(*opts));
|
|
|
|
|
|
while ((token = strsep(&o, ",")) != NULL) {
|
|
|
+ nr_opts++;
|
|
|
+
|
|
|
if (!*token)
|
|
|
return -EINVAL;
|
|
|
if (!strcmp(token, "none")) {
|
|
@@ -1417,36 +1418,32 @@ static int parse_cgroupfs_options(char *data, struct cgroup_sb_opts *opts)
|
|
|
return -ENOENT;
|
|
|
}
|
|
|
|
|
|
- /* Consistency checks */
|
|
|
-
|
|
|
if (opts->flags & CGRP_ROOT_SANE_BEHAVIOR) {
|
|
|
pr_warn("sane_behavior: this is still under development and its behaviors will change, proceed at your own risk\n");
|
|
|
-
|
|
|
- if ((opts->flags & (CGRP_ROOT_NOPREFIX | CGRP_ROOT_XATTR)) ||
|
|
|
- opts->cpuset_clone_children || opts->release_agent ||
|
|
|
- opts->name) {
|
|
|
- pr_err("sane_behavior: noprefix, xattr, clone_children, release_agent and name are not allowed\n");
|
|
|
+ if (nr_opts != 1) {
|
|
|
+ pr_err("sane_behavior: no other mount options allowed\n");
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
- } else {
|
|
|
- /*
|
|
|
- * If the 'all' option was specified select all the
|
|
|
- * subsystems, otherwise if 'none', 'name=' and a subsystem
|
|
|
- * name options were not specified, let's default to 'all'
|
|
|
- */
|
|
|
- if (all_ss || (!one_ss && !opts->none && !opts->name))
|
|
|
- for_each_subsys(ss, i)
|
|
|
- if (!ss->disabled)
|
|
|
- opts->subsys_mask |= (1 << i);
|
|
|
-
|
|
|
- /*
|
|
|
- * We either have to specify by name or by subsystems. (So
|
|
|
- * all empty hierarchies must have a name).
|
|
|
- */
|
|
|
- if (!opts->subsys_mask && !opts->name)
|
|
|
- return -EINVAL;
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
+ /*
|
|
|
+ * If the 'all' option was specified select all the subsystems,
|
|
|
+ * otherwise if 'none', 'name=' and a subsystem name options were
|
|
|
+ * not specified, let's default to 'all'
|
|
|
+ */
|
|
|
+ if (all_ss || (!one_ss && !opts->none && !opts->name))
|
|
|
+ for_each_subsys(ss, i)
|
|
|
+ if (!ss->disabled)
|
|
|
+ opts->subsys_mask |= (1 << i);
|
|
|
+
|
|
|
+ /*
|
|
|
+ * We either have to specify by name or by subsystems. (So all
|
|
|
+ * empty hierarchies must have a name).
|
|
|
+ */
|
|
|
+ if (!opts->subsys_mask && !opts->name)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
/*
|
|
|
* Option noprefix was introduced just for backward compatibility
|
|
|
* with the old cpuset, so we allow noprefix only if mounting just
|
|
@@ -1455,7 +1452,6 @@ static int parse_cgroupfs_options(char *data, struct cgroup_sb_opts *opts)
|
|
|
if ((opts->flags & CGRP_ROOT_NOPREFIX) && (opts->subsys_mask & mask))
|
|
|
return -EINVAL;
|
|
|
|
|
|
-
|
|
|
/* Can't specify "none" and some subsystems */
|
|
|
if (opts->subsys_mask && opts->none)
|
|
|
return -EINVAL;
|
|
@@ -1724,7 +1720,7 @@ static struct dentry *cgroup_mount(struct file_system_type *fs_type,
|
|
|
goto out_unlock;
|
|
|
|
|
|
/* look for a matching existing root */
|
|
|
- if (!opts.subsys_mask && !opts.none && !opts.name) {
|
|
|
+ if (opts.flags & CGRP_ROOT_SANE_BEHAVIOR) {
|
|
|
cgrp_dfl_root_visible = true;
|
|
|
root = &cgrp_dfl_root;
|
|
|
cgroup_get(&root->cgrp);
|
|
@@ -1761,15 +1757,8 @@ static struct dentry *cgroup_mount(struct file_system_type *fs_type,
|
|
|
goto out_unlock;
|
|
|
}
|
|
|
|
|
|
- if (root->flags ^ opts.flags) {
|
|
|
- if ((root->flags | opts.flags) & CGRP_ROOT_SANE_BEHAVIOR) {
|
|
|
- pr_err("sane_behavior: new mount options should match the existing superblock\n");
|
|
|
- ret = -EINVAL;
|
|
|
- goto out_unlock;
|
|
|
- } else {
|
|
|
- pr_warn("new mount options do not match the existing superblock, will be ignored\n");
|
|
|
- }
|
|
|
- }
|
|
|
+ if (root->flags ^ opts.flags)
|
|
|
+ pr_warn("new mount options do not match the existing superblock, will be ignored\n");
|
|
|
|
|
|
/*
|
|
|
* A root's lifetime is governed by its root cgroup.
|
|
@@ -4809,8 +4798,7 @@ static void __init cgroup_init_subsys(struct cgroup_subsys *ss, bool early)
|
|
|
*/
|
|
|
int __init cgroup_init_early(void)
|
|
|
{
|
|
|
- static struct cgroup_sb_opts __initdata opts =
|
|
|
- { .flags = CGRP_ROOT_SANE_BEHAVIOR };
|
|
|
+ static struct cgroup_sb_opts __initdata opts;
|
|
|
struct cgroup_subsys *ss;
|
|
|
int i;
|
|
|
|