block: fix missing queue put in error path
authorJens Axboe <axboe@kernel.dk>
Mon, 15 Nov 2021 21:23:08 +0000 (14:23 -0700)
committerJens Axboe <axboe@kernel.dk>
Tue, 16 Nov 2021 00:00:54 +0000 (17:00 -0700)
If we fail the submission queue checks, we don't put the queue afterwards.
This can cause various issues like stalls on scheduler switch or failure
to remove the device, or like in the original bug report, timeout waiting
for the device on reboot/restart.

While in there, fix a few whitespace discrepancies in the surrounding
code.

Link: https://bugzilla.kernel.org/show_bug.cgi?id=215039
Fixes: b637108a4022 ("blk-mq: fix filesystem I/O request allocation")
Reported-and-tested-by: Stephen Smith <stephenmsmith@blueyonder.co.uk>
Reviewed-by: Ming Lei <ming.lei@redhat.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
block/blk-mq.c

index 3ab34c4f20daf700e2f54fe0e6b4f79d3ef39cf6..5e1c9fd99353e4c485718dde92b9b6c451f4789d 100644 (file)
@@ -2543,8 +2543,7 @@ static struct request *blk_mq_get_new_requests(struct request_queue *q,
        return NULL;
 }
 
-static inline bool blk_mq_can_use_cached_rq(struct request *rq,
-               struct bio *bio)
+static inline bool blk_mq_can_use_cached_rq(struct request *rq, struct bio *bio)
 {
        if (blk_mq_get_hctx_type(bio->bi_opf) != rq->mq_hctx->type)
                return false;
@@ -2565,7 +2564,6 @@ static inline struct request *blk_mq_get_request(struct request_queue *q,
        bool checked = false;
 
        if (plug) {
-
                rq = rq_list_peek(&plug->cached_rq);
                if (rq && rq->q == q) {
                        if (unlikely(!submit_bio_checks(bio)))
@@ -2587,12 +2585,14 @@ static inline struct request *blk_mq_get_request(struct request_queue *q,
 fallback:
        if (unlikely(bio_queue_enter(bio)))
                return NULL;
-       if (!checked && !submit_bio_checks(bio))
-               return NULL;
+       if (unlikely(!checked && !submit_bio_checks(bio)))
+               goto out_put;
        rq = blk_mq_get_new_requests(q, plug, bio, nsegs, same_queue_rq);
-       if (!rq)
-               blk_queue_exit(q);
-       return rq;
+       if (rq)
+               return rq;
+out_put:
+       blk_queue_exit(q);
+       return NULL;
 }
 
 /**