[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 01/10] scsi-disk: move scsi_handle_rw_error earlier
From: |
Paolo Bonzini |
Subject: |
[PATCH 01/10] scsi-disk: move scsi_handle_rw_error earlier |
Date: |
Wed, 24 Feb 2021 19:24:44 +0100 |
Remove the forward declaration.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
hw/scsi/scsi-disk.c | 168 ++++++++++++++++++++++----------------------
1 file changed, 83 insertions(+), 85 deletions(-)
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index a2716b26b4..18ab777017 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -111,8 +111,6 @@ struct SCSIDiskState {
uint16_t rotation_rate;
};
-static bool scsi_handle_rw_error(SCSIDiskReq *r, int error, bool acct_failed);
-
static void scsi_free_request(SCSIRequest *req)
{
SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req);
@@ -182,6 +180,89 @@ static void scsi_disk_load_request(QEMUFile *f,
SCSIRequest *req)
qemu_iovec_init_external(&r->qiov, &r->iov, 1);
}
+/*
+ * scsi_handle_rw_error has two return values. False means that the error
+ * must be ignored, true means that the error has been processed and the
+ * caller should not do anything else for this request. Note that
+ * scsi_handle_rw_error always manages its reference counts, independent
+ * of the return value.
+ */
+static bool scsi_handle_rw_error(SCSIDiskReq *r, int error, bool acct_failed)
+{
+ bool is_read = (r->req.cmd.mode == SCSI_XFER_FROM_DEV);
+ SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
+ SCSIDiskClass *sdc = (SCSIDiskClass *) object_get_class(OBJECT(s));
+ BlockErrorAction action = blk_get_error_action(s->qdev.conf.blk,
+ is_read, error);
+
+ if (action == BLOCK_ERROR_ACTION_REPORT) {
+ if (acct_failed) {
+ block_acct_failed(blk_get_stats(s->qdev.conf.blk), &r->acct);
+ }
+ switch (error) {
+ case 0:
+ /* A passthrough command has run and has produced sense data; check
+ * whether the error has to be handled by the guest or should
rather
+ * pause the host.
+ */
+ assert(r->status && *r->status);
+ if (scsi_sense_buf_is_guest_recoverable(r->req.sense,
sizeof(r->req.sense))) {
+ /* These errors are handled by guest. */
+ sdc->update_sense(&r->req);
+ scsi_req_complete(&r->req, *r->status);
+ return true;
+ }
+ 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;
+ case ENOMEM:
+ scsi_check_condition(r, SENSE_CODE(TARGET_FAILURE));
+ break;
+ case EINVAL:
+ scsi_check_condition(r, SENSE_CODE(INVALID_FIELD));
+ break;
+ case ENOSPC:
+ scsi_check_condition(r, SENSE_CODE(SPACE_ALLOC_FAILED));
+ break;
+ default:
+ scsi_check_condition(r, SENSE_CODE(IO_ERROR));
+ break;
+ }
+ }
+
+ blk_error_action(s->qdev.conf.blk, action, is_read, error);
+ if (action == BLOCK_ERROR_ACTION_IGNORE) {
+ scsi_req_complete(&r->req, 0);
+ return true;
+ }
+
+ if (action == BLOCK_ERROR_ACTION_STOP) {
+ scsi_req_retry(&r->req);
+ }
+ return true;
+}
+
static bool scsi_disk_req_check_error(SCSIDiskReq *r, int ret, bool
acct_failed)
{
if (r->req.io_canceled) {
@@ -428,89 +509,6 @@ static void scsi_read_data(SCSIRequest *req)
}
}
-/*
- * scsi_handle_rw_error has two return values. False means that the error
- * must be ignored, true means that the error has been processed and the
- * caller should not do anything else for this request. Note that
- * scsi_handle_rw_error always manages its reference counts, independent
- * of the return value.
- */
-static bool scsi_handle_rw_error(SCSIDiskReq *r, int error, bool acct_failed)
-{
- bool is_read = (r->req.cmd.mode == SCSI_XFER_FROM_DEV);
- SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev);
- SCSIDiskClass *sdc = (SCSIDiskClass *) object_get_class(OBJECT(s));
- BlockErrorAction action = blk_get_error_action(s->qdev.conf.blk,
- is_read, error);
-
- if (action == BLOCK_ERROR_ACTION_REPORT) {
- if (acct_failed) {
- block_acct_failed(blk_get_stats(s->qdev.conf.blk), &r->acct);
- }
- switch (error) {
- case 0:
- /* A passthrough command has run and has produced sense data; check
- * whether the error has to be handled by the guest or should
rather
- * pause the host.
- */
- assert(r->status && *r->status);
- if (scsi_sense_buf_is_guest_recoverable(r->req.sense,
sizeof(r->req.sense))) {
- /* These errors are handled by guest. */
- sdc->update_sense(&r->req);
- scsi_req_complete(&r->req, *r->status);
- return true;
- }
- 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;
- case ENOMEM:
- scsi_check_condition(r, SENSE_CODE(TARGET_FAILURE));
- break;
- case EINVAL:
- scsi_check_condition(r, SENSE_CODE(INVALID_FIELD));
- break;
- case ENOSPC:
- scsi_check_condition(r, SENSE_CODE(SPACE_ALLOC_FAILED));
- break;
- default:
- scsi_check_condition(r, SENSE_CODE(IO_ERROR));
- break;
- }
- }
-
- blk_error_action(s->qdev.conf.blk, action, is_read, error);
- if (action == BLOCK_ERROR_ACTION_IGNORE) {
- scsi_req_complete(&r->req, 0);
- return true;
- }
-
- if (action == BLOCK_ERROR_ACTION_STOP) {
- scsi_req_retry(&r->req);
- }
- return true;
-}
-
static void scsi_write_complete_noio(SCSIDiskReq *r, int ret)
{
uint32_t n;
--
2.29.2
- [PATCH 00/11] scsi-generic: error handling overhaul, Paolo Bonzini, 2021/02/24
- [PATCH 02/10] scsi-disk: do not complete requests early for rerror/werror=ignore, Paolo Bonzini, 2021/02/24
- [PATCH 04/10] scsi-disk: pass SCSI status to scsi_handle_rw_error, Paolo Bonzini, 2021/02/24
- [PATCH 03/10] scsi: introduce scsi_sense_from_errno(), Paolo Bonzini, 2021/02/24
- [PATCH 05/10] scsi-disk: pass guest recoverable errors through even for rerror=stop, Paolo Bonzini, 2021/02/24
- [PATCH 07/10] scsi: Rename linux-specific SG_ERR codes to generic SCSI_HOST error codes, Paolo Bonzini, 2021/02/24
- [PATCH 09/10] scsi: inline sg_io_sense_from_errno() into the callers., Paolo Bonzini, 2021/02/24
- [PATCH 10/10] scsi: move host_status handling into SCSI drivers, Paolo Bonzini, 2021/02/24
- [PATCH 06/10] scsi: drop 'result' argument from command_complete callback, Paolo Bonzini, 2021/02/24
- [PATCH 01/10] scsi-disk: move scsi_handle_rw_error earlier,
Paolo Bonzini <=
- [PATCH 08/10] scsi: Add mapping for generic SCSI_HOST status to sense codes, Paolo Bonzini, 2021/02/24
- Re: [PATCH 00/11] scsi-generic: error handling overhaul, Philippe Mathieu-Daudé, 2021/02/24