blk-cgroup: fix missing put device in error path from blkg_conf_pref()
authorYu Kuai <yukuai3@huawei.com>
Tue, 2 Nov 2021 02:07:05 +0000 (10:07 +0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 25 Nov 2021 08:48:41 +0000 (09:48 +0100)
[ Upstream commit 15c30104965101b8e76b24d27035569d6613a7d6 ]

If blk_queue_enter() failed due to queue is dying, the
blkdev_put_no_open() is needed because blkcg_conf_open_bdev() succeeded.

Fixes: 0c9d338c8443 ("blk-cgroup: synchronize blkg creation against policy deactivation")
Signed-off-by: Yu Kuai <yukuai3@huawei.com>
Acked-by: Tejun Heo <tj@kernel.org>
Link: https://lore.kernel.org/r/20211102020705.2321858-1-yukuai3@huawei.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
block/blk-cgroup.c

index ebff1af..0eec59e 100644 (file)
@@ -639,7 +639,7 @@ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol,
         */
        ret = blk_queue_enter(q, 0);
        if (ret)
-               return ret;
+               goto fail;
 
        rcu_read_lock();
        spin_lock_irq(&q->queue_lock);
@@ -675,13 +675,13 @@ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol,
                new_blkg = blkg_alloc(pos, q, GFP_KERNEL);
                if (unlikely(!new_blkg)) {
                        ret = -ENOMEM;
-                       goto fail;
+                       goto fail_exit_queue;
                }
 
                if (radix_tree_preload(GFP_KERNEL)) {
                        blkg_free(new_blkg);
                        ret = -ENOMEM;
-                       goto fail;
+                       goto fail_exit_queue;
                }
 
                rcu_read_lock();
@@ -721,9 +721,10 @@ fail_preloaded:
 fail_unlock:
        spin_unlock_irq(&q->queue_lock);
        rcu_read_unlock();
+fail_exit_queue:
+       blk_queue_exit(q);
 fail:
        blkdev_put_no_open(bdev);
-       blk_queue_exit(q);
        /*
         * If queue was bypassing, we should retry.  Do so after a
         * short msleep().  It isn't strictly necessary but queue