|
@@ -33,46 +33,18 @@ void nvme_failover_req(struct request *req)
|
|
|
kblockd_schedule_work(&ns->head->requeue_work);
|
|
|
}
|
|
|
|
|
|
-bool nvme_req_needs_failover(struct request *req)
|
|
|
+bool nvme_req_needs_failover(struct request *req, blk_status_t error)
|
|
|
{
|
|
|
if (!(req->cmd_flags & REQ_NVME_MPATH))
|
|
|
return false;
|
|
|
|
|
|
- switch (nvme_req(req)->status & 0x7ff) {
|
|
|
- /*
|
|
|
- * Generic command status:
|
|
|
- */
|
|
|
- case NVME_SC_INVALID_OPCODE:
|
|
|
- case NVME_SC_INVALID_FIELD:
|
|
|
- case NVME_SC_INVALID_NS:
|
|
|
- case NVME_SC_LBA_RANGE:
|
|
|
- case NVME_SC_CAP_EXCEEDED:
|
|
|
- case NVME_SC_RESERVATION_CONFLICT:
|
|
|
- return false;
|
|
|
-
|
|
|
- /*
|
|
|
- * I/O command set specific error. Unfortunately these values are
|
|
|
- * reused for fabrics commands, but those should never get here.
|
|
|
- */
|
|
|
- case NVME_SC_BAD_ATTRIBUTES:
|
|
|
- case NVME_SC_INVALID_PI:
|
|
|
- case NVME_SC_READ_ONLY:
|
|
|
- case NVME_SC_ONCS_NOT_SUPPORTED:
|
|
|
- WARN_ON_ONCE(nvme_req(req)->cmd->common.opcode ==
|
|
|
- nvme_fabrics_command);
|
|
|
- return false;
|
|
|
-
|
|
|
- /*
|
|
|
- * Media and Data Integrity Errors:
|
|
|
- */
|
|
|
- case NVME_SC_WRITE_FAULT:
|
|
|
- case NVME_SC_READ_ERROR:
|
|
|
- case NVME_SC_GUARD_CHECK:
|
|
|
- case NVME_SC_APPTAG_CHECK:
|
|
|
- case NVME_SC_REFTAG_CHECK:
|
|
|
- case NVME_SC_COMPARE_FAILED:
|
|
|
- case NVME_SC_ACCESS_DENIED:
|
|
|
- case NVME_SC_UNWRITTEN_BLOCK:
|
|
|
+ switch (error) {
|
|
|
+ case BLK_STS_NOTSUPP:
|
|
|
+ case BLK_STS_NOSPC:
|
|
|
+ case BLK_STS_TARGET:
|
|
|
+ case BLK_STS_NEXUS:
|
|
|
+ case BLK_STS_MEDIUM:
|
|
|
+ case BLK_STS_PROTECTION:
|
|
|
return false;
|
|
|
}
|
|
|
|