From nobody Mon Apr 29 03:15:48 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1502979175115145.57336592630543; Thu, 17 Aug 2017 07:12:55 -0700 (PDT) Received: from localhost ([::1]:54669 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1diLXZ-0004j1-9v for importer@patchew.org; Thu, 17 Aug 2017 10:12:53 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:59296) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1diLWg-0004Iv-3K for qemu-devel@nongnu.org; Thu, 17 Aug 2017 10:11:59 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1diLWc-0003XT-2g for qemu-devel@nongnu.org; Thu, 17 Aug 2017 10:11:58 -0400 Received: from mx1.redhat.com ([209.132.183.28]:59352) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1diLWb-0003XA-P9 for qemu-devel@nongnu.org; Thu, 17 Aug 2017 10:11:53 -0400 Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id B064C2C84 for ; Thu, 17 Aug 2017 14:11:52 +0000 (UTC) Received: from lemon.redhat.com (ovpn-12-16.pek2.redhat.com [10.72.12.16]) by smtp.corp.redhat.com (Postfix) with ESMTP id DD0F06CF45; Thu, 17 Aug 2017 14:11:49 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com B064C2C84 Authentication-Results: ext-mx03.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx03.extmail.prod.ext.phx2.redhat.com; spf=fail smtp.mailfrom=famz@redhat.com From: Fam Zheng To: qemu-devel@nongnu.org Date: Thu, 17 Aug 2017 22:11:48 +0800 Message-Id: <20170817141148.13111-1-famz@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Thu, 17 Aug 2017 14:11:52 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v2] scsi-block: Add qdev error properties X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Paolo Bonzini Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" This makes the werror/rerror options available on the scsi-block device, to allow user specify error handling policy in the same way as scsi-hd etc. Signed-off-by: Fam Zheng --- Take care of status, error, sense and QMP as well. [Paolo] --- hw/scsi/scsi-disk.c | 81 ++++++++++++++++++++++++++++++++++++++-----------= ---- 1 file changed, 59 insertions(+), 22 deletions(-) diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c index 5f1e5e8070..124d77c159 100644 --- a/hw/scsi/scsi-disk.c +++ b/hw/scsi/scsi-disk.c @@ -106,7 +106,8 @@ typedef struct SCSIDiskState bool tray_locked; } SCSIDiskState; =20 -static int scsi_handle_rw_error(SCSIDiskReq *r, int error, bool acct_faile= d); +static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int status, + bool update_sense, bool acct_failed); =20 static void scsi_free_request(SCSIRequest *req) { @@ -179,21 +180,23 @@ static void scsi_disk_load_request(QEMUFile *f, SCSIR= equest *req) =20 static bool scsi_disk_req_check_error(SCSIDiskReq *r, int ret, bool acct_f= ailed) { + int status =3D r->status ? *r->status : 0; + if (r->req.io_canceled) { scsi_req_cancel_complete(&r->req); return true; } =20 - if (ret < 0) { - return scsi_handle_rw_error(r, -ret, acct_failed); + if (ret < 0 || status) { + return scsi_handle_rw_error(r, -ret, status, !r->status, acct_fail= ed); } =20 - if (r->status && *r->status) { + if (status) { if (acct_failed) { SCSIDiskState *s =3D DO_UPCAST(SCSIDiskState, qdev, r->req.dev= ); block_acct_failed(blk_get_stats(s->qdev.conf.blk), &r->acct); } - scsi_req_complete(&r->req, *r->status); + scsi_req_complete(&r->req, status); return true; } =20 @@ -421,6 +424,22 @@ static void scsi_read_data(SCSIRequest *req) } } =20 +static bool scsi_sense_matches(SCSIDiskReq *r, SCSISense sense) +{ + SCSIRequest *req =3D &r->req; + if (req->sense[0] =3D=3D 0x70) { + return (req->sense[2] & 0xF) =3D=3D sense.key && + req->sense[12] =3D=3D sense.asc && + req->sense[13] =3D=3D sense.ascq; + } else if (req->sense[0] =3D=3D 0x72) { + return (req->sense[1] & 0xF) =3D=3D sense.key && + req->sense[2] =3D=3D sense.asc && + req->sense[3] =3D=3D sense.ascq; + } else { + return false; + } +} + /* * scsi_handle_rw_error has two return values. 0 means that the error * must be ignored, 1 means that the error has been processed and the @@ -428,7 +447,8 @@ static void scsi_read_data(SCSIRequest *req) * scsi_handle_rw_error always manages its reference counts, independent * of the return value. */ -static int scsi_handle_rw_error(SCSIDiskReq *r, int error, bool acct_faile= d) +static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int status, + bool update_sense, bool acct_failed) { bool is_read =3D (r->req.cmd.mode =3D=3D SCSI_XFER_FROM_DEV); SCSIDiskState *s =3D DO_UPCAST(SCSIDiskState, qdev, r->req.dev); @@ -439,22 +459,38 @@ static int scsi_handle_rw_error(SCSIDiskReq *r, int e= rror, bool acct_failed) if (acct_failed) { block_acct_failed(blk_get_stats(s->qdev.conf.blk), &r->acct); } - switch (error) { - 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; + if (update_sense) { + switch (error) { + 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; + } + } + } + if (!error) { + assert(status); + if (scsi_sense_matches(r, SENSE_CODE(NO_MEDIUM))) { + error =3D ENOMEDIUM; + } else if (scsi_sense_matches(r, SENSE_CODE(TARGET_FAILURE))) { + error =3D ENOMEM; + } else if (scsi_sense_matches(r, SENSE_CODE(INVALID_FIELD))) { + error =3D EINVAL; + } else if (scsi_sense_matches(r, SENSE_CODE(SPACE_ALLOC_FAILED))) { + error =3D ENOSPC; + } else { + error =3D EIO; } } blk_error_action(s->qdev.conf.blk, action, is_read, error); @@ -2972,6 +3008,7 @@ static const TypeInfo scsi_cd_info =3D { =20 #ifdef __linux__ static Property scsi_block_properties[] =3D { + DEFINE_BLOCK_ERROR_PROPERTIES(SCSIDiskState, qdev.conf), \ DEFINE_PROP_DRIVE("drive", SCSIDiskState, qdev.conf.blk), DEFINE_PROP_END_OF_LIST(), }; --=20 2.13.4