aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2013-06-28 19:24:10 -0400
committerTejun Heo <tj@kernel.org>2013-07-12 15:34:01 -0400
commitb1f28d3109349899e87377e89f9d8ab5bc95ec57 (patch)
tree817a277b89882a82e5e52fd3911d81b819709c41
parent8f89140ae41ccd9c63344e6823faa862aa7435e3 (diff)
cgroup: fix error path of cgroup_addrm_files()
cgroup_addrm_files() mishandled error return value from cgroup_add_file() and returns error iff the last file fails to create. As we're in the process of cleaning up file add/rm error handling and will reliably propagate file creation failures, there's no point in keeping adding files after a failure. Replace the broken error collection logic with immediate error return. While at it, add lockdep assertions and function comment. Signed-off-by: Tejun Heo <tj@kernel.org> Acked-by: Li Zefan <lizefan@huawei.com>
-rw-r--r--kernel/cgroup.c28
1 files changed, 22 insertions, 6 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 09bfa870e698..9b16d75bec63 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -2780,11 +2780,26 @@ out:
2780 return error; 2780 return error;
2781} 2781}
2782 2782
2783/**
2784 * cgroup_addrm_files - add or remove files to a cgroup directory
2785 * @cgrp: the target cgroup
2786 * @subsys: the subsystem of files to be added
2787 * @cfts: array of cftypes to be added
2788 * @is_add: whether to add or remove
2789 *
2790 * Depending on @is_add, add or remove files defined by @cfts on @cgrp.
2791 * All @cfts should belong to @subsys. For removals, this function never
2792 * fails. If addition fails, this function doesn't remove files already
2793 * added. The caller is responsible for cleaning up.
2794 */
2783static int cgroup_addrm_files(struct cgroup *cgrp, struct cgroup_subsys *subsys, 2795static int cgroup_addrm_files(struct cgroup *cgrp, struct cgroup_subsys *subsys,
2784 struct cftype cfts[], bool is_add) 2796 struct cftype cfts[], bool is_add)
2785{ 2797{
2786 struct cftype *cft; 2798 struct cftype *cft;
2787 int err, ret = 0; 2799 int ret;
2800
2801 lockdep_assert_held(&cgrp->dentry->d_inode->i_mutex);
2802 lockdep_assert_held(&cgroup_mutex);
2788 2803
2789 for (cft = cfts; cft->name[0] != '\0'; cft++) { 2804 for (cft = cfts; cft->name[0] != '\0'; cft++) {
2790 /* does cft->flags tell us to skip this file on @cgrp? */ 2805 /* does cft->flags tell us to skip this file on @cgrp? */
@@ -2796,16 +2811,17 @@ static int cgroup_addrm_files(struct cgroup *cgrp, struct cgroup_subsys *subsys,
2796 continue; 2811 continue;
2797 2812
2798 if (is_add) { 2813 if (is_add) {
2799 err = cgroup_add_file(cgrp, subsys, cft); 2814 ret = cgroup_add_file(cgrp, subsys, cft);
2800 if (err) 2815 if (ret) {
2801 pr_warn("cgroup_addrm_files: failed to add %s, err=%d\n", 2816 pr_warn("cgroup_addrm_files: failed to add %s, err=%d\n",
2802 cft->name, err); 2817 cft->name, ret);
2803 ret = err; 2818 return ret;
2819 }
2804 } else { 2820 } else {
2805 cgroup_rm_file(cgrp, cft); 2821 cgroup_rm_file(cgrp, cft);
2806 } 2822 }
2807 } 2823 }
2808 return ret; 2824 return 0;
2809} 2825}
2810 2826
2811static void cgroup_cfts_prepare(void) 2827static void cgroup_cfts_prepare(void)