Skip to content

Commit 9f16a66

Browse files
Ming Leiaxboe
authored andcommitted
block: mark flush request as IDLE when it is really finished
For avoiding use-after-free on flush request, we call its .end_io() from both timeout code path and __blk_mq_end_request(). When flush request's ref doesn't drop to zero, it is still used, we can't mark it as IDLE, so fix it by marking IDLE when its refcount drops to zero really. Fixes: 65ff5cd ("blk-mq: mark flush request as IDLE in flush_end_io()") Signed-off-by: Ming Lei <ming.lei@redhat.com> Cc: Yi Zhang <yi.zhang@redhat.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
1 parent c01a21b commit 9f16a66

File tree

1 file changed

+6
-1
lines changed

1 file changed

+6
-1
lines changed

block/blk-flush.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,13 +225,18 @@ static void flush_end_io(struct request *flush_rq, blk_status_t error)
225225
/* release the tag's ownership to the req cloned from */
226226
spin_lock_irqsave(&fq->mq_flush_lock, flags);
227227

228-
WRITE_ONCE(flush_rq->state, MQ_RQ_IDLE);
229228
if (!refcount_dec_and_test(&flush_rq->ref)) {
230229
fq->rq_status = error;
231230
spin_unlock_irqrestore(&fq->mq_flush_lock, flags);
232231
return;
233232
}
234233

234+
/*
235+
* Flush request has to be marked as IDLE when it is really ended
236+
* because its .end_io() is called from timeout code path too for
237+
* avoiding use-after-free.
238+
*/
239+
WRITE_ONCE(flush_rq->state, MQ_RQ_IDLE);
235240
if (fq->rq_status != BLK_STS_OK)
236241
error = fq->rq_status;
237242

0 commit comments

Comments
 (0)