Return-Path: Received: from mx3-rdu2.redhat.com ([66.187.233.73]:34714 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1753270AbeDSNco (ORCPT ); Thu, 19 Apr 2018 09:32:44 -0400 Subject: [PATCH 14/24] cpuset: Use fs_context [ver #7] From: David Howells To: viro@zeniv.linux.org.uk Cc: linux-nfs@vger.kernel.org, linux-kernel@vger.kernel.org, dhowells@redhat.com, linux-fsdevel@vger.kernel.org, linux-security-module@vger.kernel.org, Tejun Heo , linux-afs@lists.infradead.org Date: Thu, 19 Apr 2018 14:32:42 +0100 Message-ID: <152414476200.23902.10569978915645391342.stgit@warthog.procyon.org.uk> In-Reply-To: <152414466005.23902.12967974041384198114.stgit@warthog.procyon.org.uk> References: <152414466005.23902.12967974041384198114.stgit@warthog.procyon.org.uk> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Sender: linux-nfs-owner@vger.kernel.org List-ID: 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 cc: Tejun Heo --- kernel/cgroup/cpuset.c | 66 ++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 52 insertions(+), 14 deletions(-) diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c index 3c8ef37879f0..fce0584f161e 100644 --- a/kernel/cgroup/cpuset.c +++ b/kernel/cgroup/cpuset.c @@ -38,7 +38,7 @@ #include #include #include -#include +#include #include #include #include @@ -315,26 +315,64 @@ 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, size_t data_size) +static int cpuset_get_tree(struct fs_context *fc) { - struct file_system_type *cgroup_fs = get_fs_type("cgroup"); - struct dentry *ret = ERR_PTR(-ENODEV); + static const char opts[] = "cpuset,noprefix,release_agent=/sbin/cpuset_release_agent"; + struct file_system_type *cgroup_fs; + struct fs_context *cg_fc; + char *p; + int ret = -ENODEV; + + cgroup_fs = get_fs_type("cgroup"); if (cgroup_fs) { - char mountopts[] = - "cpuset,noprefix," - "release_agent=/sbin/cpuset_release_agent"; - ret = cgroup_fs->mount(cgroup_fs, flags, unused_dev_name, - mountopts, data_size); - put_filesystem(cgroup_fs); + ret = PTR_ERR(cgroup_fs); + goto out; + } + + cg_fc = vfs_new_fs_context(cgroup_fs, NULL, fc->sb_flags, fc->purpose); + put_filesystem(cgroup_fs); + if (IS_ERR(cg_fc)) { + ret = PTR_ERR(cg_fc); + goto out; } + + ret = -ENOMEM; + p = kstrdup(opts, GFP_KERNEL); + if (!p) + goto out_fc; + + ret = generic_parse_monolithic(fc, p, sizeof(opts) - 1); + kfree(p); + if (ret < 0) + goto out_fc; + + ret = vfs_get_tree(cg_fc); + if (ret < 0) + goto out_fc; + + fc->root = dget(cg_fc->root); + ret = 0; + +out_fc: + put_fs_context(cg_fc); +out: 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, struct super_block *src_sb) +{ + fc->ops = &cpuset_fs_context_ops; + return 0; +} + static struct file_system_type cpuset_fs_type = { - .name = "cpuset", - .mount = cpuset_mount, + .name = "cpuset", + .fs_context_size = sizeof(struct fs_context), + .init_fs_context = cpuset_init_fs_context, }; /*