aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2020-11-12 10:52:04 +0100
committerPaolo Bonzini <pbonzini@redhat.com>2020-11-16 13:22:17 -0500
commit3b12a7fd39307017c8968b8d05986a63b33752b5 (patch)
tree81b8f40c70858a47d9326c948c74ceb470a67024
parentb430b51395650137a80e78ee7395165b80fe1752 (diff)
downloadqemu-3b12a7fd39307017c8968b8d05986a63b33752b5.zip
qemu-3b12a7fd39307017c8968b8d05986a63b33752b5.tar.gz
qemu-3b12a7fd39307017c8968b8d05986a63b33752b5.tar.bz2
scsi-disk: convert more errno values back to SCSI statuses
Linux has some OS-specific (and sometimes weird) mappings for various SCSI statuses and sense codes. The most important is probably RESERVATION CONFLICT. Add them so that they can be reported back to the guest kernel. Cc: Hannes Reinecke <hare@suse.de> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r--hw/scsi/scsi-disk.c19
1 files changed, 19 insertions, 0 deletions
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index e859534..90841ad 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -461,6 +461,25 @@ static bool scsi_handle_rw_error(SCSIDiskReq *r, int error, bool acct_failed)
}
error = scsi_sense_buf_to_errno(r->req.sense, sizeof(r->req.sense));
break;
+#ifdef CONFIG_LINUX
+ /* These errno mapping are specific to Linux. For more information:
+ * - scsi_decide_disposition in drivers/scsi/scsi_error.c
+ * - scsi_result_to_blk_status in drivers/scsi/scsi_lib.c
+ * - blk_errors[] in block/blk-core.c
+ */
+ case EBADE:
+ /* DID_NEXUS_FAILURE -> BLK_STS_NEXUS. */
+ scsi_req_complete(&r->req, RESERVATION_CONFLICT);
+ break;
+ case ENODATA:
+ /* DID_MEDIUM_ERROR -> BLK_STS_MEDIUM. */
+ scsi_check_condition(r, SENSE_CODE(READ_ERROR));
+ break;
+ case EREMOTEIO:
+ /* DID_TARGET_FAILURE -> BLK_STS_TARGET. */
+ scsi_req_complete(&r->req, HARDWARE_ERROR);
+ break;
+#endif
case ENOMEDIUM:
scsi_check_condition(r, SENSE_CODE(NO_MEDIUM));
break;