Blob Blame History Raw
From: Daniel Wagner <dwagner@suse.de>
Date: Mon, 3 May 2021 19:03:03 +0200
Subject: nvme-multipath: reset bdev to ns head when failover
Patch-mainline: v5.13-rc1
Git-commit: ce86dad222e9074d3ec174ec81cb463a770331b5
References: bsc#1178378 bsc#1182999 bsc#1186681

When a request finally completes in end_io() after it has failed over,
the bdev pointer can be stale and thus the system can crash. Set the
bdev back to ns head, so the request is map to an active path when
resubmitted.

Signed-off-by: Daniel Wagner <dwagner@suse.de>
Reviewed-by: Hannes Reinecke <hare@suse.de>
Signed-off-by: Christoph Hellwig <hch@lst.de>
[dwagner: assign bi_disk directly]
Signed-off-by: Daniel Wagner <dwagner@suse.de>
---
 drivers/nvme/host/multipath.c |    3 +++
 1 file changed, 3 insertions(+)

--- a/drivers/nvme/host/multipath.c
+++ b/drivers/nvme/host/multipath.c
@@ -70,6 +70,7 @@ bool nvme_failover_req(struct request *r
 	struct nvme_ns *ns = req->q->queuedata;
 	u16 status = nvme_req(req)->status;
 	unsigned long flags;
+	struct bio *bio;
 
 	switch (status & 0x7ff) {
 	case NVME_SC_ANA_TRANSITION:
@@ -104,6 +105,8 @@ bool nvme_failover_req(struct request *r
 	}
 
 	spin_lock_irqsave(&ns->head->requeue_lock, flags);
+	for (bio = req->bio; bio; bio = bio->bi_next)
+		bio->bi_disk = ns->head->disk;
 	blk_steal_bios(&ns->head->requeue_list, req);
 	spin_unlock_irqrestore(&ns->head->requeue_lock, flags);
 	blk_mq_end_request(req, 0);