From 67c43ceaa29e9b904216651697adf20445b219fc Mon Sep 17 00:00:00 2001 From: Josef Bacik Date: Wed, 28 Oct 2026 10:41:08 -0600 Subject: [PATCH] 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//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: 2e315dc07df0 ("blk-mq: grab rq->refcount before calling ->fn in blk_mq_tagset_busy_iter") Signed-off-by: Josef Bacik Reviewed-by: Christoph Hellwig Link: https://patch.msgid.link/20261028164415.1262013-6-axboe@kernel.dk Signed-off-by: Jens Axboe --- block/blk-flush.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/block/blk-flush.c b/block/blk-flush.c index 403a46c86411..38bd4ae5d9e7 100644 --- a/block/blk-flush.c +++ b/block/blk-flush.c @@ -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; }