From nobody Wed Apr 16 08:02:47 2025 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 1528728458178571.9500788973164; Mon, 11 Jun 2018 07:47:38 -0700 (PDT) Received: from localhost ([::1]:49284 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fSO6Z-0004NI-Em for importer@patchew.org; Mon, 11 Jun 2018 10:47:35 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53276) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1fSNmb-0004lp-Lw for qemu-devel@nongnu.org; Mon, 11 Jun 2018 10:27:01 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1fSNma-0001ui-C6 for qemu-devel@nongnu.org; Mon, 11 Jun 2018 10:26:57 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:35538 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 1fSNmX-0001qa-9V; Mon, 11 Jun 2018 10:26:53 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id DFAD9BB409; Mon, 11 Jun 2018 14:26:52 +0000 (UTC) Received: from localhost (unknown [10.40.205.155]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 8C081202698A; Mon, 11 Jun 2018 14:26:52 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Mon, 11 Jun 2018 16:26:02 +0200 Message-Id: <20180611142611.6609-21-mreitz@redhat.com> In-Reply-To: <20180611142611.6609-1-mreitz@redhat.com> References: <20180611142611.6609-1-mreitz@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.4 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.1]); Mon, 11 Jun 2018 14:26:52 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.1]); Mon, 11 Jun 2018 14:26:52 +0000 (UTC) for IP:'10.11.54.4' DOMAIN:'int-mx04.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'mreitz@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] [PULL 20/29] qemu-img: Special post-backing convert handling 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 , Peter Maydell , qemu-devel@nongnu.org, Max Reitz 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" Currently, qemu-img convert writes zeroes when it reads zeroes. Sometimes it does not because the target is initialized to zeroes anyway, so we do not need to overwrite (and thus potentially allocate) it. This is never the case for targets with backing files, though. But even they may have an area that is initialized to zeroes, and that is the area past the end of the backing file (if that is shorter than the overlay). So if the target format's unallocated blocks are zero and there is a gap between the target's backing file's end and the target's end, we do not have to explicitly write zeroes there. Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=3D1527898 Signed-off-by: Max Reitz Message-id: 20180501165750.19242-2-mreitz@redhat.com Reviewed-by: Eric Blake Signed-off-by: Max Reitz --- qemu-img.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/qemu-img.c b/qemu-img.c index ebe1b866da..ae4acb655b 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -1556,7 +1556,9 @@ typedef struct ImgConvertState { BlockBackend *target; bool has_zero_init; bool compressed; + bool unallocated_blocks_are_zero; bool target_has_backing; + int64_t target_backing_sectors; /* negative if unknown */ bool wr_in_order; bool copy_range; int min_sparse; @@ -1586,12 +1588,23 @@ static int convert_iteration_sectors(ImgConvertStat= e *s, int64_t sector_num) { int64_t src_cur_offset; int ret, n, src_cur; + bool post_backing_zero =3D false; =20 convert_select_part(s, sector_num, &src_cur, &src_cur_offset); =20 assert(s->total_sectors > sector_num); n =3D MIN(s->total_sectors - sector_num, BDRV_REQUEST_MAX_SECTORS); =20 + if (s->target_backing_sectors >=3D 0) { + if (sector_num >=3D s->target_backing_sectors) { + post_backing_zero =3D s->unallocated_blocks_are_zero; + } else if (sector_num + n > s->target_backing_sectors) { + /* Split requests around target_backing_sectors (because + * starting from there, zeros are handled differently) */ + n =3D s->target_backing_sectors - sector_num; + } + } + if (s->sector_next_status <=3D sector_num) { int64_t count =3D n * BDRV_SECTOR_SIZE; =20 @@ -1613,7 +1626,7 @@ static int convert_iteration_sectors(ImgConvertState = *s, int64_t sector_num) n =3D DIV_ROUND_UP(count, BDRV_SECTOR_SIZE); =20 if (ret & BDRV_BLOCK_ZERO) { - s->status =3D BLK_ZERO; + s->status =3D post_backing_zero ? BLK_BACKING_FILE : BLK_ZERO; } else if (ret & BDRV_BLOCK_DATA) { s->status =3D BLK_DATA; } else { @@ -2379,6 +2392,16 @@ static int img_convert(int argc, char **argv) } } =20 + if (s.target_has_backing) { + /* Errors are treated as "backing length unknown" (which means + * s.target_backing_sectors has to be negative, which it will + * be automatically). The backing file length is used only + * for optimizations, so such a case is not fatal. */ + s.target_backing_sectors =3D bdrv_nb_sectors(out_bs->backing->bs); + } else { + s.target_backing_sectors =3D -1; + } + ret =3D bdrv_get_info(out_bs, &bdi); if (ret < 0) { if (s.compressed) { @@ -2388,6 +2411,7 @@ static int img_convert(int argc, char **argv) } else { s.compressed =3D s.compressed || bdi.needs_compressed_writes; s.cluster_sectors =3D bdi.cluster_size / BDRV_SECTOR_SIZE; + s.unallocated_blocks_are_zero =3D bdi.unallocated_blocks_are_zero; } =20 ret =3D convert_do_copy(&s); --=20 2.17.1