]> Pileus Git - ~andy/linux/commitdiff
blkcg: fix blkcg->css ref leak in __blkg_lookup_create()
authorTejun Heo <tj@kernel.org>
Thu, 19 Apr 2012 23:29:23 +0000 (16:29 -0700)
committerJens Axboe <axboe@kernel.dk>
Fri, 20 Apr 2012 08:06:40 +0000 (10:06 +0200)
__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>
block/blk-cgroup.c

index 82283859727e99d5ffd1f11272ebcc36b9d20c87..30a7a9c58b3834b9d08ae22032cb8681a8fe779f 100644 (file)
@@ -174,6 +174,7 @@ static struct blkcg_gq *__blkg_lookup_create(struct blkcg *blkcg,
        __releases(q->queue_lock) __acquires(q->queue_lock)
 {
        struct blkcg_gq *blkg;
+       int ret;
 
        WARN_ON_ONCE(!rcu_read_lock_held());
        lockdep_assert_held(q->queue_lock);
@@ -186,24 +187,22 @@ static struct blkcg_gq *__blkg_lookup_create(struct blkcg *blkcg,
        if (!css_tryget(&blkcg->css))
                return ERR_PTR(-EINVAL);
 
-       /*
-        * Allocate and initialize.
-        */
+       /* allocate */
+       ret = -ENOMEM;
        blkg = blkg_alloc(blkcg, q);
-
-       /* did alloc fail? */
-       if (unlikely(!blkg)) {
-               blkg = ERR_PTR(-ENOMEM);
-               goto out;
-       }
+       if (unlikely(!blkg))
+               goto err_put;
 
        /* insert */
        spin_lock(&blkcg->lock);
        hlist_add_head_rcu(&blkg->blkcg_node, &blkcg->blkg_list);
        list_add(&blkg->q_node, &q->blkg_list);
        spin_unlock(&blkcg->lock);
-out:
        return blkg;
+
+err_put:
+       css_put(&blkcg->css);
+       return ERR_PTR(ret);
 }
 
 struct blkcg_gq *blkg_lookup_create(struct blkcg *blkcg,