diff options
author | Tejun Heo <tj@kernel.org> | 2012-07-07 16:08:18 -0700 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2012-07-07 16:08:18 -0700 |
commit | 5db9a4d99b0157a513944e9a44d29c9cec2e91dc (patch) | |
tree | 8373f346ea412ece84781bdce33c5e938ad3e3ee /lib | |
parent | 7db5b3ca0ecdb2e8fad52a4770e4e320e61c77a6 (diff) | |
download | op-kernel-dev-5db9a4d99b0157a513944e9a44d29c9cec2e91dc.zip op-kernel-dev-5db9a4d99b0157a513944e9a44d29c9cec2e91dc.tar.gz |
cgroup: fix cgroup hierarchy umount race
48ddbe1946 "cgroup: make css->refcnt clearing on cgroup removal
optional" allowed a css to linger after the associated cgroup is
removed. As a css holds a reference on the cgroup's dentry, it means
that cgroup dentries may linger for a while.
Destroying a superblock which has dentries with positive refcnts is a
critical bug and triggers BUG() in vfs code. As each cgroup dentry
holds an s_active reference, any lingering cgroup has both its dentry
and the superblock pinned and thus preventing premature release of
superblock.
Unfortunately, after 48ddbe1946, there's a small window while
releasing a cgroup which is directly under the root of the hierarchy.
When a cgroup directory is released, vfs layer first deletes the
corresponding dentry and then invokes dput() on the parent, which may
recurse further, so when a cgroup directly below root cgroup is
released, the cgroup is first destroyed - which releases the s_active
it was holding - and then the dentry for the root cgroup is dput().
This creates a window where the root dentry's refcnt isn't zero but
superblock's s_active is. If umount happens before or during this
window, vfs will see the root dentry with non-zero refcnt and trigger
BUG().
Before 48ddbe1946, this problem didn't exist because the last dentry
reference was guaranteed to be put synchronously from rmdir(2)
invocation which holds s_active around the whole process.
Fix it by holding an extra superblock->s_active reference across
dput() from css release, which is the dput() path added by 48ddbe1946
and the only one which doesn't hold an extra s_active ref across the
final cgroup dput().
Signed-off-by: Tejun Heo <tj@kernel.org>
LKML-Reference: <4FEEA5CB.8070809@huawei.com>
Reported-by: shyju pv <shyju.pv@huawei.com>
Tested-by: shyju pv <shyju.pv@huawei.com>
Cc: Sasha Levin <levinsasha928@gmail.com>
Acked-by: Li Zefan <lizefan@huawei.com>
Diffstat (limited to 'lib')
0 files changed, 0 insertions, 0 deletions