blk-cgroup: fix missing put device in error path from blkg_conf_pref()

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

Fixes: 0c9d338c84 ("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>
This commit is contained in:
Yu Kuai 2021-11-02 10:07:05 +08:00 committed by Jens Axboe
parent 245a489e81
commit 15c3010496

View File

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