diff options
author | Tejun Heo <tj@kernel.org> | 2013-06-28 19:24:11 -0400 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2013-07-12 15:34:01 -0400 |
commit | bee550994f6b0c1179bd3ccea58dc5c2c4ccf842 (patch) | |
tree | d1bdc5b58f5118bf121a34b184e2b3a983ca9bd1 /kernel/cgroup.c | |
parent | 628f7cd47ab758cae0353d1a6decf3d1459dca24 (diff) |
cgroup: update error handling in cgroup_populate_dir()
cgroup_populate_dir() didn't use to check whether the actual file
creations were successful and could return success with only subset of
the requested files created, which is nasty.
This patch udpates cgroup_populate_dir() so that it either succeeds
with all files or fails with no file.
v2: The original patch also converted for_each_root_subsys() usages to
for_each_subsys() without explaining why. That part has been
moved to a separate patch.
Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: Li Zefan <lizefan@huawei.com>
Diffstat (limited to 'kernel/cgroup.c')
-rw-r--r-- | kernel/cgroup.c | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index 9835a097f3c0..6b7324431b99 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
@@ -4171,10 +4171,13 @@ static struct cftype cgroup_base_files[] = { | |||
4171 | * cgroup_populate_dir - create subsys files in a cgroup directory | 4171 | * cgroup_populate_dir - create subsys files in a cgroup directory |
4172 | * @cgrp: target cgroup | 4172 | * @cgrp: target cgroup |
4173 | * @subsys_mask: mask of the subsystem ids whose files should be added | 4173 | * @subsys_mask: mask of the subsystem ids whose files should be added |
4174 | * | ||
4175 | * On failure, no file is added. | ||
4174 | */ | 4176 | */ |
4175 | static int cgroup_populate_dir(struct cgroup *cgrp, unsigned long subsys_mask) | 4177 | static int cgroup_populate_dir(struct cgroup *cgrp, unsigned long subsys_mask) |
4176 | { | 4178 | { |
4177 | struct cgroup_subsys *ss; | 4179 | struct cgroup_subsys *ss; |
4180 | int ret = 0; | ||
4178 | 4181 | ||
4179 | /* process cftsets of each subsystem */ | 4182 | /* process cftsets of each subsystem */ |
4180 | for_each_root_subsys(cgrp->root, ss) { | 4183 | for_each_root_subsys(cgrp->root, ss) { |
@@ -4182,8 +4185,11 @@ static int cgroup_populate_dir(struct cgroup *cgrp, unsigned long subsys_mask) | |||
4182 | if (!test_bit(ss->subsys_id, &subsys_mask)) | 4185 | if (!test_bit(ss->subsys_id, &subsys_mask)) |
4183 | continue; | 4186 | continue; |
4184 | 4187 | ||
4185 | list_for_each_entry(set, &ss->cftsets, node) | 4188 | list_for_each_entry(set, &ss->cftsets, node) { |
4186 | cgroup_addrm_files(cgrp, ss, set->cfts, true); | 4189 | ret = cgroup_addrm_files(cgrp, ss, set->cfts, true); |
4190 | if (ret < 0) | ||
4191 | goto err; | ||
4192 | } | ||
4187 | } | 4193 | } |
4188 | 4194 | ||
4189 | /* This cgroup is ready now */ | 4195 | /* This cgroup is ready now */ |
@@ -4201,6 +4207,9 @@ static int cgroup_populate_dir(struct cgroup *cgrp, unsigned long subsys_mask) | |||
4201 | } | 4207 | } |
4202 | 4208 | ||
4203 | return 0; | 4209 | return 0; |
4210 | err: | ||
4211 | cgroup_clear_dir(cgrp, subsys_mask); | ||
4212 | return ret; | ||
4204 | } | 4213 | } |
4205 | 4214 | ||
4206 | static void css_dput_fn(struct work_struct *work) | 4215 | static void css_dput_fn(struct work_struct *work) |