aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/cgroup.c
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2012-11-19 11:13:38 -0500
committerTejun Heo <tj@kernel.org>2012-11-19 11:13:38 -0500
commit4b8b47eb0001a89f271d671d959b235faa8f03e2 (patch)
tree611245ac0c36952a3b3e4af19514baf2be3d9104 /kernel/cgroup.c
parentb8a2df6a5b576d04f78f54abf254c283527d8bbc (diff)
cgroup: update cgroup_create() failure path
cgroup_create() was ignoring failure of cgroupfs files. Update it such that, if file creation fails, it rolls back by calling cgroup_destroy_locked() and returns failure. Note that error out goto labels are renamed. The labels are a bit confusing but will become better w/ later cgroup operation renames. 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.c21
1 files changed, 14 insertions, 7 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index c53f42e31704..027b66e66698 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -4107,7 +4107,7 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
4107 */ 4107 */
4108 if (!cgroup_lock_live_group(parent)) { 4108 if (!cgroup_lock_live_group(parent)) {
4109 err = -ENODEV; 4109 err = -ENODEV;
4110 goto err_free; 4110 goto err_free_cgrp;
4111 } 4111 }
4112 4112
4113 /* Grab a reference on the superblock so the hierarchy doesn't 4113 /* Grab a reference on the superblock so the hierarchy doesn't
@@ -4135,13 +4135,13 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
4135 css = ss->create(cgrp); 4135 css = ss->create(cgrp);
4136 if (IS_ERR(css)) { 4136 if (IS_ERR(css)) {
4137 err = PTR_ERR(css); 4137 err = PTR_ERR(css);
4138 goto err_destroy; 4138 goto err_free_all;
4139 } 4139 }
4140 init_cgroup_css(css, ss, cgrp); 4140 init_cgroup_css(css, ss, cgrp);
4141 if (ss->use_id) { 4141 if (ss->use_id) {
4142 err = alloc_css_id(ss, parent, cgrp); 4142 err = alloc_css_id(ss, parent, cgrp);
4143 if (err) 4143 if (err)
4144 goto err_destroy; 4144 goto err_free_all;
4145 } 4145 }
4146 /* At error, ->destroy() callback has to free assigned ID. */ 4146 /* At error, ->destroy() callback has to free assigned ID. */
4147 if (clone_children(parent) && ss->post_clone) 4147 if (clone_children(parent) && ss->post_clone)
@@ -4164,7 +4164,7 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
4164 */ 4164 */
4165 err = cgroup_create_file(dentry, S_IFDIR | mode, sb); 4165 err = cgroup_create_file(dentry, S_IFDIR | mode, sb);
4166 if (err < 0) 4166 if (err < 0)
4167 goto err_destroy; 4167 goto err_free_all;
4168 lockdep_assert_held(&dentry->d_inode->i_mutex); 4168 lockdep_assert_held(&dentry->d_inode->i_mutex);
4169 4169
4170 /* allocation complete, commit to creation */ 4170 /* allocation complete, commit to creation */
@@ -4183,14 +4183,15 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry,
4183 } 4183 }
4184 4184
4185 err = cgroup_populate_dir(cgrp, true, root->subsys_mask); 4185 err = cgroup_populate_dir(cgrp, true, root->subsys_mask);
4186 /* If err < 0, we have a half-filled directory - oh well ;) */ 4186 if (err)
4187 goto err_destroy;
4187 4188
4188 mutex_unlock(&cgroup_mutex); 4189 mutex_unlock(&cgroup_mutex);
4189 mutex_unlock(&cgrp->dentry->d_inode->i_mutex); 4190 mutex_unlock(&cgrp->dentry->d_inode->i_mutex);
4190 4191
4191 return 0; 4192 return 0;
4192 4193
4193err_destroy: 4194err_free_all:
4194 for_each_subsys(root, ss) { 4195 for_each_subsys(root, ss) {
4195 if (cgrp->subsys[ss->subsys_id]) 4196 if (cgrp->subsys[ss->subsys_id])
4196 ss->destroy(cgrp); 4197 ss->destroy(cgrp);
@@ -4198,9 +4199,15 @@ err_destroy:
4198 mutex_unlock(&cgroup_mutex); 4199 mutex_unlock(&cgroup_mutex);
4199 /* Release the reference count that we took on the superblock */ 4200 /* Release the reference count that we took on the superblock */
4200 deactivate_super(sb); 4201 deactivate_super(sb);
4201err_free: 4202err_free_cgrp:
4202 kfree(cgrp); 4203 kfree(cgrp);
4203 return err; 4204 return err;
4205
4206err_destroy:
4207 cgroup_destroy_locked(cgrp);
4208 mutex_unlock(&cgroup_mutex);
4209 mutex_unlock(&dentry->d_inode->i_mutex);
4210 return err;
4204} 4211}
4205 4212
4206static int cgroup_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode) 4213static int cgroup_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)