From patchwork Fri Nov 22 14:48:30 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Lieven X-Patchwork-Id: 293476 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 3B6822C00F9 for ; Sat, 23 Nov 2013 01:49:19 +1100 (EST) Received: from localhost ([::1]:39250 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Vjs2m-0002Gu-H3 for incoming@patchwork.ozlabs.org; Fri, 22 Nov 2013 09:49:16 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37092) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Vjs2Q-00028O-Vh for qemu-devel@nongnu.org; Fri, 22 Nov 2013 09:49:01 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Vjs2J-0006Va-2P for qemu-devel@nongnu.org; Fri, 22 Nov 2013 09:48:54 -0500 Received: from mx.ipv6.kamp.de ([2a02:248:0:51::16]:40489 helo=mx01.kamp.de) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Vjs2I-0006VV-NW for qemu-devel@nongnu.org; Fri, 22 Nov 2013 09:48:46 -0500 Received: (qmail 29537 invoked by uid 89); 22 Nov 2013 14:48:44 -0000 Received: from [82.141.1.145] by client-16-kamp (envelope-from , uid 89) with qmail-scanner-2010/03/19-MF (clamdscan: 0.98/18146. hbedv: 8.2.12.150/7.11.115.24. spamassassin: 3.3.1. Clear:RC:1(82.141.1.145):SA:0(-1.2/4.0):. Processed in 1.277301 secs); 22 Nov 2013 14:48:44 -0000 Received: from ns.kamp-intra.net (HELO dns.kamp-intra.net) ([82.141.1.145]) by mx01.kamp.de with SMTP; 22 Nov 2013 14:48:43 -0000 X-GL_Whitelist: yes Received: from lieven-pc.kamp-intra.net (lieven-pc.kamp-intra.net [172.21.12.60]) by dns.kamp-intra.net (Postfix) with ESMTP id 46E7E20688; Fri, 22 Nov 2013 15:48:13 +0100 (CET) Received: by lieven-pc.kamp-intra.net (Postfix, from userid 1000) id 606505FD2D; Fri, 22 Nov 2013 15:48:31 +0100 (CET) From: Peter Lieven To: qemu-devel@nongnu.org Date: Fri, 22 Nov 2013 15:48:30 +0100 Message-Id: <1385131710-8978-1-git-send-email-pl@kamp.de> X-Mailer: git-send-email 1.7.9.5 X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2a02:248:0:51::16 Cc: kwolf@redhat.com, pbonzini@redhat.com, Peter Lieven , stefanha@redhat.com Subject: [Qemu-devel] [RFC][PATCH] qemu-img: add support for skipping zeroes in input during convert X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Signed-off-by: Peter Lieven --- qemu-img.c | 52 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/qemu-img.c b/qemu-img.c index b6b5644..808f8f8 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -1121,8 +1121,9 @@ out3: static int img_convert(int argc, char **argv) { - int c, ret = 0, n, n1, bs_n, bs_i, compress, cluster_size, + int c, n, n1, bs_n, bs_i, compress, cluster_size, cluster_sectors, skip_create; + int64_t ret = 0; int progress = 0, flags; const char *fmt, *out_fmt, *cache, *out_baseimg, *out_filename; BlockDriver *drv, *proto_drv; @@ -1479,11 +1480,6 @@ static int img_convert(int argc, char **argv) if (nb_sectors <= 0) { break; } - if (nb_sectors >= (IO_BUF_SIZE / 512)) { - n = (IO_BUF_SIZE / 512); - } else { - n = nb_sectors; - } while (sector_num - bs_offset >= bs_sectors) { bs_i ++; @@ -1495,34 +1491,46 @@ static int img_convert(int argc, char **argv) sector_num, bs_i, bs_offset, bs_sectors); */ } - if (n > bs_offset + bs_sectors - sector_num) { - n = bs_offset + bs_sectors - sector_num; - } - - /* If the output image is being created as a copy on write image, - assume that sectors which are unallocated in the input image - are present in both the output's and input's base images (no - need to copy them). */ - if (out_baseimg) { - ret = bdrv_is_allocated(bs[bs_i], sector_num - bs_offset, - n, &n1); + if (out_baseimg || has_zero_init) { + n = nb_sectors > INT_MAX ? INT_MAX : nb_sectors; + ret = bdrv_get_block_status(bs[bs_i], sector_num - bs_offset, + n, &n1); if (ret < 0) { - error_report("error while reading metadata for sector " - "%" PRId64 ": %s", + error_report("error while reading block status of sector %" PRId64 ": %s", sector_num - bs_offset, strerror(-ret)); goto out; } - if (!ret) { + /* If the output image is zero initialized, we are not working + * on a shared base and the input is zero we can skip the next + * n1 bytes */ + if (!out_baseimg && has_zero_init && ret & BDRV_BLOCK_ZERO) { + sector_num += n1; + continue; + } + /* If the output image is being created as a copy on write image, + assume that sectors which are unallocated in the input image + are present in both the output's and input's base images (no + need to copy them). */ + if (out_baseimg && !(ret & BDRV_BLOCK_DATA)) { sector_num += n1; continue; } /* The next 'n1' sectors are allocated in the input image. Copy only those as they may be followed by unallocated sectors. */ - n = n1; + nb_sectors = n1; + } + + if (nb_sectors >= (IO_BUF_SIZE / 512)) { + n = (IO_BUF_SIZE / 512); } else { - n1 = n; + n = nb_sectors; + } + + if (n > bs_offset + bs_sectors - sector_num) { + n = bs_offset + bs_sectors - sector_num; } + n1 = n; ret = bdrv_read(bs[bs_i], sector_num - bs_offset, buf, n); if (ret < 0) { error_report("error while reading sector %" PRId64 ": %s",