From nobody Sun Mar 22 14:14:04 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=zte.com.cn Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1774065887913201.1737585554555; Fri, 20 Mar 2026 21:04:47 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1w3nZT-0006hs-Dr; Sat, 21 Mar 2026 00:04:19 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1w3nZI-0006dL-Nd; Sat, 21 Mar 2026 00:04:09 -0400 Received: from mxct.zte.com.cn ([183.62.165.209]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1w3nZE-0006sf-JW; Sat, 21 Mar 2026 00:04:06 -0400 Received: from mse-fl1.zte.com.cn (unknown [10.5.228.132]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange x25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mxct.zte.com.cn (FangMail) with ESMTPS id 4fd5QZ3YgQz4xPSQ; Sat, 21 Mar 2026 12:03:50 +0800 (CST) Received: from njb2app06.zte.com.cn ([10.55.23.119]) by mse-fl1.zte.com.cn with SMTP id 62L43mHU064294; Sat, 21 Mar 2026 12:03:48 +0800 (+08) (envelope-from long.yunjian@zte.com.cn) Received: from mapi (njy2app01[null]) by mapi (Zmail) with MAPI id mid201; Sat, 21 Mar 2026 12:03:49 +0800 (CST) X-Zmail-TransId: 2af969be18a5f84-ed3c0 X-Mailer: Zmail v1.0 Message-ID: <20260321120349693fnwhekaw-qAQrFgoQPU4g@zte.com.cn> Date: Sat, 21 Mar 2026 12:03:49 +0800 (CST) Mime-Version: 1.0 From: To: , , , Cc: , , , Subject: =?UTF-8?B?W1BBVENIXSBtaXJyb3I6IEFkZCBzcGFyc2UgY29weSBzdXBwb3J0IGZvciByYXcgYmxvY2sgZGV2aWNlcw==?= X-MAIL: mse-fl1.zte.com.cn 62L43mHU064294 X-TLS: YES X-SPF-DOMAIN: zte.com.cn X-ENVELOPE-SENDER: long.yunjian@zte.com.cn X-SPF: None X-SOURCE-IP: 10.5.228.132 unknown Sat, 21 Mar 2026 12:03:50 +0800 X-Fangmail-Anti-Spam-Filtered: true X-Fangmail-MID-QID: 69BE18A6.000/4fd5QZ3YgQz4xPSQ Received-SPF: pass (zohomail.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; Received-SPF: pass client-ip=183.62.165.209; envelope-from=long.yunjian@zte.com.cn; helo=mxct.zte.com.cn X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.819, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.903, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, UNPARSEABLE_RELAY=0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZM-MESSAGEID: 1774065893408158500 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Yunjian Long In the raw block devices scenario, when the guest OS writes only a small amount of valid data, the current mirroring mechanism writes all the data to the destination. However, when the target device has already been zeroed, it is actually possible to skip writing zero data, which is very useful for performance improvement. Signed-off-by: Yunjian Long --- block/mirror.c | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/block/mirror.c b/block/mirror.c index 2fcded9e93..939a97f1ba 100644 --- a/block/mirror.c +++ b/block/mirror.c @@ -199,6 +199,22 @@ static void coroutine_fn mirror_wait_on_conflicts(Mirr= orOp *self, } } +static bool check_iov_is_zero(struct iovec *iov, int niov) +{ + int i =3D 0; + + if (niov <=3D 0) { + return false; + } + + for (i =3D 0; i < niov; i++) { + if (!buffer_is_zero(iov->iov_base, iov->iov_len)) { + return false; + } + } + return true; +} + static void coroutine_fn mirror_iteration_done(MirrorOp *op, int ret) { MirrorBlockJob *s =3D op->s; @@ -270,6 +286,12 @@ static void coroutine_fn mirror_read_complete(MirrorOp= *op, int ret) return; } + if (s->target_is_zero && op->qiov.size > 0 && + check_iov_is_zero(op->qiov.iov, op->qiov.niov)) { + mirror_iteration_done(op, ret); + return; + } + ret =3D blk_co_pwritev(s->target, op->offset, op->qiov.size, &op->qiov= , 0); mirror_write_complete(op, ret); } @@ -1656,8 +1678,14 @@ bdrv_mirror_top_do_write(BlockDriverState *bs, Mirro= rMethod method, MirrorOp *op =3D NULL; MirrorBDSOpaque *s =3D bs->opaque; int ret =3D 0; + bool target_force_write =3D false; - if (copy_to_target) { + if (s->job && s->job->target_is_zero && qiov->size > 0 && + check_iov_is_zero(qiov->iov, qiov->niov)) { + target_force_write =3D true; + } + + if (copy_to_target || target_force_write) { op =3D active_write_prepare(s->job, offset, bytes); } @@ -1689,12 +1717,12 @@ bdrv_mirror_top_do_write(BlockDriverState *bs, Mirr= orMethod method, goto out; } - if (copy_to_target) { + if (copy_to_target || target_force_write) { do_sync_target_write(s->job, method, offset, bytes, qiov, flags); } out: - if (copy_to_target) { + if (copy_to_target || target_force_write) { active_write_settle(op); } return ret; --=20 2.27.0