From nobody Tue May 21 14:19:47 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; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1530585709147824.0217045924704; Mon, 2 Jul 2018 19:41:49 -0700 (PDT) Received: from localhost ([::1]:37477 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1faBGG-0007sX-GP for importer@patchew.org; Mon, 02 Jul 2018 22:41:48 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35775) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1faBCp-0005JG-Ey for qemu-devel@nongnu.org; Mon, 02 Jul 2018 22:38:18 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1faBCo-0008DY-Ir for qemu-devel@nongnu.org; Mon, 02 Jul 2018 22:38:15 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:38732 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1faBCm-0008Bv-70; Mon, 02 Jul 2018 22:38:12 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id B8D91857AB; Tue, 3 Jul 2018 02:38:11 +0000 (UTC) Received: from lemon.usersys.redhat.com (ovpn-12-86.pek2.redhat.com [10.72.12.86]) by smtp.corp.redhat.com (Postfix) with ESMTP id 723662156889; Tue, 3 Jul 2018 02:38:08 +0000 (UTC) From: Fam Zheng To: qemu-devel@nongnu.org Date: Tue, 3 Jul 2018 10:37:56 +0800 Message-Id: <20180703023758.14422-2-famz@redhat.com> In-Reply-To: <20180703023758.14422-1-famz@redhat.com> References: <20180703023758.14422-1-famz@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.6 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.2]); Tue, 03 Jul 2018 02:38:11 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.2]); Tue, 03 Jul 2018 02:38:11 +0000 (UTC) for IP:'10.11.54.6' DOMAIN:'int-mx06.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'famz@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [PATCH v4 1/3] block: Fix parameter checking in bdrv_co_copy_range_internal 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: Kevin Wolf , Fam Zheng , qemu-block@nongnu.org, Jeff Cody , Max Reitz , Stefan Hajnoczi 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" src may be NULL if BDRV_REQ_ZERO_WRITE flag is set, in this case only check dst and dst->bs. This bug was introduced when moving in the request tracking code from bdrv_co_copy_range, in 37aec7d75eb. This especially fixes the possible segfault when initializing src_bs with a NULL src. Signed-off-by: Fam Zheng Reviewed-by: Jeff Cody --- block/io.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/block/io.c b/block/io.c index 7035b78a20..b8845708d7 100644 --- a/block/io.c +++ b/block/io.c @@ -2897,18 +2897,11 @@ static int coroutine_fn bdrv_co_copy_range_internal= (BdrvChild *src, bool recurse_src) { BdrvTrackedRequest src_req, dst_req; - BlockDriverState *src_bs =3D src->bs; - BlockDriverState *dst_bs =3D dst->bs; int ret; =20 - if (!src || !dst || !src->bs || !dst->bs) { + if (!dst || !dst->bs) { return -ENOMEDIUM; } - ret =3D bdrv_check_byte_request(src->bs, src_offset, bytes); - if (ret) { - return ret; - } - ret =3D bdrv_check_byte_request(dst->bs, dst_offset, bytes); if (ret) { return ret; @@ -2917,16 +2910,24 @@ static int coroutine_fn bdrv_co_copy_range_internal= (BdrvChild *src, return bdrv_co_pwrite_zeroes(dst, dst_offset, bytes, flags); } =20 + if (!src || !src->bs) { + return -ENOMEDIUM; + } + ret =3D bdrv_check_byte_request(src->bs, src_offset, bytes); + if (ret) { + return ret; + } + if (!src->bs->drv->bdrv_co_copy_range_from || !dst->bs->drv->bdrv_co_copy_range_to || src->bs->encrypted || dst->bs->encrypted) { return -ENOTSUP; } - bdrv_inc_in_flight(src_bs); - bdrv_inc_in_flight(dst_bs); - tracked_request_begin(&src_req, src_bs, src_offset, + bdrv_inc_in_flight(src->bs); + bdrv_inc_in_flight(dst->bs); + tracked_request_begin(&src_req, src->bs, src_offset, bytes, BDRV_TRACKED_READ); - tracked_request_begin(&dst_req, dst_bs, dst_offset, + tracked_request_begin(&dst_req, dst->bs, dst_offset, bytes, BDRV_TRACKED_WRITE); =20 wait_serialising_requests(&src_req); @@ -2944,8 +2945,8 @@ static int coroutine_fn bdrv_co_copy_range_internal(B= drvChild *src, } tracked_request_end(&src_req); tracked_request_end(&dst_req); - bdrv_dec_in_flight(src_bs); - bdrv_dec_in_flight(dst_bs); + bdrv_dec_in_flight(src->bs); + bdrv_dec_in_flight(dst->bs); return ret; } =20 --=20 2.17.1 From nobody Tue May 21 14:19:47 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; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1530585598600989.1011971625712; Mon, 2 Jul 2018 19:39:58 -0700 (PDT) Received: from localhost ([::1]:37462 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1faBET-0006Hz-TH for importer@patchew.org; Mon, 02 Jul 2018 22:39:57 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35828) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1faBCu-0005Nf-8m for qemu-devel@nongnu.org; Mon, 02 Jul 2018 22:38:21 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1faBCt-0008IV-Bz for qemu-devel@nongnu.org; Mon, 02 Jul 2018 22:38:20 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:42016 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1faBCq-0008E5-7b; Mon, 02 Jul 2018 22:38:16 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id C670540267A1; Tue, 3 Jul 2018 02:38:15 +0000 (UTC) Received: from lemon.usersys.redhat.com (ovpn-12-86.pek2.redhat.com [10.72.12.86]) by smtp.corp.redhat.com (Postfix) with ESMTP id 763E62156889; Tue, 3 Jul 2018 02:38:12 +0000 (UTC) From: Fam Zheng To: qemu-devel@nongnu.org Date: Tue, 3 Jul 2018 10:37:57 +0800 Message-Id: <20180703023758.14422-3-famz@redhat.com> In-Reply-To: <20180703023758.14422-1-famz@redhat.com> References: <20180703023758.14422-1-famz@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.6 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.6]); Tue, 03 Jul 2018 02:38:15 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.6]); Tue, 03 Jul 2018 02:38:15 +0000 (UTC) for IP:'10.11.54.6' DOMAIN:'int-mx06.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'famz@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [PATCH v4 2/3] block: Honour BDRV_REQ_NO_SERIALISING in copy range 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: Kevin Wolf , Fam Zheng , qemu-block@nongnu.org, Jeff Cody , Max Reitz , Stefan Hajnoczi 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 semantics is needed by drive-backup so implement it before using this API there. Reviewed-by: Stefan Hajnoczi Signed-off-by: Fam Zheng --- block/io.c | 6 ++++-- include/block/block.h | 5 +++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/block/io.c b/block/io.c index b8845708d7..1a2272fad3 100644 --- a/block/io.c +++ b/block/io.c @@ -2930,8 +2930,10 @@ static int coroutine_fn bdrv_co_copy_range_internal(= BdrvChild *src, tracked_request_begin(&dst_req, dst->bs, dst_offset, bytes, BDRV_TRACKED_WRITE); =20 - wait_serialising_requests(&src_req); - wait_serialising_requests(&dst_req); + if (!(flags & BDRV_REQ_NO_SERIALISING)) { + wait_serialising_requests(&src_req); + wait_serialising_requests(&dst_req); + } if (recurse_src) { ret =3D src->bs->drv->bdrv_co_copy_range_from(src->bs, src, src_offset, diff --git a/include/block/block.h b/include/block/block.h index 2ffc1c64c6..e5c7759a0c 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -659,13 +659,14 @@ void bdrv_unregister_buf(BlockDriverState *bs, void *= host); * @dst: Destination child to copy data to * @dst_offset: offset in @dst image to write data * @bytes: number of bytes to copy - * @flags: request flags. Must be one of: - * 0 - actually read data from src; + * @flags: request flags. Supported flags: * BDRV_REQ_ZERO_WRITE - treat the @src range as zero data and do = zero * write on @dst as if bdrv_co_pwrite_zeroes= is * called. Used to simplify caller code, or * during BlockDriver.bdrv_co_copy_range_fro= m() * recursion. + * BDRV_REQ_NO_SERIALISING - do not serialize with other overlappi= ng + * requests currently in flight. * * Returns: 0 if succeeded; negative error code if failed. **/ --=20 2.17.1 From nobody Tue May 21 14:19:47 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; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1530585714896479.28140161671763; Mon, 2 Jul 2018 19:41:54 -0700 (PDT) Received: from localhost ([::1]:37478 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1faBGM-0007vo-2L for importer@patchew.org; Mon, 02 Jul 2018 22:41:54 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:35880) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1faBD1-0005Sj-1L for qemu-devel@nongnu.org; Mon, 02 Jul 2018 22:38:28 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1faBCy-0008LS-8V for qemu-devel@nongnu.org; Mon, 02 Jul 2018 22:38:27 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:38744 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1faBCu-0008Jp-V2; Mon, 02 Jul 2018 22:38:21 -0400 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 7FE4E3466D; Tue, 3 Jul 2018 02:38:20 +0000 (UTC) Received: from lemon.usersys.redhat.com (ovpn-12-86.pek2.redhat.com [10.72.12.86]) by smtp.corp.redhat.com (Postfix) with ESMTP id 70BF32156889; Tue, 3 Jul 2018 02:38:16 +0000 (UTC) From: Fam Zheng To: qemu-devel@nongnu.org Date: Tue, 3 Jul 2018 10:37:58 +0800 Message-Id: <20180703023758.14422-4-famz@redhat.com> In-Reply-To: <20180703023758.14422-1-famz@redhat.com> References: <20180703023758.14422-1-famz@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.6 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.2]); Tue, 03 Jul 2018 02:38:20 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.2]); Tue, 03 Jul 2018 02:38:20 +0000 (UTC) for IP:'10.11.54.6' DOMAIN:'int-mx06.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'famz@redhat.com' RCPT:'' X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 66.187.233.73 Subject: [Qemu-devel] [PATCH v4 3/3] backup: Use copy offloading 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: Kevin Wolf , Fam Zheng , qemu-block@nongnu.org, Jeff Cody , Max Reitz , Stefan Hajnoczi 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" The implementation is similar to the 'qemu-img convert'. In the beginning of the job, offloaded copy is attempted. If it fails, further I/O will go through the existing bounce buffer code path. Then, as Kevin pointed out, both this and qemu-img convert can benefit from a local check if one request fails because of, for example, the offset is beyond EOF, but another may well be accepted by the protocol layer. This will be implemented separately. Reviewed-by: Stefan Hajnoczi Signed-off-by: Fam Zheng --- block/backup.c | 150 ++++++++++++++++++++++++++++++++------------- block/trace-events | 1 + 2 files changed, 110 insertions(+), 41 deletions(-) diff --git a/block/backup.c b/block/backup.c index d18be40caf..81895ddbe2 100644 --- a/block/backup.c +++ b/block/backup.c @@ -45,6 +45,8 @@ typedef struct BackupBlockJob { QLIST_HEAD(, CowRequest) inflight_reqs; =20 HBitmap *copy_bitmap; + bool use_copy_range; + int64_t copy_range_size; } BackupBlockJob; =20 static const BlockJobDriver backup_job_driver; @@ -86,19 +88,101 @@ static void cow_request_end(CowRequest *req) qemu_co_queue_restart_all(&req->wait_queue); } =20 +/* Copy range to target with a bounce buffer and return the bytes copied. = If + * error occured, return a negative error number */ +static int coroutine_fn backup_cow_with_bounce_buffer(BackupBlockJob *job, + int64_t start, + int64_t end, + bool is_write_notifi= er, + bool *error_is_read, + void **bounce_buffer) +{ + int ret; + struct iovec iov; + QEMUIOVector qiov; + BlockBackend *blk =3D job->common.blk; + int nbytes; + + hbitmap_reset(job->copy_bitmap, start / job->cluster_size, 1); + nbytes =3D MIN(job->cluster_size, job->len - start); + if (!*bounce_buffer) { + *bounce_buffer =3D blk_blockalign(blk, job->cluster_size); + } + iov.iov_base =3D *bounce_buffer; + iov.iov_len =3D nbytes; + qemu_iovec_init_external(&qiov, &iov, 1); + + ret =3D blk_co_preadv(blk, start, qiov.size, &qiov, + is_write_notifier ? BDRV_REQ_NO_SERIALISING : 0); + if (ret < 0) { + trace_backup_do_cow_read_fail(job, start, ret); + if (error_is_read) { + *error_is_read =3D true; + } + goto fail; + } + + if (qemu_iovec_is_zero(&qiov)) { + ret =3D blk_co_pwrite_zeroes(job->target, start, + qiov.size, BDRV_REQ_MAY_UNMAP); + } else { + ret =3D blk_co_pwritev(job->target, start, + qiov.size, &qiov, + job->compress ? BDRV_REQ_WRITE_COMPRESSED : 0= ); + } + if (ret < 0) { + trace_backup_do_cow_write_fail(job, start, ret); + if (error_is_read) { + *error_is_read =3D false; + } + goto fail; + } + + return nbytes; +fail: + hbitmap_set(job->copy_bitmap, start / job->cluster_size, 1); + return ret; + +} + +/* Copy range to target and return the bytes copied. If error occured, ret= urn a + * negative error number. */ +static int coroutine_fn backup_cow_with_offload(BackupBlockJob *job, + int64_t start, + int64_t end, + bool is_write_notifier) +{ + int ret; + int nr_clusters; + BlockBackend *blk =3D job->common.blk; + int nbytes; + + assert(QEMU_IS_ALIGNED(job->copy_range_size, job->cluster_size)); + nbytes =3D MIN(job->copy_range_size, end - start); + nr_clusters =3D DIV_ROUND_UP(nbytes, job->cluster_size); + hbitmap_reset(job->copy_bitmap, start / job->cluster_size, + nr_clusters); + ret =3D blk_co_copy_range(blk, start, job->target, start, nbytes, + is_write_notifier ? BDRV_REQ_NO_SERIALISING : = 0); + if (ret < 0) { + trace_backup_do_cow_copy_range_fail(job, start, ret); + hbitmap_set(job->copy_bitmap, start / job->cluster_size, + nr_clusters); + return ret; + } + + return nbytes; +} + static int coroutine_fn backup_do_cow(BackupBlockJob *job, int64_t offset, uint64_t bytes, bool *error_is_read, bool is_write_notifier) { - BlockBackend *blk =3D job->common.blk; CowRequest cow_request; - struct iovec iov; - QEMUIOVector bounce_qiov; - void *bounce_buffer =3D NULL; int ret =3D 0; int64_t start, end; /* bytes */ - int n; /* bytes */ + void *bounce_buffer =3D NULL; =20 qemu_co_rwlock_rdlock(&job->flush_rwlock); =20 @@ -110,60 +194,38 @@ static int coroutine_fn backup_do_cow(BackupBlockJob = *job, wait_for_overlapping_requests(job, start, end); cow_request_begin(&cow_request, job, start, end); =20 - for (; start < end; start +=3D job->cluster_size) { + while (start < end) { if (!hbitmap_get(job->copy_bitmap, start / job->cluster_size)) { trace_backup_do_cow_skip(job, start); + start +=3D job->cluster_size; continue; /* already copied */ } - hbitmap_reset(job->copy_bitmap, start / job->cluster_size, 1); =20 trace_backup_do_cow_process(job, start); =20 - n =3D MIN(job->cluster_size, job->len - start); - - if (!bounce_buffer) { - bounce_buffer =3D blk_blockalign(blk, job->cluster_size); - } - iov.iov_base =3D bounce_buffer; - iov.iov_len =3D n; - qemu_iovec_init_external(&bounce_qiov, &iov, 1); - - ret =3D blk_co_preadv(blk, start, bounce_qiov.size, &bounce_qiov, - is_write_notifier ? BDRV_REQ_NO_SERIALISING : = 0); - if (ret < 0) { - trace_backup_do_cow_read_fail(job, start, ret); - if (error_is_read) { - *error_is_read =3D true; + if (job->use_copy_range) { + ret =3D backup_cow_with_offload(job, start, end, is_write_noti= fier); + if (ret < 0) { + job->use_copy_range =3D false; } - hbitmap_set(job->copy_bitmap, start / job->cluster_size, 1); - goto out; } - - if (buffer_is_zero(iov.iov_base, iov.iov_len)) { - ret =3D blk_co_pwrite_zeroes(job->target, start, - bounce_qiov.size, BDRV_REQ_MAY_UNMA= P); - } else { - ret =3D blk_co_pwritev(job->target, start, - bounce_qiov.size, &bounce_qiov, - job->compress ? BDRV_REQ_WRITE_COMPRESSED= : 0); + if (!job->use_copy_range) { + ret =3D backup_cow_with_bounce_buffer(job, start, end, is_writ= e_notifier, + error_is_read, &bounce_buf= fer); } if (ret < 0) { - trace_backup_do_cow_write_fail(job, start, ret); - if (error_is_read) { - *error_is_read =3D false; - } - hbitmap_set(job->copy_bitmap, start / job->cluster_size, 1); - goto out; + break; } =20 /* Publish progress, guest I/O counts as progress too. Note that = the * offset field is an opaque progress value, it is not a disk offs= et. */ - job->bytes_read +=3D n; - job_progress_update(&job->common.job, n); + start +=3D ret; + job->bytes_read +=3D ret; + job_progress_update(&job->common.job, ret); + ret =3D 0; } =20 -out: if (bounce_buffer) { qemu_vfree(bounce_buffer); } @@ -665,6 +727,12 @@ BlockJob *backup_job_create(const char *job_id, BlockD= riverState *bs, } else { job->cluster_size =3D MAX(BACKUP_CLUSTER_SIZE_DEFAULT, bdi.cluster= _size); } + job->use_copy_range =3D true; + job->copy_range_size =3D MIN_NON_ZERO(blk_get_max_transfer(job->common= .blk), + blk_get_max_transfer(job->target)); + job->copy_range_size =3D MAX(job->cluster_size, + QEMU_ALIGN_UP(job->copy_range_size, + job->cluster_size)); =20 /* Required permissions are already taken with target's blk_new() */ block_job_add_bdrv(&job->common, "target", target, 0, BLK_PERM_ALL, diff --git a/block/trace-events b/block/trace-events index 2d59b53fd3..c35287b48a 100644 --- a/block/trace-events +++ b/block/trace-events @@ -42,6 +42,7 @@ backup_do_cow_skip(void *job, int64_t start) "job %p star= t %"PRId64 backup_do_cow_process(void *job, int64_t start) "job %p start %"PRId64 backup_do_cow_read_fail(void *job, int64_t start, int ret) "job %p start %= "PRId64" ret %d" backup_do_cow_write_fail(void *job, int64_t start, int ret) "job %p start = %"PRId64" ret %d" +backup_do_cow_copy_range_fail(void *job, int64_t start, int ret) "job %p s= tart %"PRId64" ret %d" =20 # blockdev.c qmp_block_job_cancel(void *job) "job %p" --=20 2.17.1