summaryrefslogtreecommitdiff
path: root/kernel/cgroup
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/cgroup')
-rw-r--r--kernel/cgroup/cgroup-internal.h5
-rw-r--r--kernel/cgroup/cgroup.c31
2 files changed, 18 insertions, 18 deletions
diff --git a/kernel/cgroup/cgroup-internal.h b/kernel/cgroup/cgroup-internal.h
index 37cf709b7a0e..30e39f3932ad 100644
--- a/kernel/cgroup/cgroup-internal.h
+++ b/kernel/cgroup/cgroup-internal.h
@@ -41,6 +41,7 @@ extern void __init enable_debug_cgroup(void);
* The cgroup filesystem superblock creation/mount context.
*/
struct cgroup_fs_context {
+ struct kernfs_fs_context kfc;
struct cgroup_root *root;
struct cgroup_namespace *ns;
unsigned int flags; /* CGRP_ROOT_* flags */
@@ -56,7 +57,9 @@ struct cgroup_fs_context {
static inline struct cgroup_fs_context *cgroup_fc2context(struct fs_context *fc)
{
- return fc->fs_private;
+ struct kernfs_fs_context *kfc = fc->fs_private;
+
+ return container_of(kfc, struct cgroup_fs_context, kfc);
}
/*
diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c
index 0c6bef234a7c..747e5b17f9da 100644
--- a/kernel/cgroup/cgroup.c
+++ b/kernel/cgroup/cgroup.c
@@ -2039,18 +2039,14 @@ out:
int cgroup_do_get_tree(struct fs_context *fc)
{
struct cgroup_fs_context *ctx = cgroup_fc2context(fc);
- bool new_sb = false;
- unsigned long magic;
- int ret = 0;
+ int ret;
+ ctx->kfc.root = ctx->root->kf_root;
if (fc->fs_type == &cgroup2_fs_type)
- magic = CGROUP2_SUPER_MAGIC;
+ ctx->kfc.magic = CGROUP2_SUPER_MAGIC;
else
- magic = CGROUP_SUPER_MAGIC;
- fc->root = kernfs_mount(fc->fs_type, fc->sb_flags, ctx->root->kf_root,
- magic, &new_sb);
- if (IS_ERR(fc->root))
- ret = PTR_ERR(fc->root);
+ ctx->kfc.magic = CGROUP_SUPER_MAGIC;
+ ret = kernfs_get_tree(fc);
/*
* In non-init cgroup namespace, instead of root cgroup's dentry,
@@ -2078,7 +2074,7 @@ int cgroup_do_get_tree(struct fs_context *fc)
}
}
- if (!new_sb)
+ if (!ctx->kfc.new_sb_created)
cgroup_put(&ctx->root->cgrp);
return ret;
@@ -2094,19 +2090,15 @@ static void cgroup_fs_context_free(struct fs_context *fc)
kfree(ctx->name);
kfree(ctx->release_agent);
put_cgroup_ns(ctx->ns);
+ kernfs_free_fs_context(fc);
kfree(ctx);
}
static int cgroup_get_tree(struct fs_context *fc)
{
- struct cgroup_namespace *ns = current->nsproxy->cgroup_ns;
struct cgroup_fs_context *ctx = cgroup_fc2context(fc);
int ret;
- /* Check if the caller has permission to mount. */
- if (!ns_capable(ns->user_ns, CAP_SYS_ADMIN))
- return -EPERM;
-
cgrp_dfl_visible = true;
cgroup_get_live(&cgrp_dfl_root.cgrp);
ctx->root = &cgrp_dfl_root;
@@ -2132,7 +2124,8 @@ static const struct fs_context_operations cgroup1_fs_context_ops = {
};
/*
- * Initialise the cgroup filesystem creation/reconfiguration context.
+ * Initialise the cgroup filesystem creation/reconfiguration context. Notably,
+ * we select the namespace we're going to use.
*/
static int cgroup_init_fs_context(struct fs_context *fc)
{
@@ -2151,11 +2144,15 @@ static int cgroup_init_fs_context(struct fs_context *fc)
ctx->ns = current->nsproxy->cgroup_ns;
get_cgroup_ns(ctx->ns);
- fc->fs_private = ctx;
+ fc->fs_private = &ctx->kfc;
if (fc->fs_type == &cgroup2_fs_type)
fc->ops = &cgroup_fs_context_ops;
else
fc->ops = &cgroup1_fs_context_ops;
+ if (fc->user_ns)
+ put_user_ns(fc->user_ns);
+ fc->user_ns = get_user_ns(ctx->ns->user_ns);
+ fc->global = true;
return 0;
}