mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 04:18:39 +08:00
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: 65ff5cd045
("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>
This commit is contained in:
parent
c01a21b777
commit
9f16a66733
@ -225,13 +225,18 @@ static void flush_end_io(struct request *flush_rq, blk_status_t error)
|
||||
/* release the tag's ownership to the req cloned from */
|
||||
spin_lock_irqsave(&fq->mq_flush_lock, flags);
|
||||
|
||||
WRITE_ONCE(flush_rq->state, MQ_RQ_IDLE);
|
||||
if (!refcount_dec_and_test(&flush_rq->ref)) {
|
||||
fq->rq_status = error;
|
||||
spin_unlock_irqrestore(&fq->mq_flush_lock, flags);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Flush request has to be marked as IDLE when it is really ended
|
||||
* because its .end_io() is called from timeout code path too for
|
||||
* avoiding use-after-free.
|
||||
*/
|
||||
WRITE_ONCE(flush_rq->state, MQ_RQ_IDLE);
|
||||
if (fq->rq_status != BLK_STS_OK)
|
||||
error = fq->rq_status;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user