blk-mq: reflow blk_insert_flush
authorChristoph Hellwig <hch@lst.de>
Fri, 19 May 2023 04:40:45 +0000 (06:40 +0200)
committerJens Axboe <axboe@kernel.dk>
Sat, 20 May 2023 01:52:29 +0000 (19:52 -0600)
Use a switch statement to decide on the disposition of a flush request
instead of multiple if statements, out of which one does checks that are
more complex than required.  Also warn on a malformed request early
on instead of doing a BUG_ON later.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Link: https://lore.kernel.org/r/20230519044050.107790-3-hch@lst.de
Signed-off-by: Jens Axboe <axboe@kernel.dk>
block/blk-flush.c

index ed37d272f787ebba7f17b4e9a117e3b0b65cad0c..d8144f1f6fb12fc4c1a9c39995b1dc2c26171dde 100644 (file)
@@ -402,6 +402,9 @@ void blk_insert_flush(struct request *rq)
        struct blk_flush_queue *fq = blk_get_flush_queue(q, rq->mq_ctx);
        struct blk_mq_hw_ctx *hctx = rq->mq_hctx;
 
+       /* FLUSH/FUA request must never be merged */
+       WARN_ON_ONCE(rq->bio != rq->biotail);
+
        /*
         * @policy now records what operations need to be done.  Adjust
         * REQ_PREFLUSH and FUA for the driver.
@@ -417,39 +420,35 @@ void blk_insert_flush(struct request *rq)
         */
        rq->cmd_flags |= REQ_SYNC;
 
-       /*
-        * An empty flush handed down from a stacking driver may
-        * translate into nothing if the underlying device does not
-        * advertise a write-back cache.  In this case, simply
-        * complete the request.
-        */
-       if (!policy) {
+       switch (policy) {
+       case 0:
+               /*
+                * An empty flush handed down from a stacking driver may
+                * translate into nothing if the underlying device does not
+                * advertise a write-back cache.  In this case, simply
+                * complete the request.
+                */
                blk_mq_end_request(rq, 0);
                return;
-       }
-
-       BUG_ON(rq->bio != rq->biotail); /*assumes zero or single bio rq */
-
-       /*
-        * If there's data but flush is not necessary, the request can be
-        * processed directly without going through flush machinery.  Queue
-        * for normal execution.
-        */
-       if ((policy & REQ_FSEQ_DATA) &&
-           !(policy & (REQ_FSEQ_PREFLUSH | REQ_FSEQ_POSTFLUSH))) {
+       case REQ_FSEQ_DATA:
+               /*
+                * If there's data, but no flush is necessary, the request can
+                * be processed directly without going through flush machinery.
+                * Queue for normal execution.
+                */
                blk_mq_request_bypass_insert(rq, 0);
                blk_mq_run_hw_queue(hctx, false);
                return;
+       default:
+               /*
+                * Mark the request as part of a flush sequence and submit it
+                * for further processing to the flush state machine.
+                */
+               blk_rq_init_flush(rq);
+               spin_lock_irq(&fq->mq_flush_lock);
+               blk_flush_complete_seq(rq, fq, REQ_FSEQ_ACTIONS & ~policy, 0);
+               spin_unlock_irq(&fq->mq_flush_lock);
        }
-
-       /*
-        * @rq should go through flush machinery.  Mark it part of flush
-        * sequence and submit for further processing.
-        */
-       blk_rq_init_flush(rq);
-       spin_lock_irq(&fq->mq_flush_lock);
-       blk_flush_complete_seq(rq, fq, REQ_FSEQ_ACTIONS & ~policy, 0);
-       spin_unlock_irq(&fq->mq_flush_lock);
 }
 
 /**