nvme: introduce a nvme_host_path_error helper
authorChao Leng <lengchao@huawei.com>
Thu, 4 Feb 2021 07:55:11 +0000 (08:55 +0100)
committerChristoph Hellwig <hch@lst.de>
Wed, 10 Feb 2021 15:38:03 +0000 (16:38 +0100)
When using nvme native multipathing, if a path related error occurs
during ->queue_rq, the request needs to be completed with
NVME_SC_HOST_PATH_ERROR so that the request can be failed over.

Introduce a helper to complete the command from ->queue_rq in a wait
that invokes nvme_complete_rq.

Signed-off-by: Chao Leng <lengchao@huawei.com>
[hch: renamed, added a return value to clean up the callers a bit]
Signed-off-by: Christoph Hellwig <hch@lst.de>
drivers/nvme/host/core.c
drivers/nvme/host/nvme.h

index 0befaad788a094fa7d44dc6117dad8c018b96b8f..02579f4f776c7d2fccbb7c4d2b32192bdfc4adfa 100644 (file)
@@ -355,6 +355,21 @@ void nvme_complete_rq(struct request *req)
 }
 EXPORT_SYMBOL_GPL(nvme_complete_rq);
 
+/*
+ * Called to unwind from ->queue_rq on a failed command submission so that the
+ * multipathing code gets called to potentially failover to another path.
+ * The caller needs to unwind all transport specific resource allocations and
+ * must return propagate the return value.
+ */
+blk_status_t nvme_host_path_error(struct request *req)
+{
+       nvme_req(req)->status = NVME_SC_HOST_PATH_ERROR;
+       blk_mq_set_request_complete(req);
+       nvme_complete_rq(req);
+       return BLK_STS_OK;
+}
+EXPORT_SYMBOL_GPL(nvme_host_path_error);
+
 bool nvme_cancel_request(struct request *req, void *data, bool reserved)
 {
        dev_dbg_ratelimited(((struct nvme_ctrl *) data)->device,
index a72f0718109100492d66bc155233a962065e2483..5819f0381041491807b05362d9b5cf074897de50 100644 (file)
@@ -575,6 +575,7 @@ static inline bool nvme_is_aen_req(u16 qid, __u16 command_id)
 }
 
 void nvme_complete_rq(struct request *req);
+blk_status_t nvme_host_path_error(struct request *req);
 bool nvme_cancel_request(struct request *req, void *data, bool reserved);
 void nvme_cancel_tagset(struct nvme_ctrl *ctrl);
 void nvme_cancel_admin_tagset(struct nvme_ctrl *ctrl);