From patchwork Tue Apr 11 01:17:06 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Blake X-Patchwork-Id: 9674431 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id C9A3E6020C for ; Tue, 11 Apr 2017 01:19:08 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B8C51283E1 for ; Tue, 11 Apr 2017 01:19:08 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id ADAF1284DD; Tue, 11 Apr 2017 01:19:08 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 43EAE283E1 for ; Tue, 11 Apr 2017 01:19:08 +0000 (UTC) Received: from localhost ([::1]:36679 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cxkSZ-0005Pa-9g for patchwork-qemu-devel@patchwork.kernel.org; Mon, 10 Apr 2017 21:19:07 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:46412) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1cxkR6-0005H9-2t for qemu-devel@nongnu.org; Mon, 10 Apr 2017 21:17:39 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1cxkR4-0005q2-FS for qemu-devel@nongnu.org; Mon, 10 Apr 2017 21:17:36 -0400 Received: from mx1.redhat.com ([209.132.183.28]:36998) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1cxkQx-0005mQ-M9; Mon, 10 Apr 2017 21:17:27 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id A7C8C80F90; Tue, 11 Apr 2017 01:17:26 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com A7C8C80F90 Authentication-Results: ext-mx03.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx03.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=eblake@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com A7C8C80F90 Received: from red.redhat.com (ovpn-122-58.rdu2.redhat.com [10.10.122.58]) by smtp.corp.redhat.com (Postfix) with ESMTP id F104881868; Tue, 11 Apr 2017 01:17:25 +0000 (UTC) From: Eric Blake To: qemu-devel@nongnu.org Date: Mon, 10 Apr 2017 20:17:06 -0500 Message-Id: <20170411011718.9152-2-eblake@redhat.com> In-Reply-To: <20170411011718.9152-1-eblake@redhat.com> References: <20170411011718.9152-1-eblake@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Tue, 11 Apr 2017 01:17:26 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PATCH v9 01/13] qcow2: Unallocate unmapped zero clusters if no backing file 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: kwolf@redhat.com, qemu-block@nongnu.org, mreitz@redhat.com Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" X-Virus-Scanned: ClamAV using ClamSMTP 'qemu-img map' already coalesces information about unallocated clusters (those with status 0) and pure zero clusters (those with status BDRV_BLOCK_ZERO and no offset). Furthermore, all qcow2 images with no backing file already report all unallocated clusters (in the preallocation sense of clusters with no offset) as BDRV_BLOCK_ZERO, regardless of whether the QCOW_OFLAG_ZERO was set in that L2 entry (QCOW_OFLAG_ZERO also implies a return of BDRV_BLOCK_ALLOCATED, but we intentionally do not expose that bit to external users), thanks to generic block layer code in bdrv_co_get_block_status(). So, for an image with no backing file, having bdrv_pwrite_zeroes mark clusters as unallocated (defer to backing file) rather than reads-as-zero (regardless of backing file) makes no difference to normal behavior, but may potentially allow for fewer writes to the L2 table of a freshly-created image where the L2 table is initially written to all-zeroes (although I don't actually know if we skip an L2 update and flush when re-writing the same contents as already present). Furthermore, this matches the behavior of discard_single_l2(), in favoring an unallocated cluster over a zero cluster when full discard is requested. Meanwhile, version 2 qcow2 files (compat=0.10) lack support for an explicit zero cluster. This minor tweak therefore allows us to turn write zeroes with unmap into an actual unallocation on those files, where they used to return -ENOTSUP and cause an allocation due to the fallback to explicitly written zeroes. Note that technically, we _could_ write a cluster as unallocated rather than zero if a backing file exists but the backing file also reads as zero, but that's more expensive to determine, so this optimization is limited to qcow2 without a backing file. Also note that this patch unmaps a compressed cluster when there is no backing file, even when BDRV_REQ_MAY_UNMAP was not set, but it is unlikely to have compressed clusters in a fully preallocated image (the point of compression is to reduce space requirements), so the side effect of unmapping a cluster in that case is not deemed to be a problem. Finally, note that this change can create a subtle difference if a backing file is later added with 'qemu-img rebase -u'; pre-patch, a v3 file (compat=1.1) will have a cluster that still reads as 0 (the cluster is not allocated in the sense of preallocation, but is provided from the layer), while post-patch the cluster will now defer to the backing file - but it's already an unsupported action if you are modifying guest-visible data by messing with backing chains ;) Signed-off-by: Eric Blake --- v9: new patch --- block/qcow2-cluster.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c index 100398c..12f44b2 100644 --- a/block/qcow2-cluster.c +++ b/block/qcow2-cluster.c @@ -1579,7 +1579,8 @@ static int zero_single_l2(BlockDriverState *bs, uint64_t offset, /* Update L2 entries */ qcow2_cache_entry_mark_dirty(bs, s->l2_table_cache, l2_table); if (old_offset & QCOW_OFLAG_COMPRESSED || flags & BDRV_REQ_MAY_UNMAP) { - l2_table[l2_index + i] = cpu_to_be64(QCOW_OFLAG_ZERO); + l2_table[l2_index + i] = bs->backing + ? cpu_to_be64(QCOW_OFLAG_ZERO) : 0; qcow2_free_any_clusters(bs, old_offset, 1, QCOW2_DISCARD_REQUEST); } else { l2_table[l2_index + i] |= cpu_to_be64(QCOW_OFLAG_ZERO); @@ -1598,8 +1599,11 @@ int qcow2_zero_clusters(BlockDriverState *bs, uint64_t offset, int nb_sectors, uint64_t nb_clusters; int ret; - /* The zero flag is only supported by version 3 and newer */ - if (s->qcow_version < 3) { + /* The zero flag is only supported by version 3 and newer; we + * require the use of that flag if there is a backing file or if + * we are not allowed to unmap. */ + if (s->qcow_version < 3 && + (bs->backing || !(flags & BDRV_REQ_MAY_UNMAP))) { return -ENOTSUP; }