aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo2012-04-19 18:29:23 -0500
committerJens Axboe2012-04-20 03:06:40 -0500
commit496fb7806d616185a46865a4f3a20ef19dc6c7e3 (patch)
treea200e6825be55f6d0ed411ec32dc16244f488fd9 /block/blk-cgroup.c
parentaaf7c680682f1999ef2e574f743c45d1674a8b8a (diff)
downloadkernel-common-496fb7806d616185a46865a4f3a20ef19dc6c7e3.tar.gz
kernel-common-496fb7806d616185a46865a4f3a20ef19dc6c7e3.tar.xz
kernel-common-496fb7806d616185a46865a4f3a20ef19dc6c7e3.zip
blkcg: fix blkcg->css ref leak in __blkg_lookup_create()
__blkg_lookup_create() leaked blkcg->css ref if blkg allocation failed. Fix it. Signed-off-by: Tejun Heo <tj@kernel.org> Cc: Vivek Goyal <vgoyal@redhat.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'block/blk-cgroup.c')
-rw-r--r--block/blk-cgroup.c19
1 files changed, 9 insertions, 10 deletions
diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c
index 82283859727..30a7a9c58b3 100644
--- a/block/blk-cgroup.c
+++ b/block/blk-cgroup.c
@@ -174,6 +174,7 @@ static struct blkcg_gq *__blkg_lookup_create(struct blkcg *blkcg,
174 __releases(q->queue_lock) __acquires(q->queue_lock) 174 __releases(q->queue_lock) __acquires(q->queue_lock)
175{ 175{
176 struct blkcg_gq *blkg; 176 struct blkcg_gq *blkg;
177 int ret;
177 178
178 WARN_ON_ONCE(!rcu_read_lock_held()); 179 WARN_ON_ONCE(!rcu_read_lock_held());
179 lockdep_assert_held(q->queue_lock); 180 lockdep_assert_held(q->queue_lock);
@@ -186,24 +187,22 @@ static struct blkcg_gq *__blkg_lookup_create(struct blkcg *blkcg,
186 if (!css_tryget(&blkcg->css)) 187 if (!css_tryget(&blkcg->css))
187 return ERR_PTR(-EINVAL); 188 return ERR_PTR(-EINVAL);
188 189
189 /* 190 /* allocate */
190 * Allocate and initialize. 191 ret = -ENOMEM;
191 */
192 blkg = blkg_alloc(blkcg, q); 192 blkg = blkg_alloc(blkcg, q);
193 193 if (unlikely(!blkg))
194 /* did alloc fail? */ 194 goto err_put;
195 if (unlikely(!blkg)) {
196 blkg = ERR_PTR(-ENOMEM);
197 goto out;
198 }
199 195
200 /* insert */ 196 /* insert */
201 spin_lock(&blkcg->lock); 197 spin_lock(&blkcg->lock);
202 hlist_add_head_rcu(&blkg->blkcg_node, &blkcg->blkg_list); 198 hlist_add_head_rcu(&blkg->blkcg_node, &blkcg->blkg_list);
203 list_add(&blkg->q_node, &q->blkg_list); 199 list_add(&blkg->q_node, &q->blkg_list);
204 spin_unlock(&blkcg->lock); 200 spin_unlock(&blkcg->lock);
205out:
206 return blkg; 201 return blkg;
202
203err_put:
204 css_put(&blkcg->css);
205 return ERR_PTR(ret);
207} 206}
208 207
209struct blkcg_gq *blkg_lookup_create(struct blkcg *blkcg, 208struct blkcg_gq *blkg_lookup_create(struct blkcg *blkcg,