Skip to content

Commit a187537

Browse files
dhowellsAl Viro
authored andcommitted
cpuset: Use fs_context
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>
1 parent 23bf1b6 commit a187537

File tree

1 file changed

+42
-14
lines changed

1 file changed

+42
-14
lines changed

kernel/cgroup/cpuset.c

Lines changed: 42 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
#include <linux/memory.h>
4040
#include <linux/export.h>
4141
#include <linux/mount.h>
42+
#include <linux/fs_context.h>
4243
#include <linux/namei.h>
4344
#include <linux/pagemap.h>
4445
#include <linux/proc_fs.h>
@@ -372,25 +373,52 @@ static inline bool is_in_v2_mode(void)
372373
* users. If someone tries to mount the "cpuset" filesystem, we
373374
* silently switch it to mount "cgroup" instead
374375
*/
375-
static struct dentry *cpuset_mount(struct file_system_type *fs_type,
376-
int flags, const char *unused_dev_name, void *data)
377-
{
378-
struct file_system_type *cgroup_fs = get_fs_type("cgroup");
379-
struct dentry *ret = ERR_PTR(-ENODEV);
380-
if (cgroup_fs) {
381-
char mountopts[] =
382-
"cpuset,noprefix,"
383-
"release_agent=/sbin/cpuset_release_agent";
384-
ret = cgroup_fs->mount(cgroup_fs, flags,
385-
unused_dev_name, mountopts);
386-
put_filesystem(cgroup_fs);
376+
static int cpuset_get_tree(struct fs_context *fc)
377+
{
378+
struct file_system_type *cgroup_fs;
379+
struct fs_context *new_fc;
380+
int ret;
381+
382+
cgroup_fs = get_fs_type("cgroup");
383+
if (!cgroup_fs)
384+
return -ENODEV;
385+
386+
new_fc = fs_context_for_mount(cgroup_fs, fc->sb_flags);
387+
if (IS_ERR(new_fc)) {
388+
ret = PTR_ERR(new_fc);
389+
} else {
390+
static const char agent_path[] = "/sbin/cpuset_release_agent";
391+
ret = vfs_parse_fs_string(new_fc, "cpuset", NULL, 0);
392+
if (!ret)
393+
ret = vfs_parse_fs_string(new_fc, "noprefix", NULL, 0);
394+
if (!ret)
395+
ret = vfs_parse_fs_string(new_fc, "release_agent",
396+
agent_path, sizeof(agent_path) - 1);
397+
if (!ret)
398+
ret = vfs_get_tree(new_fc);
399+
if (!ret) { /* steal the result */
400+
fc->root = new_fc->root;
401+
new_fc->root = NULL;
402+
}
403+
put_fs_context(new_fc);
387404
}
405+
put_filesystem(cgroup_fs);
388406
return ret;
389407
}
390408

409+
static const struct fs_context_operations cpuset_fs_context_ops = {
410+
.get_tree = cpuset_get_tree,
411+
};
412+
413+
static int cpuset_init_fs_context(struct fs_context *fc)
414+
{
415+
fc->ops = &cpuset_fs_context_ops;
416+
return 0;
417+
}
418+
391419
static struct file_system_type cpuset_fs_type = {
392-
.name = "cpuset",
393-
.mount = cpuset_mount,
420+
.name = "cpuset",
421+
.init_fs_context = cpuset_init_fs_context,
394422
};
395423

396424
/*

0 commit comments

Comments
 (0)