mirror of
https://github.com/torvalds/linux.git
synced 2026-11-06 21:58:01 +01:00
block: don't lose the status of a failed flush request
flush_end_io() stores the status in fq->rq_status for whoever drops the
last reference to finish the flush sequence. blk_mq_put_rq_ref() calls
it with BLK_STS_OK from tag iterators and the timeout handler and
overwrites an error the real completion stored. With two extra
references, reading /sys/block/<disk>/inflight is enough for that, a
failed flush completes everything waiting on it with success and fsync()
lies to the application.
Only store a status that is an error.
Fixes: 2e315dc07d ("blk-mq: grab rq->refcount before calling ->fn in blk_mq_tagset_busy_iter")
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Link: https://patch.msgid.link/20261028164415.1262013-6-axboe@kernel.dk
Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
cebb1c2331
commit
67c43ceaa2
|
|
@ -212,7 +212,13 @@ static enum rq_end_io_ret flush_end_io(struct request *flush_rq,
|
|||
spin_lock_irqsave(&fq->mq_flush_lock, flags);
|
||||
|
||||
if (!req_ref_put_and_test(flush_rq)) {
|
||||
fq->rq_status = error;
|
||||
/*
|
||||
* Remember the status of the flush for whoever drops the last
|
||||
* reference. blk_mq_put_rq_ref() gets here with BLK_STS_OK and
|
||||
* must not wipe it out.
|
||||
*/
|
||||
if (error != BLK_STS_OK)
|
||||
fq->rq_status = error;
|
||||
spin_unlock_irqrestore(&fq->mq_flush_lock, flags);
|
||||
return RQ_END_IO_NONE;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user