Skip to content

Commit

Permalink
cpuset: Use fs_context
Browse files Browse the repository at this point in the history
Make the cpuset filesystem use the filesystem context.  This is potentially
tricky as the cpuset fs is almost an alias for the cgroup filesystem, but
with some special parameters.

This can, however, be handled by setting up an appropriate cgroup
filesystem and returning the root directory of that as the root dir of this
one.

Signed-off-by: David Howells <dhowells@redhat.com>
cc: Tejun Heo <tj@kernel.org>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
  • Loading branch information
dhowells authored and Al Viro committed Feb 28, 2019
1 parent 23bf1b6 commit a187537
Showing 1 changed file with 42 additions and 14 deletions.
56 changes: 42 additions & 14 deletions kernel/cgroup/cpuset.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include <linux/memory.h>
#include <linux/export.h>
#include <linux/mount.h>
#include <linux/fs_context.h>
#include <linux/namei.h>
#include <linux/pagemap.h>
#include <linux/proc_fs.h>
Expand Down Expand Up @@ -372,25 +373,52 @@ static inline bool is_in_v2_mode(void)
* users. If someone tries to mount the "cpuset" filesystem, we
* silently switch it to mount "cgroup" instead
*/
static struct dentry *cpuset_mount(struct file_system_type *fs_type,
int flags, const char *unused_dev_name, void *data)
{
struct file_system_type *cgroup_fs = get_fs_type("cgroup");
struct dentry *ret = ERR_PTR(-ENODEV);
if (cgroup_fs) {
char mountopts[] =
"cpuset,noprefix,"
"release_agent=/sbin/cpuset_release_agent";
ret = cgroup_fs->mount(cgroup_fs, flags,
unused_dev_name, mountopts);
put_filesystem(cgroup_fs);
static int cpuset_get_tree(struct fs_context *fc)
{
struct file_system_type *cgroup_fs;
struct fs_context *new_fc;
int ret;

cgroup_fs = get_fs_type("cgroup");
if (!cgroup_fs)
return -ENODEV;

new_fc = fs_context_for_mount(cgroup_fs, fc->sb_flags);
if (IS_ERR(new_fc)) {
ret = PTR_ERR(new_fc);
} else {
static const char agent_path[] = "/sbin/cpuset_release_agent";
ret = vfs_parse_fs_string(new_fc, "cpuset", NULL, 0);
if (!ret)
ret = vfs_parse_fs_string(new_fc, "noprefix", NULL, 0);
if (!ret)
ret = vfs_parse_fs_string(new_fc, "release_agent",
agent_path, sizeof(agent_path) - 1);
if (!ret)
ret = vfs_get_tree(new_fc);
if (!ret) { /* steal the result */
fc->root = new_fc->root;
new_fc->root = NULL;
}
put_fs_context(new_fc);
}
put_filesystem(cgroup_fs);
return ret;
}

static const struct fs_context_operations cpuset_fs_context_ops = {
.get_tree = cpuset_get_tree,
};

static int cpuset_init_fs_context(struct fs_context *fc)
{
fc->ops = &cpuset_fs_context_ops;
return 0;
}

static struct file_system_type cpuset_fs_type = {
.name = "cpuset",
.mount = cpuset_mount,
.name = "cpuset",
.init_fs_context = cpuset_init_fs_context,
};

/*
Expand Down

0 comments on commit a187537

Please sign in to comment.