|
39 | 39 | #include <linux/memory.h>
|
40 | 40 | #include <linux/export.h>
|
41 | 41 | #include <linux/mount.h>
|
| 42 | +#include <linux/fs_context.h> |
42 | 43 | #include <linux/namei.h>
|
43 | 44 | #include <linux/pagemap.h>
|
44 | 45 | #include <linux/proc_fs.h>
|
@@ -372,25 +373,52 @@ static inline bool is_in_v2_mode(void)
|
372 | 373 | * users. If someone tries to mount the "cpuset" filesystem, we
|
373 | 374 | * silently switch it to mount "cgroup" instead
|
374 | 375 | */
|
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); |
387 | 404 | }
|
| 405 | + put_filesystem(cgroup_fs); |
388 | 406 | return ret;
|
389 | 407 | }
|
390 | 408 |
|
| 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 | + |
391 | 419 | 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, |
394 | 422 | };
|
395 | 423 |
|
396 | 424 | /*
|
|
0 commit comments