diff options
author | Li Zefan <lizefan@huawei.com> | 2014-04-04 11:14:41 +0200 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2014-04-04 14:22:27 +0200 |
commit | c6b3d5bcd67c75961a1e8b9564d1475c0f194a84 (patch) | |
tree | e6ed4f1c3b98474996b6b61e232569564d86d352 | |
parent | Merge branch 'linux_next' of git://git.kernel.org/pub/scm/linux/kernel/git/mc... (diff) | |
download | linux-c6b3d5bcd67c75961a1e8b9564d1475c0f194a84.tar.xz linux-c6b3d5bcd67c75961a1e8b9564d1475c0f194a84.zip |
cgroup: fix top cgroup refcnt leak
As mount() and kill_sb() is not a one-to-one match, If we mount the same
cgroupfs in serveral mount points, and then umount all of them, kill_sb()
will be called only once.
Try:
# mount -t cgroup -o cpuacct xxx /cgroup
# mount -t cgroup -o cpuacct xxx /cgroup2
# cat /proc/cgroups | grep cpuacct
cpuacct 2 1 1
# umount /cgroup
# umount /cgroup2
# cat /proc/cgroups | grep cpuacct
cpuacct 2 1 1
You'll see cgroupfs will never be freed.
Signed-off-by: Li Zefan <lizefan@huawei.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
-rw-r--r-- | kernel/cgroup.c | 5 |
1 files changed, 3 insertions, 2 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index fede3d3f28ff..0dfc7324c789 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c @@ -1487,6 +1487,7 @@ static struct dentry *cgroup_mount(struct file_system_type *fs_type, struct cgroup_sb_opts opts; struct dentry *dentry; int ret; + bool new_sb; /* * The first time anyone tries to mount a cgroup, enable the list @@ -1603,8 +1604,8 @@ out_unlock: if (ret) return ERR_PTR(ret); - dentry = kernfs_mount(fs_type, flags, root->kf_root, NULL); - if (IS_ERR(dentry)) + dentry = kernfs_mount(fs_type, flags, root->kf_root, &new_sb); + if (IS_ERR(dentry) || !new_sb) cgroup_put(&root->cgrp); return dentry; } |