blk-mq: reflow blk_insert_flush
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>
This commit is contained in:
Родитель
0b573692f1
Коммит
c1075e548c
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Загрузка…
Ссылка в новой задаче