Commit b1f28d31 authored by Tejun Heo's avatar Tejun Heo

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: default avatarTejun Heo <tj@kernel.org>
Acked-by: default avatarLi Zefan <lizefan@huawei.com>
parent 8f89140a
...@@ -2780,11 +2780,26 @@ static int cgroup_add_file(struct cgroup *cgrp, struct cgroup_subsys *subsys, ...@@ -2780,11 +2780,26 @@ static int cgroup_add_file(struct cgroup *cgrp, struct cgroup_subsys *subsys,
return error; return error;
} }
/**
* cgroup_addrm_files - add or remove files to a cgroup directory
* @cgrp: the target cgroup
* @subsys: the subsystem of files to be added
* @cfts: array of cftypes to be added
* @is_add: whether to add or remove
*
* Depending on @is_add, add or remove files defined by @cfts on @cgrp.
* All @cfts should belong to @subsys. For removals, this function never
* fails. If addition fails, this function doesn't remove files already
* added. The caller is responsible for cleaning up.
*/
static int cgroup_addrm_files(struct cgroup *cgrp, struct cgroup_subsys *subsys, static int cgroup_addrm_files(struct cgroup *cgrp, struct cgroup_subsys *subsys,
struct cftype cfts[], bool is_add) struct cftype cfts[], bool is_add)
{ {
struct cftype *cft; struct cftype *cft;
int err, ret = 0; int ret;
lockdep_assert_held(&cgrp->dentry->d_inode->i_mutex);
lockdep_assert_held(&cgroup_mutex);
for (cft = cfts; cft->name[0] != '\0'; cft++) { for (cft = cfts; cft->name[0] != '\0'; cft++) {
/* does cft->flags tell us to skip this file on @cgrp? */ /* 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,16 +2811,17 @@ static int cgroup_addrm_files(struct cgroup *cgrp, struct cgroup_subsys *subsys,
continue; continue;
if (is_add) { if (is_add) {
err = cgroup_add_file(cgrp, subsys, cft); ret = cgroup_add_file(cgrp, subsys, cft);
if (err) if (ret) {
pr_warn("cgroup_addrm_files: failed to add %s, err=%d\n", pr_warn("cgroup_addrm_files: failed to add %s, err=%d\n",
cft->name, err); cft->name, ret);
ret = err; return ret;
}
} else { } else {
cgroup_rm_file(cgrp, cft); cgroup_rm_file(cgrp, cft);
} }
} }
return ret; return 0;
} }
static void cgroup_cfts_prepare(void) static void cgroup_cfts_prepare(void)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment