From nobody Fri Mar 29 14:03:20 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.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 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1573205912; cv=none; d=zoho.com; s=zohoarc; b=G7p6nv3J8gS+wIC6lRArO1BhKMPTKpTv9/qSwi1FMXchSwIsxYoqwcL+000KzqApDYgIesGIyfV3rhKGgjr/GxC3fOLPQJANcuFrTZ74Q1CUR/M07xTHmmZDCVb7HtAi/Y/KPSVLBt97Sd8MGWpn8TeshosOcldMPSxl4+IrAxs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1573205912; h=Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:Message-ID:References:Sender:Subject:To; bh=r5zdx6/A4HZL3Yk8sLfwRt/KT7Mpao2ycRNSnyCbXJU=; b=dxg8XzRH//iUSBIalEmfArYelLKtBDFfJJbFNSm23HAz41KEWeUJufE7EmYZc1Mjsz0Co22xQETqJpzhse9iWy+NPVFCma5TN6haMLI9XwzshA0S11VTiEBjedpl7sPBLdN4H7JRSOt2Y47sp2Zk0U36u23giekscYwj6qhLzYQ= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1573205912340901.5571567057239; Fri, 8 Nov 2019 01:38:32 -0800 (PST) Received: from localhost ([::1]:51104 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT0is-00054o-94 for importer@patchew.org; Fri, 08 Nov 2019 04:38:30 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:37739) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT0hB-0003F7-Fw for qemu-devel@nongnu.org; Fri, 08 Nov 2019 04:36:46 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iT0h9-0002UL-Hi for qemu-devel@nongnu.org; Fri, 08 Nov 2019 04:36:45 -0500 Received: from cmccmta2.chinamobile.com ([221.176.66.80]:4899) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1iT0h4-0002LD-80; Fri, 08 Nov 2019 04:36:39 -0500 Received: from spf.mail.chinamobile.com (unknown[172.16.121.3]) by rmmx-syy-dmz-app06-12006 (RichMail) with SMTP id 2ee65dc536d6057-8550e; Fri, 08 Nov 2019 17:35:18 +0800 (CST) Received: from localhost.novalocal (unknown[112.25.65.41]) by rmsmtp-syy-appsvr02-12002 (RichMail) with SMTP id 2ee25dc536d2c26-16e3e; Fri, 08 Nov 2019 17:35:17 +0800 (CST) X-RM-TRANSID: 2ee65dc536d6057-8550e X-RM-TagInfo: emlType=0 X-RM-SPAM-FLAG: 00000000 X-RM-TRANSID: 2ee25dc536d2c26-16e3e From: Yaowei Bai To: pbonzini@redhat.com, fam@euphon.net, dillaman@redhat.com, kwolf@redhat.com, mreitz@redhat.com Subject: [PATCH 1/4 V2] block: add SCSI COMPARE_AND_WRITE support Date: Fri, 8 Nov 2019 17:35:38 +0800 Message-Id: <1573205741-2094-2-git-send-email-baiyaowei@cmss.chinamobile.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1573205741-2094-1-git-send-email-baiyaowei@cmss.chinamobile.com> References: <1573205741-2094-1-git-send-email-baiyaowei@cmss.chinamobile.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 221.176.66.80 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: baiyaowei@cmss.chinamobile.com, yangjun@cmss.chinamobile.com, qemu-devel@nongnu.org, qemu-block@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Some storages(i.e. librbd) already have interfaces to handle some SCSI commands directly. This patch adds COMPARE_AND_WRITE command support through the write path in the block io layer by introducing a new element BDRV_REQ_COMPARE_AND_WRITE into BdrvRequestFlags which indicates a COMPARE_AND_WRITE request. In this way we could easily extend to other SCSI commands support like WRITE_SAME in the future. Signed-off-by: Yaowei Bai --- block/io.c | 20 ++++++++++++++++++++ include/block/block.h | 5 +++-- include/block/block_int.h | 3 +++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/block/io.c b/block/io.c index f75777f..3507d71 100644 --- a/block/io.c +++ b/block/io.c @@ -1186,6 +1186,26 @@ static int coroutine_fn bdrv_driver_pwritev(BlockDri= verState *bs, goto emulate_flags; } =20 + if (drv->bdrv_aio_compare_and_write && + (flags & BDRV_REQ_COMPARE_AND_WRITE)) { + BlockAIOCB *acb; + CoroutineIOCompletion co =3D { + .coroutine =3D qemu_coroutine_self(), + }; + + acb =3D drv->bdrv_aio_compare_and_write(bs, offset, bytes, qiov, + flags & bs->supported_write_flags, + bdrv_co_io_em_complete, &co); + flags &=3D ~bs->supported_write_flags; + if (acb =3D=3D NULL) { + ret =3D -EIO; + } else { + qemu_coroutine_yield(); + ret =3D co.ret; + } + goto emulate_flags; + } + if (drv->bdrv_aio_pwritev) { BlockAIOCB *acb; CoroutineIOCompletion co =3D { diff --git a/include/block/block.h b/include/block/block.h index 1df9848..f71aa4f 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -92,9 +92,10 @@ typedef enum { * on read request and means that caller doesn't really need data to be * written to qiov parameter which may be NULL. */ - BDRV_REQ_PREFETCH =3D 0x200, + BDRV_REQ_PREFETCH =3D 0x200, + BDRV_REQ_COMPARE_AND_WRITE =3D 0x400, /* Mask of valid flags */ - BDRV_REQ_MASK =3D 0x3ff, + BDRV_REQ_MASK =3D 0x7ff, } BdrvRequestFlags; =20 typedef struct BlockSizes { diff --git a/include/block/block_int.h b/include/block/block_int.h index dd033d0..96096e0 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -189,6 +189,9 @@ struct BlockDriver { BlockAIOCB *(*bdrv_aio_pdiscard)(BlockDriverState *bs, int64_t offset, int bytes, BlockCompletionFunc *cb, void *opaque); + BlockAIOCB *(*bdrv_aio_compare_and_write)(BlockDriverState *bs, + uint64_t offset, uint64_t bytes, QEMUIOVector *qiov, int flags, + BlockCompletionFunc *cb, void *opaque); =20 int coroutine_fn (*bdrv_co_readv)(BlockDriverState *bs, int64_t sector_num, int nb_sectors, QEMUIOVector *qiov); --=20 1.8.3.1 From nobody Fri Mar 29 14:03:20 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.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 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1573206018; cv=none; d=zoho.com; s=zohoarc; b=fEtzc6FSHFe4EmMoRnBedKGTd3M+JQFWZUT7cj1E9hQG9nJ8SBFyOaMcJ1Fkfpw6d2OcOsG6jQDsLOafzst9VUFch3qT2Dzm7iNyVO4XxBzYw7GiGA121U+TvOAb7ruWTQhs7LN7qu20ZAW7uz7A+jUTUmZ5X7hd7uUP7ptzztM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1573206018; h=Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:Message-ID:References:Sender:Subject:To; bh=jisRdgWbyZcwElIwrv5G/uBMA7TbM+0hEiIIaX7r64I=; b=KI1LhDt89SBUCquzqHYYiF4cRCiRHtLWOp5+FUlyuf0f+Dt5zhgqOWfLaoIAUIdaVhCVeG6ZZUqvomo454gzTi6vLO7qllhzX9HcdWDWp06eBHgxnPtmcbQm/6YoSYMqRFSB1Ikgto2Xtykkmp9fiJCvnq3vJn4niyG5Mba5LnU= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1573206018772306.68136601667186; Fri, 8 Nov 2019 01:40:18 -0800 (PST) Received: from localhost ([::1]:51120 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT0kb-0006uL-8S for importer@patchew.org; Fri, 08 Nov 2019 04:40:17 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:37774) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT0hE-0003JI-0Y for qemu-devel@nongnu.org; Fri, 08 Nov 2019 04:36:49 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iT0hC-0002XC-NF for qemu-devel@nongnu.org; Fri, 08 Nov 2019 04:36:47 -0500 Received: from cmccmta1.chinamobile.com ([221.176.66.79]:3513) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1iT0h8-0002Rf-5t; Fri, 08 Nov 2019 04:36:43 -0500 Received: from spf.mail.chinamobile.com (unknown[172.16.121.3]) by rmmx-syy-dmz-app01-12001 (RichMail) with SMTP id 2ee15dc536d717f-854e7; Fri, 08 Nov 2019 17:35:19 +0800 (CST) Received: from localhost.novalocal (unknown[112.25.65.41]) by rmsmtp-syy-appsvr02-12002 (RichMail) with SMTP id 2ee25dc536d2c26-16e45; Fri, 08 Nov 2019 17:35:18 +0800 (CST) X-RM-TRANSID: 2ee15dc536d717f-854e7 X-RM-TagInfo: emlType=0 X-RM-SPAM-FLAG: 00000000 X-RM-TRANSID: 2ee25dc536d2c26-16e45 From: Yaowei Bai To: pbonzini@redhat.com, fam@euphon.net, dillaman@redhat.com, kwolf@redhat.com, mreitz@redhat.com Subject: [PATCH 2/4 V2] block/rbd: implement bdrv_aio_compare_and_write interface Date: Fri, 8 Nov 2019 17:35:39 +0800 Message-Id: <1573205741-2094-3-git-send-email-baiyaowei@cmss.chinamobile.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1573205741-2094-1-git-send-email-baiyaowei@cmss.chinamobile.com> References: <1573205741-2094-1-git-send-email-baiyaowei@cmss.chinamobile.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 221.176.66.79 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: baiyaowei@cmss.chinamobile.com, yangjun@cmss.chinamobile.com, qemu-devel@nongnu.org, qemu-block@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" This patch adds librbd's SCSI COMPARE_AND_WRITE command interface support with bdrv_aio_compare_and_write function pointer. Note currently when a miscompare happens a mismatch offset of 0 is always reported rather than the actual mismatch offset. This should not be a big issue contemporarily and will be fixed accordingly in the future. Signed-off-by: Yaowei Bai --- block/raw-format.c | 3 ++- block/rbd.c | 45 +++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/block/raw-format.c b/block/raw-format.c index 3a76ec7..e87cd44 100644 --- a/block/raw-format.c +++ b/block/raw-format.c @@ -439,7 +439,8 @@ static int raw_open(BlockDriverState *bs, QDict *option= s, int flags, =20 bs->sg =3D bs->file->bs->sg; bs->supported_write_flags =3D BDRV_REQ_WRITE_UNCHANGED | - (BDRV_REQ_FUA & bs->file->bs->supported_write_flags); + (BDRV_REQ_FUA & bs->file->bs->supported_write_flags) | + (BDRV_REQ_COMPARE_AND_WRITE & bs->file->bs->supported_write_flags); bs->supported_zero_flags =3D BDRV_REQ_WRITE_UNCHANGED | ((BDRV_REQ_FUA | BDRV_REQ_MAY_UNMAP | BDRV_REQ_NO_FALLBACK) & bs->file->bs->supported_zero_flags); diff --git a/block/rbd.c b/block/rbd.c index 027cbcc..0e45bc3 100644 --- a/block/rbd.c +++ b/block/rbd.c @@ -73,11 +73,18 @@ #define LIBRBD_USE_IOVEC 0 #endif =20 +#ifdef LIBRBD_SUPPORTS_COMPARE_AND_WRITE +#define LIBRBD_HAVE_COMPARE_AND_WRITE 1 +#else +#define LIBRBD_HAVE_COMPARE_AND_WRITE 0 +#endif + typedef enum { RBD_AIO_READ, RBD_AIO_WRITE, RBD_AIO_DISCARD, - RBD_AIO_FLUSH + RBD_AIO_FLUSH, + RBD_AIO_COMPARE_AND_WRITE } RBDAIOCmd; =20 typedef struct RBDAIOCB { @@ -798,6 +805,10 @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *= options, int flags, } } =20 + if (LIBRBD_HAVE_COMPARE_AND_WRITE) { + bs->supported_write_flags =3D BDRV_REQ_COMPARE_AND_WRITE; + } + r =3D 0; goto out; =20 @@ -933,7 +944,15 @@ static BlockAIOCB *rbd_start_aio(BlockDriverState *bs, =20 rcb =3D g_new(RADOSCB, 1); =20 - if (!LIBRBD_USE_IOVEC) { + if (cmd =3D=3D RBD_AIO_COMPARE_AND_WRITE) { + acb->bounce =3D qemu_try_blockalign(bs, qiov->size); + if (acb->bounce =3D=3D NULL) { + goto failed; + } + + qemu_iovec_to_buf(acb->qiov, 0, acb->bounce, qiov->size); + rcb->buf =3D acb->bounce; + } else if (!LIBRBD_USE_IOVEC) { if (cmd =3D=3D RBD_AIO_DISCARD || cmd =3D=3D RBD_AIO_FLUSH) { acb->bounce =3D NULL; } else { @@ -993,6 +1012,10 @@ static BlockAIOCB *rbd_start_aio(BlockDriverState *bs, case RBD_AIO_FLUSH: r =3D rbd_aio_flush_wrapper(s->image, c); break; + case RBD_AIO_COMPARE_AND_WRITE: + r =3D rbd_aio_compare_and_write(s->image, off, size / 2, rcb->buf, + (rcb->buf + size / 2), c, 0, 0); + break; default: r =3D -EINVAL; } @@ -1056,6 +1079,20 @@ static int qemu_rbd_co_flush(BlockDriverState *bs) } #endif =20 +#ifdef LIBRBD_SUPPORTS_COMPARE_AND_WRITE +static BlockAIOCB *qemu_rbd_aio_compare_and_write(BlockDriverState *bs, + uint64_t offset, + uint64_t bytes, + QEMUIOVector *qiov, + int flags, + BlockCompletionFunc *cb, + void *opaque) +{ + return rbd_start_aio(bs, offset, qiov, bytes, cb, opaque, + RBD_AIO_COMPARE_AND_WRITE); +} +#endif + static int qemu_rbd_getinfo(BlockDriverState *bs, BlockDriverInfo *bdi) { BDRVRBDState *s =3D bs->opaque; @@ -1310,6 +1347,10 @@ static BlockDriver bdrv_rbd =3D { .bdrv_aio_pdiscard =3D qemu_rbd_aio_pdiscard, #endif =20 +#ifdef LIBRBD_SUPPORTS_COMPARE_AND_WRITE + .bdrv_aio_compare_and_write =3D qemu_rbd_aio_compare_and_write, +#endif + .bdrv_snapshot_create =3D qemu_rbd_snap_create, .bdrv_snapshot_delete =3D qemu_rbd_snap_remove, .bdrv_snapshot_list =3D qemu_rbd_snap_list, --=20 1.8.3.1 From nobody Fri Mar 29 14:03:20 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.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 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1573206055; cv=none; d=zoho.com; s=zohoarc; b=TZe1xo0qIaPo7s821Dlz7xZcACDZ2YsrF2PrnOA34tPJ7YuZ6FumVjNqlhs1lAnxIK5eKtq66rUZzY13bpV8BqF6MaQhe6KaUHT4M1cYiRbuh1Or4tHAhrW0E1V4Rpt2PX8KwYqvQcLIWkyv/zFLRw33rcGH7zJ/4SGyiSnVLMo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1573206055; h=Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:Message-ID:References:Sender:Subject:To; bh=+T3ha/tZ+pXUg0ZhQZllpTcOJTaw4RTtBINUu2yrbaQ=; b=eDB1vhyWNn4BxJhMlSa4ym7YdcuqGCAsFjfTBtPRfNAIBNIrGVC3pzHokjexAonmAXOQ6eQwGYsbhqhV1PurlsS9+F4BEZchWTh/noryWwn205UEO80IeBWQv3bnsthA8Cb/BXHnm2zZAGDIbxRqbnEMyPXTZ368OfCXy/yEqtU= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1573206055660232.72762204871992; Fri, 8 Nov 2019 01:40:55 -0800 (PST) Received: from localhost ([::1]:51124 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT0lA-0007oh-Gr for importer@patchew.org; Fri, 08 Nov 2019 04:40:52 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:37916) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT0hu-0004MZ-Eg for qemu-devel@nongnu.org; Fri, 08 Nov 2019 04:37:32 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iT0hs-00035s-QY for qemu-devel@nongnu.org; Fri, 08 Nov 2019 04:37:30 -0500 Received: from cmccmta2.chinamobile.com ([221.176.66.80]:4100) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1iT0ho-00031u-MA; Fri, 08 Nov 2019 04:37:25 -0500 Received: from spf.mail.chinamobile.com (unknown[172.16.121.3]) by rmmx-syy-dmz-app08-12008 (RichMail) with SMTP id 2ee85dc536d7063-85542; Fri, 08 Nov 2019 17:35:19 +0800 (CST) Received: from localhost.novalocal (unknown[112.25.65.41]) by rmsmtp-syy-appsvr02-12002 (RichMail) with SMTP id 2ee25dc536d2c26-16e46; Fri, 08 Nov 2019 17:35:19 +0800 (CST) X-RM-TRANSID: 2ee85dc536d7063-85542 X-RM-TagInfo: emlType=0 X-RM-SPAM-FLAG: 00000000 X-RM-TRANSID: 2ee25dc536d2c26-16e46 From: Yaowei Bai To: pbonzini@redhat.com, fam@euphon.net, dillaman@redhat.com, kwolf@redhat.com, mreitz@redhat.com Subject: [PATCH 3/4 V2] hw/scsi: add SCSI COMPARE_AND_WRITE support Date: Fri, 8 Nov 2019 17:35:40 +0800 Message-Id: <1573205741-2094-4-git-send-email-baiyaowei@cmss.chinamobile.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1573205741-2094-1-git-send-email-baiyaowei@cmss.chinamobile.com> References: <1573205741-2094-1-git-send-email-baiyaowei@cmss.chinamobile.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 221.176.66.80 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: baiyaowei@cmss.chinamobile.com, yangjun@cmss.chinamobile.com, qemu-devel@nongnu.org, qemu-block@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" This patch emulates COMPARE_AND_WRITE command with the BDRV_REQ_COMPARE_AND_WRITE flag introduced by last patch. It matches the SBC-4 standard except the FUA bit support, it'll be finished in the next patch. Note that cmd->xfer is set 2 * the number got by scsi_data_cdb_xfer so we could touch the least code. Signed-off-by: Yaowei Bai --- hw/scsi/emulation.c | 1 + hw/scsi/scsi-bus.c | 4 +++ hw/scsi/scsi-disk.c | 88 +++++++++++++++++++++++++++++++++++++++++= ++++ hw/scsi/trace-events | 1 + include/hw/scsi/emulation.h | 3 ++ include/scsi/utils.h | 2 ++ scsi/utils.c | 5 +++ 7 files changed, 104 insertions(+) diff --git a/hw/scsi/emulation.c b/hw/scsi/emulation.c index 06d62f3..1f53c4a 100644 --- a/hw/scsi/emulation.c +++ b/hw/scsi/emulation.c @@ -9,6 +9,7 @@ int scsi_emulate_block_limits(uint8_t *outbuf, const SCSIBl= ockLimits *bl) memset(outbuf, 0, 0x3c); =20 outbuf[0] =3D bl->wsnz; /* wsnz */ + outbuf[1] =3D MAX_COMPARE_AND_WRITE_LENGTH; =20 if (bl->max_io_sectors) { /* optimal transfer length granularity. This field and the optimal diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c index 359d50d..a20eb11 100644 --- a/hw/scsi/scsi-bus.c +++ b/hw/scsi/scsi-bus.c @@ -1003,6 +1003,9 @@ static int scsi_req_xfer(SCSICommand *cmd, SCSIDevice= *dev, uint8_t *buf) case WRITE_VERIFY_16: cmd->xfer *=3D dev->blocksize; break; + case COMPARE_AND_WRITE: + cmd->xfer *=3D 2 * dev->blocksize; + break; case READ_6: case READ_REVERSE: /* length 0 means 256 blocks */ @@ -1222,6 +1225,7 @@ static void scsi_cmd_xfer_mode(SCSICommand *cmd) case PERSISTENT_RESERVE_OUT: case MAINTENANCE_OUT: case SET_WINDOW: + case COMPARE_AND_WRITE: case SCAN: /* SCAN conflicts with START_STOP. START_STOP has cmd->xfer set t= o 0 for * non-scanner devices, so we only get here for SCAN and not for S= TART_STOP. diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c index 07fb5eb..f9a0267 100644 --- a/hw/scsi/scsi-disk.c +++ b/hw/scsi/scsi-disk.c @@ -478,6 +478,9 @@ static bool scsi_handle_rw_error(SCSIDiskReq *r, int er= ror, bool acct_failed) case ENOSPC: scsi_check_condition(r, SENSE_CODE(SPACE_ALLOC_FAILED)); break; + case EILSEQ: + scsi_check_condition(r, SENSE_CODE(MISCOMPARE_DURING_VERIFY)); + break; default: scsi_check_condition(r, SENSE_CODE(IO_ERROR)); break; @@ -1825,6 +1828,84 @@ static void scsi_disk_emulate_write_same(SCSIDiskReq= *r, uint8_t *inbuf) scsi_write_same_complete, data); } =20 +typedef struct CompareAndWriteCBData { + SCSIDiskReq *r; + int64_t sector; + int nb_sectors; + QEMUIOVector qiov; + struct iovec iov; +} CompareAndWriteCBData; + +static void scsi_compare_and_write_complete(void *opaque, int ret) +{ + CompareAndWriteCBData *data =3D opaque; + SCSIDiskReq *r =3D data->r; + SCSIDiskState *s =3D DO_UPCAST(SCSIDiskState, qdev, r->req.dev); + + assert(r->req.aiocb !=3D NULL); + r->req.aiocb =3D NULL; + aio_context_acquire(blk_get_aio_context(s->qdev.conf.blk)); + if (scsi_disk_req_check_error(r, ret, true)) { + goto done; + } + + block_acct_done(blk_get_stats(s->qdev.conf.blk), &r->acct); + scsi_req_complete(&r->req, GOOD); + +done: + scsi_req_unref(&r->req); + qemu_vfree(data->iov.iov_base); + g_free(data); + aio_context_release(blk_get_aio_context(s->qdev.conf.blk)); +} + +static void scsi_disk_emulate_compare_and_write(SCSIDiskReq *r, uint8_t *i= nbuf) +{ + SCSIRequest *req =3D &r->req; + SCSIDiskState *s =3D DO_UPCAST(SCSIDiskState, qdev, req->dev); + uint32_t nb_sectors =3D scsi_data_cdb_xfer(r->req.cmd.buf); + CompareAndWriteCBData *data; + uint8_t *buf; + int i; + + if (nb_sectors > MAX_COMPARE_AND_WRITE_LENGTH) { + scsi_check_condition(r, SENSE_CODE(INVALID_FIELD)); + return; + } + + if (blk_is_read_only(s->qdev.conf.blk)) { + scsi_check_condition(r, SENSE_CODE(WRITE_PROTECTED)); + return; + } + + if (r->req.cmd.lba > s->qdev.max_lba || + !check_lba_range(s, r->req.cmd.lba, nb_sectors)) { + scsi_check_condition(r, SENSE_CODE(LBA_OUT_OF_RANGE)); + return; + } + + data =3D g_new0(CompareAndWriteCBData, 1); + data->r =3D r; + data->sector =3D r->req.cmd.lba * (s->qdev.blocksize / 512); + data->nb_sectors =3D r->req.cmd.xfer * (s->qdev.blocksize / 512); + data->iov.iov_len =3D data->nb_sectors; + data->iov.iov_base =3D buf =3D blk_blockalign(s->qdev.conf.blk, + data->iov.iov_len); + qemu_iovec_init_external(&data->qiov, &data->iov, 1); + + for (i =3D 0; i < data->iov.iov_len; i +=3D s->qdev.blocksize) { + memcpy(&buf[i], &inbuf[i], s->qdev.blocksize); + } + + scsi_req_ref(&r->req); + block_acct_start(blk_get_stats(s->qdev.conf.blk), &r->acct, + data->iov.iov_len, BLOCK_ACCT_WRITE); + r->req.aiocb =3D blk_aio_pwritev(s->qdev.conf.blk, + data->sector << BDRV_SECTOR_BITS, + &data->qiov, BDRV_REQ_COMPARE_AND_WRITE, + scsi_compare_and_write_complete, data); +} + static void scsi_disk_emulate_write_data(SCSIRequest *req) { SCSIDiskReq *r =3D DO_UPCAST(SCSIDiskReq, req, req); @@ -1861,6 +1942,9 @@ static void scsi_disk_emulate_write_data(SCSIRequest = *req) scsi_disk_emulate_write_same(r, r->iov.iov_base); break; =20 + case COMPARE_AND_WRITE: + scsi_disk_emulate_compare_and_write(r, r->iov.iov_base); + break; default: abort(); } @@ -2115,6 +2199,9 @@ static int32_t scsi_disk_emulate_command(SCSIRequest = *req, uint8_t *buf) trace_scsi_disk_emulate_command_WRITE_SAME( req->cmd.buf[0] =3D=3D WRITE_SAME_10 ? 10 : 16, r->req.cmd= .xfer); break; + case COMPARE_AND_WRITE: + trace_scsi_disk_emulate_command_COMPARE_AND_WRITE(r->req.cmd.xfer); + break; default: trace_scsi_disk_emulate_command_UNKNOWN(buf[0], scsi_command_name(buf[0])); @@ -2542,6 +2629,7 @@ static const SCSIReqOps *const scsi_disk_reqops_dispa= tch[256] =3D { [VERIFY_10] =3D &scsi_disk_emulate_reqops, [VERIFY_12] =3D &scsi_disk_emulate_reqops, [VERIFY_16] =3D &scsi_disk_emulate_reqops, + [COMPARE_AND_WRITE] =3D &scsi_disk_emulate_reqops, =20 [READ_6] =3D &scsi_disk_dma_reqops, [READ_10] =3D &scsi_disk_dma_reqops, diff --git a/hw/scsi/trace-events b/hw/scsi/trace-events index b082005..0783e58 100644 --- a/hw/scsi/trace-events +++ b/hw/scsi/trace-events @@ -317,6 +317,7 @@ scsi_disk_emulate_command_MODE_SELECT_10(size_t xfer) "= Mode Select(10) (len %zd) scsi_disk_emulate_command_UNMAP(size_t xfer) "Unmap (len %zd)" scsi_disk_emulate_command_VERIFY(int bytchk) "Verify (bytchk %d)" scsi_disk_emulate_command_WRITE_SAME(int cmd, size_t xfer) "WRITE SAME %d = (len %zd)" +scsi_disk_emulate_command_COMPARE_AND_WRITE(size_t xfer) "COMPARE AND WRIT= E (len %zd)" scsi_disk_emulate_command_UNKNOWN(int cmd, const char *name) "Unknown SCSI= command (0x%2.2x=3D%s)" scsi_disk_dma_command_READ(uint64_t lba, uint32_t len) "Read (sector %" PR= Id64 ", count %u)" scsi_disk_dma_command_WRITE(const char *cmd, uint64_t lba, int len) "Write= %s(sector %" PRId64 ", count %u)" diff --git a/include/hw/scsi/emulation.h b/include/hw/scsi/emulation.h index 9521704..2148316 100644 --- a/include/hw/scsi/emulation.h +++ b/include/hw/scsi/emulation.h @@ -1,6 +1,9 @@ #ifndef HW_SCSI_EMULATION_H #define HW_SCSI_EMULATION_H =20 +/* maximum compare and write length : 64kb */ +#define MAX_COMPARE_AND_WRITE_LENGTH 128 + typedef struct SCSIBlockLimits { bool wsnz; uint16_t min_io_size; diff --git a/include/scsi/utils.h b/include/scsi/utils.h index fbc5588..35f554e 100644 --- a/include/scsi/utils.h +++ b/include/scsi/utils.h @@ -101,6 +101,8 @@ extern const struct SCSISense sense_code_DEVICE_INTERNA= L_RESET; extern const struct SCSISense sense_code_WRITE_PROTECTED; /* Data Protection, Space Allocation Failed Write Protect */ extern const struct SCSISense sense_code_SPACE_ALLOC_FAILED; +/* Miscompare, Miscompare During Verify Operation */ +extern const struct SCSISense sense_code_MISCOMPARE_DURING_VERIFY; =20 #define SENSE_CODE(x) sense_code_ ## x =20 diff --git a/scsi/utils.c b/scsi/utils.c index c50e81f..c142a53 100644 --- a/scsi/utils.c +++ b/scsi/utils.c @@ -311,6 +311,11 @@ const struct SCSISense sense_code_SPACE_ALLOC_FAILED = =3D { .key =3D DATA_PROTECT, .asc =3D 0x27, .ascq =3D 0x07 }; =20 +/* Miscompare, Miscompare During Verify Operation */ +const struct SCSISense sense_code_MISCOMPARE_DURING_VERIFY =3D { + .key =3D MISCOMPARE, .asc =3D 0x1d, .ascq =3D 0x00 +}; + /* * scsi_convert_sense * --=20 1.8.3.1 From nobody Fri Mar 29 14:03:20 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.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 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1573205888; cv=none; d=zoho.com; s=zohoarc; b=K2JGBCl3EdTW3bWKNzk1wtKkjpXZ3sFUuLg7WNRzpt+wNoP/jFfmessXDpWsO+78WQTLWCqZwzuA4Wr4M5GwzRKmzygWZN3zZPPxutMB+wLOvTmKb2olm4ZAPpxKZECPG2hXL3I06F/WYoYtz3ygpqa8Aq3xJOkW7Dh7IsCoHkY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1573205888; h=Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:Message-ID:References:Sender:Subject:To; bh=aaq20cKPP3sYk8W9hRhifecyuUlBBQn3xt+aLd9cZZg=; b=DJhPBaN5Uz+T1NQ4rG97Ds18V3b3TLv13FGarlTEkco/UJTCL9xACOyK/DONepr8tbUQnOEU/g0bqdqpT6MQhbzXU//dtuSgrI9Dr55fJbaYYHnmrIncXvwTq3cjjfTfK167NaoQQm0Co3Z82Mj82XIXsgKt78bwb4lYeK/AM6M= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1573205888371877.637165884732; Fri, 8 Nov 2019 01:38:08 -0800 (PST) Received: from localhost ([::1]:51102 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT0iU-0004m7-4p for importer@patchew.org; Fri, 08 Nov 2019 04:38:06 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:37684) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iT0h5-0003BJ-NR for qemu-devel@nongnu.org; Fri, 08 Nov 2019 04:36:41 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iT0h3-0002Oz-PG for qemu-devel@nongnu.org; Fri, 08 Nov 2019 04:36:39 -0500 Received: from cmccmta2.chinamobile.com ([221.176.66.80]:26086) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1iT0gx-0002Cv-Fu; Fri, 08 Nov 2019 04:36:32 -0500 Received: from spf.mail.chinamobile.com (unknown[172.16.121.3]) by rmmx-syy-dmz-app07-12007 (RichMail) with SMTP id 2ee75dc536d81fa-857d8; Fri, 08 Nov 2019 17:35:20 +0800 (CST) Received: from localhost.novalocal (unknown[112.25.65.41]) by rmsmtp-syy-appsvr02-12002 (RichMail) with SMTP id 2ee25dc536d2c26-16e4c; Fri, 08 Nov 2019 17:35:19 +0800 (CST) X-RM-TRANSID: 2ee75dc536d81fa-857d8 X-RM-TagInfo: emlType=0 X-RM-SPAM-FLAG: 00000000 X-RM-TRANSID: 2ee25dc536d2c26-16e4c From: Yaowei Bai To: pbonzini@redhat.com, fam@euphon.net, dillaman@redhat.com, kwolf@redhat.com, mreitz@redhat.com Subject: [PATCH 4/4 V2] scsi-disk: add FUA support for COMPARE_AND_WRITE Date: Fri, 8 Nov 2019 17:35:41 +0800 Message-Id: <1573205741-2094-5-git-send-email-baiyaowei@cmss.chinamobile.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1573205741-2094-1-git-send-email-baiyaowei@cmss.chinamobile.com> References: <1573205741-2094-1-git-send-email-baiyaowei@cmss.chinamobile.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x [fuzzy] X-Received-From: 221.176.66.80 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: baiyaowei@cmss.chinamobile.com, yangjun@cmss.chinamobile.com, qemu-devel@nongnu.org, qemu-block@nongnu.org Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" It is implemented in the blk_aio_pwritev's callback function in a way similar to its emulation in scsi_write_do_fua function Signed-off-by: Yaowei Bai --- hw/scsi/scsi-disk.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c index f9a0267..0731a3b 100644 --- a/hw/scsi/scsi-disk.c +++ b/hw/scsi/scsi-disk.c @@ -229,6 +229,7 @@ static bool scsi_is_cmd_fua(SCSICommand *cmd) case WRITE_10: case WRITE_12: case WRITE_16: + case COMPARE_AND_WRITE: return (cmd->buf[1] & 8) !=3D 0; =20 case VERIFY_10: @@ -1850,10 +1851,17 @@ static void scsi_compare_and_write_complete(void *o= paque, int ret) } =20 block_acct_done(blk_get_stats(s->qdev.conf.blk), &r->acct); + if (r->need_fua_emulation) { + block_acct_start(blk_get_stats(s->qdev.conf.blk), &r->acct, 0, + BLOCK_ACCT_FLUSH); + r->req.aiocb =3D blk_aio_flush(s->qdev.conf.blk, scsi_aio_complete= , r); + goto free; + } scsi_req_complete(&r->req, GOOD); =20 done: scsi_req_unref(&r->req); +free: qemu_vfree(data->iov.iov_base); g_free(data); aio_context_release(blk_get_aio_context(s->qdev.conf.blk)); @@ -1954,6 +1962,7 @@ static int32_t scsi_disk_emulate_command(SCSIRequest = *req, uint8_t *buf) { SCSIDiskReq *r =3D DO_UPCAST(SCSIDiskReq, req, req); SCSIDiskState *s =3D DO_UPCAST(SCSIDiskState, qdev, req->dev); + SCSIDiskClass *sdc =3D (SCSIDiskClass *) object_get_class(OBJECT(s)); uint64_t nb_sectors; uint8_t *outbuf; int buflen; @@ -2209,6 +2218,7 @@ static int32_t scsi_disk_emulate_command(SCSIRequest = *req, uint8_t *buf) return 0; } assert(!r->req.aiocb); + r->need_fua_emulation =3D sdc->need_fua_emulation(&r->req.cmd); r->iov.iov_len =3D MIN(r->buflen, req->cmd.xfer); if (r->iov.iov_len =3D=3D 0) { scsi_req_complete(&r->req, GOOD); --=20 1.8.3.1