diff options
author | Tejun Heo <tj@kernel.org> | 2014-02-11 11:02:59 -0500 |
---|---|---|
committer | Tejun Heo <tj@kernel.org> | 2014-02-11 11:02:59 -0500 |
commit | 398f878789fceb51bf5e424b753a3756643513c4 (patch) | |
tree | cd80a446bd1e2f1adc5652a805ac2f98a40b003e /kernel | |
parent | f7cef064aa01a1ac682c1945cc168b878cb118ff (diff) | |
parent | 0ab02ca8f887908152d1a96db5130fc661d36a1e (diff) |
Merge branch 'cgroup/for-3.14-fixes' into cgroup/for-3.15
Pull for-3.14-fixes to receive 0ab02ca8f887 ("cgroup: protect
modifications to cgroup_idr with cgroup_mutex") prior to kernfs
conversion series to avoid non-trivial conflicts.
Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/cgroup.c | 34 |
1 files changed, 18 insertions, 16 deletions
diff --git a/kernel/cgroup.c b/kernel/cgroup.c index f5bbe5885364..2de8decfd99f 100644 --- a/kernel/cgroup.c +++ b/kernel/cgroup.c | |||
@@ -850,7 +850,9 @@ static void cgroup_diput(struct dentry *dentry, struct inode *inode) | |||
850 | * per-subsystem and moved to css->id so that lookups are | 850 | * per-subsystem and moved to css->id so that lookups are |
851 | * successful until the target css is released. | 851 | * successful until the target css is released. |
852 | */ | 852 | */ |
853 | mutex_lock(&cgroup_mutex); | ||
853 | idr_remove(&cgrp->root->cgroup_idr, cgrp->id); | 854 | idr_remove(&cgrp->root->cgroup_idr, cgrp->id); |
855 | mutex_unlock(&cgroup_mutex); | ||
854 | cgrp->id = -1; | 856 | cgrp->id = -1; |
855 | 857 | ||
856 | call_rcu(&cgrp->rcu_head, cgroup_free_rcu); | 858 | call_rcu(&cgrp->rcu_head, cgroup_free_rcu); |
@@ -4092,16 +4094,6 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry, | |||
4092 | rcu_assign_pointer(cgrp->name, name); | 4094 | rcu_assign_pointer(cgrp->name, name); |
4093 | 4095 | ||
4094 | /* | 4096 | /* |
4095 | * Temporarily set the pointer to NULL, so idr_find() won't return | ||
4096 | * a half-baked cgroup. | ||
4097 | */ | ||
4098 | cgrp->id = idr_alloc(&root->cgroup_idr, NULL, 1, 0, GFP_KERNEL); | ||
4099 | if (cgrp->id < 0) { | ||
4100 | err = -ENOMEM; | ||
4101 | goto err_free_name; | ||
4102 | } | ||
4103 | |||
4104 | /* | ||
4105 | * Only live parents can have children. Note that the liveliness | 4097 | * Only live parents can have children. Note that the liveliness |
4106 | * check isn't strictly necessary because cgroup_mkdir() and | 4098 | * check isn't strictly necessary because cgroup_mkdir() and |
4107 | * cgroup_rmdir() are fully synchronized by i_mutex; however, do it | 4099 | * cgroup_rmdir() are fully synchronized by i_mutex; however, do it |
@@ -4110,7 +4102,17 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry, | |||
4110 | */ | 4102 | */ |
4111 | if (!cgroup_lock_live_group(parent)) { | 4103 | if (!cgroup_lock_live_group(parent)) { |
4112 | err = -ENODEV; | 4104 | err = -ENODEV; |
4113 | goto err_free_id; | 4105 | goto err_free_name; |
4106 | } | ||
4107 | |||
4108 | /* | ||
4109 | * Temporarily set the pointer to NULL, so idr_find() won't return | ||
4110 | * a half-baked cgroup. | ||
4111 | */ | ||
4112 | cgrp->id = idr_alloc(&root->cgroup_idr, NULL, 1, 0, GFP_KERNEL); | ||
4113 | if (cgrp->id < 0) { | ||
4114 | err = -ENOMEM; | ||
4115 | goto err_unlock; | ||
4114 | } | 4116 | } |
4115 | 4117 | ||
4116 | /* Grab a reference on the superblock so the hierarchy doesn't | 4118 | /* Grab a reference on the superblock so the hierarchy doesn't |
@@ -4142,7 +4144,7 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry, | |||
4142 | */ | 4144 | */ |
4143 | err = cgroup_create_file(dentry, S_IFDIR | mode, sb); | 4145 | err = cgroup_create_file(dentry, S_IFDIR | mode, sb); |
4144 | if (err < 0) | 4146 | if (err < 0) |
4145 | goto err_unlock; | 4147 | goto err_free_id; |
4146 | lockdep_assert_held(&dentry->d_inode->i_mutex); | 4148 | lockdep_assert_held(&dentry->d_inode->i_mutex); |
4147 | 4149 | ||
4148 | cgrp->serial_nr = cgroup_serial_nr_next++; | 4150 | cgrp->serial_nr = cgroup_serial_nr_next++; |
@@ -4178,12 +4180,12 @@ static long cgroup_create(struct cgroup *parent, struct dentry *dentry, | |||
4178 | 4180 | ||
4179 | return 0; | 4181 | return 0; |
4180 | 4182 | ||
4181 | err_unlock: | ||
4182 | mutex_unlock(&cgroup_mutex); | ||
4183 | /* Release the reference count that we took on the superblock */ | ||
4184 | deactivate_super(sb); | ||
4185 | err_free_id: | 4183 | err_free_id: |
4186 | idr_remove(&root->cgroup_idr, cgrp->id); | 4184 | idr_remove(&root->cgroup_idr, cgrp->id); |
4185 | /* Release the reference count that we took on the superblock */ | ||
4186 | deactivate_super(sb); | ||
4187 | err_unlock: | ||
4188 | mutex_unlock(&cgroup_mutex); | ||
4187 | err_free_name: | 4189 | err_free_name: |
4188 | kfree(rcu_dereference_raw(cgrp->name)); | 4190 | kfree(rcu_dereference_raw(cgrp->name)); |
4189 | err_free_cgrp: | 4191 | err_free_cgrp: |