From patchwork Sun Jun 28 11:02:10 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alberto Garcia X-Patchwork-Id: 279179 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 066A7C433E0 for ; Sun, 28 Jun 2020 11:14:32 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id B616D20B80 for ; Sun, 28 Jun 2020 11:14:31 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=igalia.com header.i=@igalia.com header.b="nLhy2Lf/" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org B616D20B80 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=igalia.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:56038 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jpVGZ-0000N6-0i for qemu-devel@archiver.kernel.org; Sun, 28 Jun 2020 07:14:31 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:48630) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jpV6S-0007X7-UV; Sun, 28 Jun 2020 07:04:05 -0400 Received: from fanzine.igalia.com ([178.60.130.6]:42236) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1jpV6K-0000WW-7H; Sun, 28 Jun 2020 07:04:04 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From; bh=rG3HtHSB2vY898CvBDGVh5MfaibllWEuf52ko3hA7Is=; b=nLhy2Lf/XGZnHXO0OXXP0BjWHlrJVG3Ib2sUzD1B17hPmPPpVVuXmR2LPTPDpfS1r9PiNSLGYwXg5acudtf9RJaC4Lk9oy46Y0DvSjbCkVw8MtPglVc8pe92t5FQHvFWMGmYuCwZ9/73dvRIX97BhVl9+OUtsAji88KI6H5zs5ZZ4XLx3qANFbnmoL3mb/Bgi/590f/sVqw3dTZrwYmH3oOPWNLY+NCSRzPxT0MRfgBMvGSTp8uEDnRz0giqBdL6fAUO+j1OFuPlOVzsUB/0EI+1+3RIyNBEIZah3I79CDR76GrUoDzFuS8F73ZCSxtIH3AM1AP/7YM6debfCTiBpw==; Received: from 26.red-79-158-236.dynamicip.rima-tde.net ([79.158.236.26] helo=perseus.local) by fanzine.igalia.com with esmtpsa (Cipher TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim) id 1jpV5X-0002gP-05; Sun, 28 Jun 2020 13:03:07 +0200 Received: from berto by perseus.local with local (Exim 4.92) (envelope-from ) id 1jpV5H-000389-Em; Sun, 28 Jun 2020 13:02:51 +0200 From: Alberto Garcia To: qemu-devel@nongnu.org Subject: [PATCH v9 01/34] qcow2: Make Qcow2AioTask store the full host offset Date: Sun, 28 Jun 2020 13:02:10 +0200 Message-Id: <02c9a7133a220ab2279a8cb360bf3488e444be1e.1593342067.git.berto@igalia.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 Received-SPF: pass client-ip=178.60.130.6; envelope-from=berto@igalia.com; helo=fanzine.igalia.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/06/28 07:03:08 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x (no timestamps) [generic] [fuzzy] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , Alberto Garcia , qemu-block@nongnu.org, Derek Su , Max Reitz Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" The file_cluster_offset field of Qcow2AioTask stores a cluster-aligned host offset. In practice this is not very useful because all users(*) of this structure need the final host offset into the cluster, which they calculate using host_offset = file_cluster_offset + offset_into_cluster(s, offset) There is no reason why Qcow2AioTask cannot store host_offset directly and that is what this patch does. (*) compressed clusters are the exception: in this case what file_cluster_offset was storing was the full compressed cluster descriptor (offset + size). This does not change with this patch but it is documented now. Signed-off-by: Alberto Garcia Reviewed-by: Eric Blake Reviewed-by: Max Reitz Reviewed-by: Vladimir Sementsov-Ogievskiy --- block/qcow2.c | 69 ++++++++++++++++++++++------------------------ block/trace-events | 2 +- 2 files changed, 34 insertions(+), 37 deletions(-) diff --git a/block/qcow2.c b/block/qcow2.c index e20590c3b7..d792137af6 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -74,7 +74,7 @@ typedef struct { static int coroutine_fn qcow2_co_preadv_compressed(BlockDriverState *bs, - uint64_t file_cluster_offset, + uint64_t cluster_descriptor, uint64_t offset, uint64_t bytes, QEMUIOVector *qiov, @@ -2103,7 +2103,7 @@ out: static coroutine_fn int qcow2_co_preadv_encrypted(BlockDriverState *bs, - uint64_t file_cluster_offset, + uint64_t host_offset, uint64_t offset, uint64_t bytes, QEMUIOVector *qiov, @@ -2130,16 +2130,12 @@ qcow2_co_preadv_encrypted(BlockDriverState *bs, } BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO); - ret = bdrv_co_pread(s->data_file, - file_cluster_offset + offset_into_cluster(s, offset), - bytes, buf, 0); + ret = bdrv_co_pread(s->data_file, host_offset, bytes, buf, 0); if (ret < 0) { goto fail; } - if (qcow2_co_decrypt(bs, - file_cluster_offset + offset_into_cluster(s, offset), - offset, buf, bytes) < 0) + if (qcow2_co_decrypt(bs, host_offset, offset, buf, bytes) < 0) { ret = -EIO; goto fail; @@ -2157,7 +2153,7 @@ typedef struct Qcow2AioTask { BlockDriverState *bs; QCow2ClusterType cluster_type; /* only for read */ - uint64_t file_cluster_offset; + uint64_t host_offset; /* or full descriptor in compressed clusters */ uint64_t offset; uint64_t bytes; QEMUIOVector *qiov; @@ -2170,7 +2166,7 @@ static coroutine_fn int qcow2_add_task(BlockDriverState *bs, AioTaskPool *pool, AioTaskFunc func, QCow2ClusterType cluster_type, - uint64_t file_cluster_offset, + uint64_t host_offset, uint64_t offset, uint64_t bytes, QEMUIOVector *qiov, @@ -2185,7 +2181,7 @@ static coroutine_fn int qcow2_add_task(BlockDriverState *bs, .bs = bs, .cluster_type = cluster_type, .qiov = qiov, - .file_cluster_offset = file_cluster_offset, + .host_offset = host_offset, .offset = offset, .bytes = bytes, .qiov_offset = qiov_offset, @@ -2194,7 +2190,7 @@ static coroutine_fn int qcow2_add_task(BlockDriverState *bs, trace_qcow2_add_task(qemu_coroutine_self(), bs, pool, func == qcow2_co_preadv_task_entry ? "read" : "write", - cluster_type, file_cluster_offset, offset, bytes, + cluster_type, host_offset, offset, bytes, qiov, qiov_offset); if (!pool) { @@ -2208,13 +2204,12 @@ static coroutine_fn int qcow2_add_task(BlockDriverState *bs, static coroutine_fn int qcow2_co_preadv_task(BlockDriverState *bs, QCow2ClusterType cluster_type, - uint64_t file_cluster_offset, + uint64_t host_offset, uint64_t offset, uint64_t bytes, QEMUIOVector *qiov, size_t qiov_offset) { BDRVQcow2State *s = bs->opaque; - int offset_in_cluster = offset_into_cluster(s, offset); switch (cluster_type) { case QCOW2_CLUSTER_ZERO_PLAIN: @@ -2230,19 +2225,17 @@ static coroutine_fn int qcow2_co_preadv_task(BlockDriverState *bs, qiov, qiov_offset, 0); case QCOW2_CLUSTER_COMPRESSED: - return qcow2_co_preadv_compressed(bs, file_cluster_offset, + return qcow2_co_preadv_compressed(bs, host_offset, offset, bytes, qiov, qiov_offset); case QCOW2_CLUSTER_NORMAL: - assert(offset_into_cluster(s, file_cluster_offset) == 0); if (bs->encrypted) { - return qcow2_co_preadv_encrypted(bs, file_cluster_offset, + return qcow2_co_preadv_encrypted(bs, host_offset, offset, bytes, qiov, qiov_offset); } BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO); - return bdrv_co_preadv_part(s->data_file, - file_cluster_offset + offset_in_cluster, + return bdrv_co_preadv_part(s->data_file, host_offset, bytes, qiov, qiov_offset, 0); default: @@ -2258,7 +2251,7 @@ static coroutine_fn int qcow2_co_preadv_task_entry(AioTask *task) assert(!t->l2meta); - return qcow2_co_preadv_task(t->bs, t->cluster_type, t->file_cluster_offset, + return qcow2_co_preadv_task(t->bs, t->cluster_type, t->host_offset, t->offset, t->bytes, t->qiov, t->qiov_offset); } @@ -2294,11 +2287,20 @@ static coroutine_fn int qcow2_co_preadv_part(BlockDriverState *bs, { qemu_iovec_memset(qiov, qiov_offset, 0, cur_bytes); } else { + /* + * For compressed clusters the variable cluster_offset + * does not actually store the offset but the full + * descriptor. We need to leave it unchanged because + * that's what qcow2_co_preadv_compressed() expects. + */ + uint64_t host_offset = (ret == QCOW2_CLUSTER_COMPRESSED) ? + cluster_offset : + cluster_offset + offset_into_cluster(s, offset); if (!aio && cur_bytes != bytes) { aio = aio_task_pool_new(QCOW2_MAX_WORKERS); } ret = qcow2_add_task(bs, aio, qcow2_co_preadv_task_entry, ret, - cluster_offset, offset, cur_bytes, + host_offset, offset, cur_bytes, qiov, qiov_offset, NULL); if (ret < 0) { goto out; @@ -2449,7 +2451,7 @@ static int handle_alloc_space(BlockDriverState *bs, QCowL2Meta *l2meta) * not use it somehow after qcow2_co_pwritev_task() call */ static coroutine_fn int qcow2_co_pwritev_task(BlockDriverState *bs, - uint64_t file_cluster_offset, + uint64_t host_offset, uint64_t offset, uint64_t bytes, QEMUIOVector *qiov, uint64_t qiov_offset, @@ -2458,7 +2460,6 @@ static coroutine_fn int qcow2_co_pwritev_task(BlockDriverState *bs, int ret; BDRVQcow2State *s = bs->opaque; void *crypt_buf = NULL; - int offset_in_cluster = offset_into_cluster(s, offset); QEMUIOVector encrypted_qiov; if (bs->encrypted) { @@ -2471,9 +2472,7 @@ static coroutine_fn int qcow2_co_pwritev_task(BlockDriverState *bs, } qemu_iovec_to_buf(qiov, qiov_offset, crypt_buf, bytes); - if (qcow2_co_encrypt(bs, file_cluster_offset + offset_in_cluster, - offset, crypt_buf, bytes) < 0) - { + if (qcow2_co_encrypt(bs, host_offset, offset, crypt_buf, bytes) < 0) { ret = -EIO; goto out_unlocked; } @@ -2497,10 +2496,8 @@ static coroutine_fn int qcow2_co_pwritev_task(BlockDriverState *bs, */ if (!merge_cow(offset, bytes, qiov, qiov_offset, l2meta)) { BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO); - trace_qcow2_writev_data(qemu_coroutine_self(), - file_cluster_offset + offset_in_cluster); - ret = bdrv_co_pwritev_part(s->data_file, - file_cluster_offset + offset_in_cluster, + trace_qcow2_writev_data(qemu_coroutine_self(), host_offset); + ret = bdrv_co_pwritev_part(s->data_file, host_offset, bytes, qiov, qiov_offset, 0); if (ret < 0) { goto out_unlocked; @@ -2530,7 +2527,7 @@ static coroutine_fn int qcow2_co_pwritev_task_entry(AioTask *task) assert(!t->cluster_type); - return qcow2_co_pwritev_task(t->bs, t->file_cluster_offset, + return qcow2_co_pwritev_task(t->bs, t->host_offset, t->offset, t->bytes, t->qiov, t->qiov_offset, t->l2meta); } @@ -2585,8 +2582,8 @@ static coroutine_fn int qcow2_co_pwritev_part( aio = aio_task_pool_new(QCOW2_MAX_WORKERS); } ret = qcow2_add_task(bs, aio, qcow2_co_pwritev_task_entry, 0, - cluster_offset, offset, cur_bytes, - qiov, qiov_offset, l2meta); + cluster_offset + offset_in_cluster, offset, + cur_bytes, qiov, qiov_offset, l2meta); l2meta = NULL; /* l2meta is consumed by qcow2_co_pwritev_task() */ if (ret < 0) { goto fail_nometa; @@ -4569,7 +4566,7 @@ qcow2_co_pwritev_compressed_part(BlockDriverState *bs, static int coroutine_fn qcow2_co_preadv_compressed(BlockDriverState *bs, - uint64_t file_cluster_offset, + uint64_t cluster_descriptor, uint64_t offset, uint64_t bytes, QEMUIOVector *qiov, @@ -4581,8 +4578,8 @@ qcow2_co_preadv_compressed(BlockDriverState *bs, uint8_t *buf, *out_buf; int offset_in_cluster = offset_into_cluster(s, offset); - coffset = file_cluster_offset & s->cluster_offset_mask; - nb_csectors = ((file_cluster_offset >> s->csize_shift) & s->csize_mask) + 1; + coffset = cluster_descriptor & s->cluster_offset_mask; + nb_csectors = ((cluster_descriptor >> s->csize_shift) & s->csize_mask) + 1; csize = nb_csectors * QCOW2_COMPRESSED_SECTOR_SIZE - (coffset & ~QCOW2_COMPRESSED_SECTOR_MASK); diff --git a/block/trace-events b/block/trace-events index dbe76a7613..e21b95f3e6 100644 --- a/block/trace-events +++ b/block/trace-events @@ -77,7 +77,7 @@ luring_io_uring_submit(void *s, int ret) "LuringState %p ret %d" luring_resubmit_short_read(void *s, void *luringcb, int nread) "LuringState %p luringcb %p nread %d" # qcow2.c -qcow2_add_task(void *co, void *bs, void *pool, const char *action, int cluster_type, uint64_t file_cluster_offset, uint64_t offset, uint64_t bytes, void *qiov, size_t qiov_offset) "co %p bs %p pool %p: %s: cluster_type %d file_cluster_offset %" PRIu64 " offset %" PRIu64 " bytes %" PRIu64 " qiov %p qiov_offset %zu" +qcow2_add_task(void *co, void *bs, void *pool, const char *action, int cluster_type, uint64_t host_offset, uint64_t offset, uint64_t bytes, void *qiov, size_t qiov_offset) "co %p bs %p pool %p: %s: cluster_type %d file_cluster_offset %" PRIu64 " offset %" PRIu64 " bytes %" PRIu64 " qiov %p qiov_offset %zu" qcow2_writev_start_req(void *co, int64_t offset, int bytes) "co %p offset 0x%" PRIx64 " bytes %d" qcow2_writev_done_req(void *co, int ret) "co %p ret %d" qcow2_writev_start_part(void *co) "co %p" From patchwork Sun Jun 28 11:02:12 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alberto Garcia X-Patchwork-Id: 279187 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 479C2C433E0 for ; Sun, 28 Jun 2020 11:05:12 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 1418D20771 for ; Sun, 28 Jun 2020 11:05:12 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=igalia.com header.i=@igalia.com header.b="RaAzkD7n" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 1418D20771 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=igalia.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:45804 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jpV7X-0000uc-8b for qemu-devel@archiver.kernel.org; Sun, 28 Jun 2020 07:05:11 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:47758) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jpV62-0006v3-KM; Sun, 28 Jun 2020 07:03:38 -0400 Received: from fanzine.igalia.com ([178.60.130.6]:42243) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1jpV5x-0000Wb-Ut; Sun, 28 Jun 2020 07:03:38 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From; bh=zhUI+SdcRuNKlLxl0eH0JWm96meGNa39l1+qfmyCMtQ=; b=RaAzkD7nNUYhv1iUDsw3stPCg4juLcrbuNRAmDsV5H0YxscReBBS2IvWelsBw33J9Ro0pooIhVf+YnEnQGn9nDLqEncoXqCcwUA8LegZUrzySeAh88QfG1a4GD8zKdA4eFFSPSzn794zq35XhkjytmMZGmDtmYNMkSdZGGws91MkOiaf6Fl82fpgnwouD3QEWHVGRdHi4FZ6eH/jUtniatxfIl9FRy4OcfXw+LOqyA/gYeSRTyZqwTJp8oO9jxHO/enRHA2ZfSp9rcOFy8WT+MH+koLjAnn1Sn6xllXttlLCYQ49RNcNS968UAm3cGzVDzpn1CG4EMS9fdrD6YD15w==; Received: from 26.red-79-158-236.dynamicip.rima-tde.net ([79.158.236.26] helo=perseus.local) by fanzine.igalia.com with esmtpsa (Cipher TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim) id 1jpV5X-0002gN-Cc; Sun, 28 Jun 2020 13:03:07 +0200 Received: from berto by perseus.local with local (Exim 4.92) (envelope-from ) id 1jpV5H-00038D-H4; Sun, 28 Jun 2020 13:02:51 +0200 From: Alberto Garcia To: qemu-devel@nongnu.org Subject: [PATCH v9 03/34] qcow2: Add calculate_l2_meta() Date: Sun, 28 Jun 2020 13:02:12 +0200 Message-Id: <08a1848d974ee94f3074fd76132d30cd041d00f6.1593342067.git.berto@igalia.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 Received-SPF: pass client-ip=178.60.130.6; envelope-from=berto@igalia.com; helo=fanzine.igalia.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/06/28 07:03:08 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x (no timestamps) [generic] [fuzzy] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , Alberto Garcia , qemu-block@nongnu.org, Derek Su , Max Reitz Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" handle_alloc() creates a QCowL2Meta structure in order to update the image metadata and perform the necessary copy-on-write operations. This patch moves that code to a separate function so it can be used from other places. Signed-off-by: Alberto Garcia Reviewed-by: Max Reitz --- block/qcow2-cluster.c | 77 +++++++++++++++++++++++++++++-------------- 1 file changed, 53 insertions(+), 24 deletions(-) diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c index 9ab41cb728..61ad638bdc 100644 --- a/block/qcow2-cluster.c +++ b/block/qcow2-cluster.c @@ -1037,6 +1037,56 @@ void qcow2_alloc_cluster_abort(BlockDriverState *bs, QCowL2Meta *m) } } +/* + * For a given write request, create a new QCowL2Meta structure, add + * it to @m and the BDRVQcow2State.cluster_allocs list. + * + * @host_cluster_offset points to the beginning of the first cluster. + * + * @guest_offset and @bytes indicate the offset and length of the + * request. + * + * If @keep_old is true it means that the clusters were already + * allocated and will be overwritten. If false then the clusters are + * new and we have to decrease the reference count of the old ones. + */ +static void calculate_l2_meta(BlockDriverState *bs, + uint64_t host_cluster_offset, + uint64_t guest_offset, unsigned bytes, + QCowL2Meta **m, bool keep_old) +{ + BDRVQcow2State *s = bs->opaque; + unsigned cow_start_from = 0; + unsigned cow_start_to = offset_into_cluster(s, guest_offset); + unsigned cow_end_from = cow_start_to + bytes; + unsigned cow_end_to = ROUND_UP(cow_end_from, s->cluster_size); + unsigned nb_clusters = size_to_clusters(s, cow_end_from); + QCowL2Meta *old_m = *m; + + *m = g_malloc0(sizeof(**m)); + **m = (QCowL2Meta) { + .next = old_m, + + .alloc_offset = host_cluster_offset, + .offset = start_of_cluster(s, guest_offset), + .nb_clusters = nb_clusters, + + .keep_old_clusters = keep_old, + + .cow_start = { + .offset = cow_start_from, + .nb_bytes = cow_start_to - cow_start_from, + }, + .cow_end = { + .offset = cow_end_from, + .nb_bytes = cow_end_to - cow_end_from, + }, + }; + + qemu_co_queue_init(&(*m)->dependent_requests); + QLIST_INSERT_HEAD(&s->cluster_allocs, *m, next_in_flight); +} + /* * Returns the number of contiguous clusters that can be used for an allocating * write, but require COW to be performed (this includes yet unallocated space, @@ -1435,35 +1485,14 @@ static int handle_alloc(BlockDriverState *bs, uint64_t guest_offset, uint64_t requested_bytes = *bytes + offset_into_cluster(s, guest_offset); int avail_bytes = nb_clusters << s->cluster_bits; int nb_bytes = MIN(requested_bytes, avail_bytes); - QCowL2Meta *old_m = *m; - - *m = g_malloc0(sizeof(**m)); - - **m = (QCowL2Meta) { - .next = old_m, - - .alloc_offset = alloc_cluster_offset, - .offset = start_of_cluster(s, guest_offset), - .nb_clusters = nb_clusters, - - .keep_old_clusters = keep_old_clusters, - - .cow_start = { - .offset = 0, - .nb_bytes = offset_into_cluster(s, guest_offset), - }, - .cow_end = { - .offset = nb_bytes, - .nb_bytes = avail_bytes - nb_bytes, - }, - }; - qemu_co_queue_init(&(*m)->dependent_requests); - QLIST_INSERT_HEAD(&s->cluster_allocs, *m, next_in_flight); *host_offset = alloc_cluster_offset + offset_into_cluster(s, guest_offset); *bytes = MIN(*bytes, nb_bytes - offset_into_cluster(s, guest_offset)); assert(*bytes != 0); + calculate_l2_meta(bs, alloc_cluster_offset, guest_offset, *bytes, + m, keep_old_clusters); + return 1; fail: From patchwork Sun Jun 28 11:02:13 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alberto Garcia X-Patchwork-Id: 279182 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7FFF2C433DF for ; Sun, 28 Jun 2020 11:11:51 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 4B13E20B80 for ; Sun, 28 Jun 2020 11:11:51 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=igalia.com header.i=@igalia.com header.b="lsk0/TMq" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 4B13E20B80 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=igalia.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:43488 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jpVDy-0003Zs-Ft for qemu-devel@archiver.kernel.org; Sun, 28 Jun 2020 07:11:50 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:47808) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jpV64-0006y3-Mh; Sun, 28 Jun 2020 07:03:40 -0400 Received: from fanzine.igalia.com ([178.60.130.6]:42246) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1jpV5x-0000WZ-VG; Sun, 28 Jun 2020 07:03:40 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From; bh=x44WykpORUb7jKPsPZokuc5MU7JgoaeSdWXwYoNGUz0=; b=lsk0/TMqHOHLkoV/eVCBo7690IotqousTYlwxI/aaGaownTjjpX95yvW+B/GdWynqjSQ3sZwZmkwwSGQB3rWXMzf93ITnAjtAmgZo1ZU1DoLfSHY5qxSSHPsRcDbvFjOkEblso3crkYegVThTMwLuVLFTpGYX0qLQ4itU2t/ckMq9/vA2ii8ZWvJ5e+lOjPuelMgXOQxps/u5xWi48EEgU/bW45u3ZNs4j4AuVkFg+103owweKecrG8miiHKBBbHBFTzaaQpGSvYY8DNNu4tuAoOHoma1+GoRTNMvAhMcKcaqhab5KMbCxxFVz4WhPRrBxNhKc/N4Sejx8reEtHuYQ==; Received: from 26.red-79-158-236.dynamicip.rima-tde.net ([79.158.236.26] helo=perseus.local) by fanzine.igalia.com with esmtpsa (Cipher TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim) id 1jpV5X-0002gO-Db; Sun, 28 Jun 2020 13:03:07 +0200 Received: from berto by perseus.local with local (Exim 4.92) (envelope-from ) id 1jpV5H-00038F-I6; Sun, 28 Jun 2020 13:02:51 +0200 From: Alberto Garcia To: qemu-devel@nongnu.org Subject: [PATCH v9 04/34] qcow2: Split cluster_needs_cow() out of count_cow_clusters() Date: Sun, 28 Jun 2020 13:02:13 +0200 Message-Id: X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 Received-SPF: pass client-ip=178.60.130.6; envelope-from=berto@igalia.com; helo=fanzine.igalia.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/06/28 07:03:08 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x (no timestamps) [generic] [fuzzy] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , Alberto Garcia , qemu-block@nongnu.org, Derek Su , Max Reitz Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" We are going to need it in other places. Signed-off-by: Alberto Garcia Reviewed-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Max Reitz --- block/qcow2-cluster.c | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c index 61ad638bdc..80f9787461 100644 --- a/block/qcow2-cluster.c +++ b/block/qcow2-cluster.c @@ -1087,6 +1087,24 @@ static void calculate_l2_meta(BlockDriverState *bs, QLIST_INSERT_HEAD(&s->cluster_allocs, *m, next_in_flight); } +/* Returns true if writing to a cluster requires COW */ +static bool cluster_needs_cow(BlockDriverState *bs, uint64_t l2_entry) +{ + switch (qcow2_get_cluster_type(bs, l2_entry)) { + case QCOW2_CLUSTER_NORMAL: + if (l2_entry & QCOW_OFLAG_COPIED) { + return false; + } + case QCOW2_CLUSTER_UNALLOCATED: + case QCOW2_CLUSTER_COMPRESSED: + case QCOW2_CLUSTER_ZERO_PLAIN: + case QCOW2_CLUSTER_ZERO_ALLOC: + return true; + default: + abort(); + } +} + /* * Returns the number of contiguous clusters that can be used for an allocating * write, but require COW to be performed (this includes yet unallocated space, @@ -1099,25 +1117,11 @@ static int count_cow_clusters(BlockDriverState *bs, int nb_clusters, for (i = 0; i < nb_clusters; i++) { uint64_t l2_entry = be64_to_cpu(l2_slice[l2_index + i]); - QCow2ClusterType cluster_type = qcow2_get_cluster_type(bs, l2_entry); - - switch(cluster_type) { - case QCOW2_CLUSTER_NORMAL: - if (l2_entry & QCOW_OFLAG_COPIED) { - goto out; - } + if (!cluster_needs_cow(bs, l2_entry)) { break; - case QCOW2_CLUSTER_UNALLOCATED: - case QCOW2_CLUSTER_COMPRESSED: - case QCOW2_CLUSTER_ZERO_PLAIN: - case QCOW2_CLUSTER_ZERO_ALLOC: - break; - default: - abort(); } } -out: assert(i <= nb_clusters); return i; } From patchwork Sun Jun 28 11:02:16 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alberto Garcia X-Patchwork-Id: 279186 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7A0C2C433E0 for ; Sun, 28 Jun 2020 11:07:42 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 3E52720771 for ; Sun, 28 Jun 2020 11:07:42 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=igalia.com header.i=@igalia.com header.b="Kos87P5I" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 3E52720771 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=igalia.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:54262 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jpV9x-0004dv-Fg for qemu-devel@archiver.kernel.org; Sun, 28 Jun 2020 07:07:41 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:47842) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jpV65-00070L-Pp; Sun, 28 Jun 2020 07:03:41 -0400 Received: from fanzine.igalia.com ([178.60.130.6]:42262) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1jpV5y-0000We-4O; Sun, 28 Jun 2020 07:03:41 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From; bh=FDdJ3NUfcSN6UfYGz2xPvNrqQCi8ZzpI2orXDpb0voQ=; b=Kos87P5ItIUSwHMTBISOdyMSdNztLDVqc53MbC6iC5/Nvw8BOoHNvzEFQWkK3BPZFonw8Rrwg0wFNcjk/JIHplSu0c31pFFSqj3uhQPS/Vc8rclooD7jYvaBMMjfrKX0wy24p2iDOE+9oqNYndTWdRPYHCmTJJg9Y3fS1UjAPn+gE9I3K/FCujhjwYbBzyhHMzX8ulm0NSogfNFcvvE4JK4uk5djRhZ+Ovq3V8eFhKnyv2VwwIhm8xJ2x1xX7LTWE/AN7PPTPN5wtv8trH8/OhlP83SUHuzeP26FHSYEN0hTvW94IF4ksaUKIyP0jEJXpadXxv+IGSKiwETyjWZNWQ==; Received: from 26.red-79-158-236.dynamicip.rima-tde.net ([79.158.236.26] helo=perseus.local) by fanzine.igalia.com with esmtpsa (Cipher TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim) id 1jpV5X-0002gT-G6; Sun, 28 Jun 2020 13:03:08 +0200 Received: from berto by perseus.local with local (Exim 4.92) (envelope-from ) id 1jpV5H-00038L-Lu; Sun, 28 Jun 2020 13:02:51 +0200 From: Alberto Garcia To: qemu-devel@nongnu.org Subject: [PATCH v9 07/34] qcow2: Document the Extended L2 Entries feature Date: Sun, 28 Jun 2020 13:02:16 +0200 Message-Id: X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 Received-SPF: pass client-ip=178.60.130.6; envelope-from=berto@igalia.com; helo=fanzine.igalia.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/06/28 07:03:08 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x (no timestamps) [generic] [fuzzy] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , Alberto Garcia , qemu-block@nongnu.org, Derek Su , Max Reitz Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Subcluster allocation in qcow2 is implemented by extending the existing L2 table entries and adding additional information to indicate the allocation status of each subcluster. This patch documents the changes to the qcow2 format and how they affect the calculation of the L2 cache size. Signed-off-by: Alberto Garcia Reviewed-by: Max Reitz Reviewed-by: Eric Blake --- docs/interop/qcow2.txt | 68 ++++++++++++++++++++++++++++++++++++++++-- docs/qcow2-cache.txt | 19 +++++++++++- 2 files changed, 83 insertions(+), 4 deletions(-) diff --git a/docs/interop/qcow2.txt b/docs/interop/qcow2.txt index cb723463f2..64e9345fb4 100644 --- a/docs/interop/qcow2.txt +++ b/docs/interop/qcow2.txt @@ -42,6 +42,9 @@ The first cluster of a qcow2 image contains the file header: as the maximum cluster size and won't be able to open images with larger cluster sizes. + Note: if the image has Extended L2 Entries then cluster_bits + must be at least 14 (i.e. 16384 byte clusters). + 24 - 31: size Virtual disk size in bytes. @@ -117,7 +120,12 @@ the next fields through header_length. clusters. The compression_type field must be present and not zero. - Bits 4-63: Reserved (set to 0) + Bit 4: Extended L2 Entries. If this bit is set then + L2 table entries use an extended format that + allows subcluster-based allocation. See the + Extended L2 Entries section for more details. + + Bits 5-63: Reserved (set to 0) 80 - 87: compatible_features Bitmask of compatible features. An implementation can @@ -498,7 +506,7 @@ cannot be relaxed without an incompatible layout change). Given an offset into the virtual disk, the offset into the image file can be obtained as follows: - l2_entries = (cluster_size / sizeof(uint64_t)) + l2_entries = (cluster_size / sizeof(uint64_t)) [*] l2_index = (offset / cluster_size) % l2_entries l1_index = (offset / cluster_size) / l2_entries @@ -508,6 +516,8 @@ obtained as follows: return cluster_offset + (offset % cluster_size) + [*] this changes if Extended L2 Entries are enabled, see next section + L1 table entry: Bit 0 - 8: Reserved (set to 0) @@ -548,7 +558,8 @@ Standard Cluster Descriptor: nor is data read from the backing file if the cluster is unallocated. - With version 2, this is always 0. + With version 2 or with extended L2 entries (see the next + section), this is always 0. 1 - 8: Reserved (set to 0) @@ -585,6 +596,57 @@ file (except if bit 0 in the Standard Cluster Descriptor is set). If there is no backing file or the backing file is smaller than the image, they shall read zeros for all parts that are not covered by the backing file. +== Extended L2 Entries == + +An image uses Extended L2 Entries if bit 4 is set on the incompatible_features +field of the header. + +In these images standard data clusters are divided into 32 subclusters of the +same size. They are contiguous and start from the beginning of the cluster. +Subclusters can be allocated independently and the L2 entry contains information +indicating the status of each one of them. Compressed data clusters don't have +subclusters so they are treated the same as in images without this feature. + +The size of an extended L2 entry is 128 bits so the number of entries per table +is calculated using this formula: + + l2_entries = (cluster_size / (2 * sizeof(uint64_t))) + +The first 64 bits have the same format as the standard L2 table entry described +in the previous section, with the exception of bit 0 of the standard cluster +descriptor. + +The last 64 bits contain a subcluster allocation bitmap with this format: + +Subcluster Allocation Bitmap (for standard clusters): + + Bit 0 - 31: Allocation status (one bit per subcluster) + + 1: the subcluster is allocated. In this case the + host cluster offset field must contain a valid + offset. + 0: the subcluster is not allocated. In this case + read requests shall go to the backing file or + return zeros if there is no backing file data. + + Bits are assigned starting from the least significant + one (i.e. bit x is used for subcluster x). + + 32 - 63 Subcluster reads as zeros (one bit per subcluster) + + 1: the subcluster reads as zeros. In this case the + allocation status bit must be unset. The host + cluster offset field may or may not be set. + 0: no effect. + + Bits are assigned starting from the least significant + one (i.e. bit x is used for subcluster x - 32). + +Subcluster Allocation Bitmap (for compressed clusters): + + Bit 0 - 63: Reserved (set to 0) + Compressed clusters don't have subclusters, + so this field is not used. == Snapshots == diff --git a/docs/qcow2-cache.txt b/docs/qcow2-cache.txt index d57f409861..5f763aa6bb 100644 --- a/docs/qcow2-cache.txt +++ b/docs/qcow2-cache.txt @@ -1,6 +1,6 @@ qcow2 L2/refcount cache configuration ===================================== -Copyright (C) 2015, 2018 Igalia, S.L. +Copyright (C) 2015, 2018-2020 Igalia, S.L. Author: Alberto Garcia This work is licensed under the terms of the GNU GPL, version 2 or @@ -222,3 +222,20 @@ support this functionality, and is 0 (disabled) on other platforms. This functionality currently relies on the MADV_DONTNEED argument for madvise() to actually free the memory. This is a Linux-specific feature, so cache-clean-interval is not supported on other systems. + + +Extended L2 Entries +------------------- +All numbers shown in this document are valid for qcow2 images with normal +64-bit L2 entries. + +Images with extended L2 entries need twice as much L2 metadata, so the L2 +cache size must be twice as large for the same disk space. + + disk_size = l2_cache_size * cluster_size / 16 + +i.e. + + l2_cache_size = disk_size * 16 / cluster_size + +Refcount blocks are not affected by this. From patchwork Sun Jun 28 11:02:17 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alberto Garcia X-Patchwork-Id: 279184 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E2092C433E0 for ; Sun, 28 Jun 2020 11:09:42 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id AC6BE20771 for ; Sun, 28 Jun 2020 11:09:42 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=igalia.com header.i=@igalia.com header.b="dPKxX884" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org AC6BE20771 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=igalia.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:34666 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jpVBt-0008HH-Vg for qemu-devel@archiver.kernel.org; Sun, 28 Jun 2020 07:09:42 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:47846) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jpV66-000717-5M; Sun, 28 Jun 2020 07:03:42 -0400 Received: from fanzine.igalia.com ([178.60.130.6]:42244) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1jpV5y-0000WY-3o; Sun, 28 Jun 2020 07:03:41 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From; bh=FLnW2yKPd876mhIBSmNOIZZESH7oUMAItbps7FGNKa4=; b=dPKxX884d6m0QSfRu6LkOxBJtVKBFXkNsjyXo6TfC3Y93FpRDLQDtNn9ctDzbyfw27d7ysoXH97K2fyw+HW5KNYuV8EVuXSxgZMzIujUi9KxX2/jxpbx7wUnJGNSqEGaeGzobVU50Hqmg4NrVS7Xp61d0lNurWWNwlk4gPke5iazQ0LDiR283YCKZNO4vByiWOSvvZv36CpJFVohdf4NvIvZYD/8zZ/F1ldvOY2B75UnprvjECgDl8511WLgHRGif+6Tp+biYrLmZ456IJ3SIuIpcDGkxgEBYkxS6uEobvzYBu1H1BEwCyKdRzxC9rHOU8Yt/WhNNRM85tROfRmDlA==; Received: from 26.red-79-158-236.dynamicip.rima-tde.net ([79.158.236.26] helo=perseus.local) by fanzine.igalia.com with esmtpsa (Cipher TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim) id 1jpV5X-0002gU-CN; Sun, 28 Jun 2020 13:03:07 +0200 Received: from berto by perseus.local with local (Exim 4.92) (envelope-from ) id 1jpV5H-00038N-Mn; Sun, 28 Jun 2020 13:02:51 +0200 From: Alberto Garcia To: qemu-devel@nongnu.org Subject: [PATCH v9 08/34] qcow2: Add dummy has_subclusters() function Date: Sun, 28 Jun 2020 13:02:17 +0200 Message-Id: <51ecdcef699bab9791800e48c4b35cfbd5f953c8.1593342067.git.berto@igalia.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 Received-SPF: pass client-ip=178.60.130.6; envelope-from=berto@igalia.com; helo=fanzine.igalia.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/06/28 07:03:08 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x (no timestamps) [generic] [fuzzy] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , Alberto Garcia , qemu-block@nongnu.org, Derek Su , Max Reitz Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" This function will be used by the qcow2 code to check if an image has subclusters or not. At the moment this simply returns false. Once all patches needed for subcluster support are ready then QEMU will be able to create and read images with subclusters and this function will return the actual value. Signed-off-by: Alberto Garcia Reviewed-by: Eric Blake Reviewed-by: Max Reitz Reviewed-by: Vladimir Sementsov-Ogievskiy --- block/qcow2.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/block/qcow2.h b/block/qcow2.h index eecbadc4cb..2064dd3d85 100644 --- a/block/qcow2.h +++ b/block/qcow2.h @@ -510,6 +510,12 @@ typedef enum QCow2MetadataOverlap { #define INV_OFFSET (-1ULL) +static inline bool has_subclusters(BDRVQcow2State *s) +{ + /* FIXME: Return false until this feature is complete */ + return false; +} + static inline uint64_t get_l2_entry(BDRVQcow2State *s, uint64_t *l2_slice, int idx) { From patchwork Sun Jun 28 11:02:18 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alberto Garcia X-Patchwork-Id: 279176 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C67FAC433DF for ; Sun, 28 Jun 2020 11:19:37 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 8EEE820B80 for ; Sun, 28 Jun 2020 11:19:37 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=igalia.com header.i=@igalia.com header.b="RgagloH8" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 8EEE820B80 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=igalia.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:42478 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jpVLU-0006Ze-Ni for qemu-devel@archiver.kernel.org; Sun, 28 Jun 2020 07:19:36 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:48484) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jpV6P-0007Q0-Jx; Sun, 28 Jun 2020 07:04:01 -0400 Received: from fanzine.igalia.com ([178.60.130.6]:42277) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1jpV6J-0000Wj-Js; Sun, 28 Jun 2020 07:04:01 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From; bh=zbMhjtGKVeY7EryanAE+iwZTdNLcuFqDn9UZxBryOf4=; b=RgagloH8tWgR7JNRrsXVZzN44kMze4oM6PSt/mJnNK9uu4XatQRVRXejFOtooSWdo8+hr7h8ss8j4zLOkutwTdX7fNkaviVS5/CXXarf6hRpObJq6dEPsGY+a1F0jV1VOR61DKnCJ7XI50yG3vm/RL68b5u0PCddp+QrsVZYRHnO88sOw/SymaFoQk/Go1ViQlFVYDHFplk8KRwQf86LG3yP8U1RTdHv8Pm2QRASNrwiyz/8o3lk7DiKT9q1W9bbOEOBOmUJkGxA0LJr6QxTjIkN2sOxGjFjaOP4Naqq7EspD15ZjfEnl8Cj9+i51U9Oh+RMLx9l+j19W5Qc37In3Q==; Received: from 26.red-79-158-236.dynamicip.rima-tde.net ([79.158.236.26] helo=perseus.local) by fanzine.igalia.com with esmtpsa (Cipher TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim) id 1jpV5X-0002gV-K2; Sun, 28 Jun 2020 13:03:08 +0200 Received: from berto by perseus.local with local (Exim 4.92) (envelope-from ) id 1jpV5H-00038P-Nn; Sun, 28 Jun 2020 13:02:51 +0200 From: Alberto Garcia To: qemu-devel@nongnu.org Subject: [PATCH v9 09/34] qcow2: Add subcluster-related fields to BDRVQcow2State Date: Sun, 28 Jun 2020 13:02:18 +0200 Message-Id: <81ab1f501461c3870e4b6358fa966472760cd5b3.1593342067.git.berto@igalia.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 Received-SPF: pass client-ip=178.60.130.6; envelope-from=berto@igalia.com; helo=fanzine.igalia.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/06/28 07:03:08 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x (no timestamps) [generic] [fuzzy] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , Alberto Garcia , qemu-block@nongnu.org, Derek Su , Max Reitz Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" This patch adds the following new fields to BDRVQcow2State: - subclusters_per_cluster: Number of subclusters in a cluster - subcluster_size: The size of each subcluster, in bytes - subcluster_bits: No. of bits so 1 << subcluster_bits = subcluster_size Images without subclusters are treated as if they had exactly one subcluster per cluster (i.e. subcluster_size = cluster_size). Signed-off-by: Alberto Garcia Reviewed-by: Max Reitz Reviewed-by: Vladimir Sementsov-Ogievskiy --- block/qcow2.h | 5 +++++ block/qcow2.c | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/block/qcow2.h b/block/qcow2.h index 2064dd3d85..eee4c8de9c 100644 --- a/block/qcow2.h +++ b/block/qcow2.h @@ -78,6 +78,8 @@ /* The cluster reads as all zeros */ #define QCOW_OFLAG_ZERO (1ULL << 0) +#define QCOW_EXTL2_SUBCLUSTERS_PER_CLUSTER 32 + #define MIN_CLUSTER_BITS 9 #define MAX_CLUSTER_BITS 21 @@ -295,6 +297,9 @@ typedef struct BDRVQcow2State { int cluster_bits; int cluster_size; int l2_slice_size; + int subcluster_bits; + int subcluster_size; + int subclusters_per_cluster; int l2_bits; int l2_size; int l1_size; diff --git a/block/qcow2.c b/block/qcow2.c index afb00ada42..5c175a314c 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -1433,6 +1433,11 @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options, } } + s->subclusters_per_cluster = + has_subclusters(s) ? QCOW_EXTL2_SUBCLUSTERS_PER_CLUSTER : 1; + s->subcluster_size = s->cluster_size / s->subclusters_per_cluster; + s->subcluster_bits = ctz32(s->subcluster_size); + /* Check support for various header values */ if (header.refcount_order > 6) { error_setg(errp, "Reference count entry width too large; may not " From patchwork Sun Jun 28 11:02:19 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alberto Garcia X-Patchwork-Id: 279188 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 597BBC433E0 for ; Sun, 28 Jun 2020 11:05:02 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 1D8E320857 for ; Sun, 28 Jun 2020 11:05:02 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=igalia.com header.i=@igalia.com header.b="bKi/OLMU" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 1D8E320857 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=igalia.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:45000 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jpV7N-0000YM-6m for qemu-devel@archiver.kernel.org; Sun, 28 Jun 2020 07:05:01 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:47730) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jpV62-0006uR-3r; Sun, 28 Jun 2020 07:03:38 -0400 Received: from fanzine.igalia.com ([178.60.130.6]:42235) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1jpV5y-0000WX-17; Sun, 28 Jun 2020 07:03:37 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From; bh=DWFzz4T+AhoA6h3Vs/ROK38xw63e6XfJbmyzdTE6EKY=; b=bKi/OLMUwjmPG5wbTuFYXmLc9dv0t71DKUeNPHUOkDu5Rh4BMvU3Larr55ocbd8ZxVVhWTTQOJN6oinHEcqUP5FPzG7BuLJy5bMhSNaMB1zSBdGqTQlM/531wk1WCenpNSTiid1YilFk5i0dUXjH5egiJh6qB8t1lmhB1F2vqoQV8Ws3R9ds41ZJzPH9wFTr2x93eWLolLlX9b/Eg42+zdfo66y4JT6FMoama8ZuxmdyD5Noo8ROjqI2WkNpJuxwfgOhN2bx6FgnOD31oF2uXY1m1126yAZ3iQ/stCN5+6sqYRVH9bEqBAQmzpVNJFwDjhBHHG/kU9EUCGRaPx5yXQ==; Received: from 26.red-79-158-236.dynamicip.rima-tde.net ([79.158.236.26] helo=perseus.local) by fanzine.igalia.com with esmtpsa (Cipher TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim) id 1jpV5X-0002gW-Gs; Sun, 28 Jun 2020 13:03:07 +0200 Received: from berto by perseus.local with local (Exim 4.92) (envelope-from ) id 1jpV5H-00038R-Ok; Sun, 28 Jun 2020 13:02:51 +0200 From: Alberto Garcia To: qemu-devel@nongnu.org Subject: [PATCH v9 10/34] qcow2: Add offset_to_sc_index() Date: Sun, 28 Jun 2020 13:02:19 +0200 Message-Id: X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 Received-SPF: pass client-ip=178.60.130.6; envelope-from=berto@igalia.com; helo=fanzine.igalia.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/06/28 07:03:08 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x (no timestamps) [generic] [fuzzy] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , Alberto Garcia , qemu-block@nongnu.org, Derek Su , Max Reitz Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" For a given offset, return the subcluster number within its cluster (i.e. with 32 subclusters per cluster it returns a number between 0 and 31). Signed-off-by: Alberto Garcia Reviewed-by: Max Reitz Reviewed-by: Vladimir Sementsov-Ogievskiy --- block/qcow2.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/block/qcow2.h b/block/qcow2.h index eee4c8de9c..2503374677 100644 --- a/block/qcow2.h +++ b/block/qcow2.h @@ -581,6 +581,11 @@ static inline int offset_to_l2_slice_index(BDRVQcow2State *s, int64_t offset) return (offset >> s->cluster_bits) & (s->l2_slice_size - 1); } +static inline int offset_to_sc_index(BDRVQcow2State *s, int64_t offset) +{ + return (offset >> s->subcluster_bits) & (s->subclusters_per_cluster - 1); +} + static inline int64_t qcow2_vm_state_offset(BDRVQcow2State *s) { return (int64_t)s->l1_vm_state_index << (s->cluster_bits + s->l2_bits); From patchwork Sun Jun 28 11:02:22 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alberto Garcia X-Patchwork-Id: 279185 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D7A1DC433E0 for ; Sun, 28 Jun 2020 11:08:16 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id A1E7F20771 for ; Sun, 28 Jun 2020 11:08:16 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=igalia.com header.i=@igalia.com header.b="kAdiWIX5" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org A1E7F20771 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=igalia.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:56592 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jpVAV-0005b6-TQ for qemu-devel@archiver.kernel.org; Sun, 28 Jun 2020 07:08:15 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:48394) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jpV6M-0007L1-M9; Sun, 28 Jun 2020 07:03:58 -0400 Received: from fanzine.igalia.com ([178.60.130.6]:42321) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1jpV6I-0000X6-Nf; Sun, 28 Jun 2020 07:03:58 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From; bh=3TcxrFGVkCtUtsIcvfPDHVNJ3SGTTueaU2gMyJDgFo0=; b=kAdiWIX5g7XcMZjxPQJkESRShwLT4Wcg69KMhp7aUVPmL/5IQMnqnjaahP9H2J16qs7KC0ZLHPGWsWr17UDAbYKk69aHBWhNUx9b/6SrFwiilXj78BBZsI97yfkWe+p6Jij31Gsnp/FpFDZ3Ro5x6vTfoOmUtgVoW0BH2g27Min5n5q40E1BXNwG8EyJKsN+Q8CrzoT+ofiBhgrlsTRmX+Nq482JOAdxuDuVr4WiNI/0ZT4u7IkRaakLyUGkyV5sKtKaibaUmmx3O7baXlkeSx/0Kosps0A22TCh3lGvj100kaJp7XvhwIsNHTx5V5t1ZHNYWzlMqfiuLmF2PGHZnw==; Received: from 26.red-79-158-236.dynamicip.rima-tde.net ([79.158.236.26] helo=perseus.local) by fanzine.igalia.com with esmtpsa (Cipher TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim) id 1jpV5Y-0002gZ-50; Sun, 28 Jun 2020 13:03:09 +0200 Received: from berto by perseus.local with local (Exim 4.92) (envelope-from ) id 1jpV5H-00038X-Rv; Sun, 28 Jun 2020 13:02:51 +0200 From: Alberto Garcia To: qemu-devel@nongnu.org Subject: [PATCH v9 13/34] qcow2: Update get/set_l2_entry() and add get/set_l2_bitmap() Date: Sun, 28 Jun 2020 13:02:22 +0200 Message-Id: <40ed71f2147221dc6c29b6603cb4a35db599d0fa.1593342067.git.berto@igalia.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 Received-SPF: pass client-ip=178.60.130.6; envelope-from=berto@igalia.com; helo=fanzine.igalia.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/06/28 07:03:08 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x (no timestamps) [generic] [fuzzy] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , Alberto Garcia , qemu-block@nongnu.org, Derek Su , Max Reitz Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Extended L2 entries are 128-bit wide: 64 bits for the entry itself and 64 bits for the subcluster allocation bitmap. In order to support them correctly get/set_l2_entry() need to be updated so they take the entry width into account in order to calculate the correct offset. This patch also adds the get/set_l2_bitmap() functions that are used to access the bitmaps. For convenience we allow calling get_l2_bitmap() on images without subclusters. In this case the returned value is always 0 and has no meaning. Signed-off-by: Alberto Garcia Reviewed-by: Eric Blake --- block/qcow2.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/block/qcow2.h b/block/qcow2.h index 46b351229a..82b86f6cec 100644 --- a/block/qcow2.h +++ b/block/qcow2.h @@ -533,15 +533,36 @@ static inline size_t l2_entry_size(BDRVQcow2State *s) static inline uint64_t get_l2_entry(BDRVQcow2State *s, uint64_t *l2_slice, int idx) { + idx *= l2_entry_size(s) / sizeof(uint64_t); return be64_to_cpu(l2_slice[idx]); } +static inline uint64_t get_l2_bitmap(BDRVQcow2State *s, uint64_t *l2_slice, + int idx) +{ + if (has_subclusters(s)) { + idx *= l2_entry_size(s) / sizeof(uint64_t); + return be64_to_cpu(l2_slice[idx + 1]); + } else { + return 0; /* For convenience only; this value has no meaning. */ + } +} + static inline void set_l2_entry(BDRVQcow2State *s, uint64_t *l2_slice, int idx, uint64_t entry) { + idx *= l2_entry_size(s) / sizeof(uint64_t); l2_slice[idx] = cpu_to_be64(entry); } +static inline void set_l2_bitmap(BDRVQcow2State *s, uint64_t *l2_slice, + int idx, uint64_t bitmap) +{ + assert(has_subclusters(s)); + idx *= l2_entry_size(s) / sizeof(uint64_t); + l2_slice[idx + 1] = cpu_to_be64(bitmap); +} + static inline bool has_data_file(BlockDriverState *bs) { BDRVQcow2State *s = bs->opaque; From patchwork Sun Jun 28 11:02:23 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alberto Garcia X-Patchwork-Id: 279172 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A61C0C433DF for ; Sun, 28 Jun 2020 11:28:52 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 6E09C20720 for ; Sun, 28 Jun 2020 11:28:52 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=igalia.com header.i=@igalia.com header.b="e8Hs8h60" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 6E09C20720 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=igalia.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:35758 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jpVUR-0007f0-OY for qemu-devel@archiver.kernel.org; Sun, 28 Jun 2020 07:28:51 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:48904) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jpV6c-0007rZ-8y; Sun, 28 Jun 2020 07:04:14 -0400 Received: from fanzine.igalia.com ([178.60.130.6]:42462) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1jpV6N-0000Xh-Nz; Sun, 28 Jun 2020 07:04:13 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From; bh=+DmjjyZHHWdutW0VaiL2W0gHvH6gXYupbWQx9py7wZo=; b=e8Hs8h60+2PlFnuR+8a5mBxfCwSY+sMs1zcMlIkSwzlbuweQUBMYnYRUujbJopN6ZiGh8lcKNWyFm6zR54FNzX+q85cXoFaeABwu5gH5U5CaJPopE3PMeNzyPI8Zzf6t+rBnYP3q0I79+v0mXxiwg/xp8E5kLg6r0ZQ3k8lTNtZ8cYLAWT7ZFOaNDa8Tt9a/r9+7Re+c3JZDQlKGtho+Vmfli1jpWWSKMK3ujdrB0AHJYMK9md0mo7BMvbqVwSjzvwIifnpwlLxN3Qu1VbChRYJsFiIDbqzL1mgp++yQA8r8ElHQqm8W05UBWfhGU2bkCljs1YwTy5sPvPasfN49yw==; Received: from 26.red-79-158-236.dynamicip.rima-tde.net ([79.158.236.26] helo=perseus.local) by fanzine.igalia.com with esmtpsa (Cipher TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim) id 1jpV5Y-0002ga-5h; Sun, 28 Jun 2020 13:03:10 +0200 Received: from berto by perseus.local with local (Exim 4.92) (envelope-from ) id 1jpV5H-00038Z-Sz; Sun, 28 Jun 2020 13:02:51 +0200 From: Alberto Garcia To: qemu-devel@nongnu.org Subject: [PATCH v9 14/34] qcow2: Add QCow2SubclusterType and qcow2_get_subcluster_type() Date: Sun, 28 Jun 2020 13:02:23 +0200 Message-Id: <6ee75696d3eaed56b46e91fe242fdfab51feb066.1593342067.git.berto@igalia.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 Received-SPF: pass client-ip=178.60.130.6; envelope-from=berto@igalia.com; helo=fanzine.igalia.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/06/28 07:03:08 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x (no timestamps) [generic] [fuzzy] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , Alberto Garcia , qemu-block@nongnu.org, Derek Su , Max Reitz Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" This patch adds QCow2SubclusterType, which is the subcluster-level version of QCow2ClusterType. All QCOW2_SUBCLUSTER_* values have the the same meaning as their QCOW2_CLUSTER_* equivalents (when they exist). See below for details and caveats. In images without extended L2 entries clusters are treated as having exactly one subcluster so it is possible to replace one data type with the other while keeping the exact same semantics. With extended L2 entries there are new possible values, and every subcluster in the same cluster can obviously have a different QCow2SubclusterType so functions need to be adapted to work on the subcluster level. There are several things that have to be taken into account: a) QCOW2_SUBCLUSTER_COMPRESSED means that the whole cluster is compressed. We do not support compression at the subcluster level. b) There are two different values for unallocated subclusters: QCOW2_SUBCLUSTER_UNALLOCATED_PLAIN which means that the whole cluster is unallocated, and QCOW2_SUBCLUSTER_UNALLOCATED_ALLOC which means that the cluster is allocated but the subcluster is not. The latter can only happen in images with extended L2 entries. c) QCOW2_SUBCLUSTER_INVALID is used to detect the cases where an L2 entry has a value that violates the specification. The caller is responsible for handling these situations. To prevent compatibility problems with images that have invalid values but are currently being read by QEMU without causing side effects, QCOW2_SUBCLUSTER_INVALID is only returned for images with extended L2 entries. qcow2_cluster_to_subcluster_type() is added as a separate function from qcow2_get_subcluster_type(), but this is only temporary and both will be merged in a subsequent patch. Signed-off-by: Alberto Garcia Reviewed-by: Eric Blake --- block/qcow2.h | 126 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 125 insertions(+), 1 deletion(-) diff --git a/block/qcow2.h b/block/qcow2.h index 82b86f6cec..3aec6f452a 100644 --- a/block/qcow2.h +++ b/block/qcow2.h @@ -80,6 +80,21 @@ #define QCOW_EXTL2_SUBCLUSTERS_PER_CLUSTER 32 +/* The subcluster X [0..31] is allocated */ +#define QCOW_OFLAG_SUB_ALLOC(X) (1ULL << (X)) +/* The subcluster X [0..31] reads as zeroes */ +#define QCOW_OFLAG_SUB_ZERO(X) (QCOW_OFLAG_SUB_ALLOC(X) << 32) +/* Subclusters [X, Y) (0 <= X <= Y <= 32) are allocated */ +#define QCOW_OFLAG_SUB_ALLOC_RANGE(X, Y) \ + (QCOW_OFLAG_SUB_ALLOC(Y) - QCOW_OFLAG_SUB_ALLOC(X)) +/* Subclusters [X, Y) (0 <= X <= Y <= 32) read as zeroes */ +#define QCOW_OFLAG_SUB_ZERO_RANGE(X, Y) \ + (QCOW_OFLAG_SUB_ALLOC_RANGE(X, Y) << 32) +/* L2 entry bitmap with all allocation bits set */ +#define QCOW_L2_BITMAP_ALL_ALLOC (QCOW_OFLAG_SUB_ALLOC_RANGE(0, 32)) +/* L2 entry bitmap with all "read as zeroes" bits set */ +#define QCOW_L2_BITMAP_ALL_ZEROES (QCOW_OFLAG_SUB_ZERO_RANGE(0, 32)) + /* Size of normal and extended L2 entries */ #define L2E_SIZE_NORMAL (sizeof(uint64_t)) #define L2E_SIZE_EXTENDED (sizeof(uint64_t) * 2) @@ -462,6 +477,33 @@ typedef struct QCowL2Meta QLIST_ENTRY(QCowL2Meta) next_in_flight; } QCowL2Meta; +/* + * In images with standard L2 entries all clusters are treated as if + * they had one subcluster so QCow2ClusterType and QCow2SubclusterType + * can be mapped to each other and have the exact same meaning + * (QCOW2_SUBCLUSTER_UNALLOCATED_ALLOC cannot happen in these images). + * + * In images with extended L2 entries QCow2ClusterType refers to the + * complete cluster and QCow2SubclusterType to each of the individual + * subclusters, so there are several possible combinations: + * + * |--------------+---------------------------| + * | Cluster type | Possible subcluster types | + * |--------------+---------------------------| + * | UNALLOCATED | UNALLOCATED_PLAIN | + * | | ZERO_PLAIN | + * |--------------+---------------------------| + * | NORMAL | UNALLOCATED_ALLOC | + * | | ZERO_ALLOC | + * | | NORMAL | + * |--------------+---------------------------| + * | COMPRESSED | COMPRESSED | + * |--------------+---------------------------| + * + * QCOW2_SUBCLUSTER_INVALID means that the L2 entry is incorrect and + * the image should be marked corrupt. + */ + typedef enum QCow2ClusterType { QCOW2_CLUSTER_UNALLOCATED, QCOW2_CLUSTER_ZERO_PLAIN, @@ -470,6 +512,16 @@ typedef enum QCow2ClusterType { QCOW2_CLUSTER_COMPRESSED, } QCow2ClusterType; +typedef enum QCow2SubclusterType { + QCOW2_SUBCLUSTER_UNALLOCATED_PLAIN, + QCOW2_SUBCLUSTER_UNALLOCATED_ALLOC, + QCOW2_SUBCLUSTER_ZERO_PLAIN, + QCOW2_SUBCLUSTER_ZERO_ALLOC, + QCOW2_SUBCLUSTER_NORMAL, + QCOW2_SUBCLUSTER_COMPRESSED, + QCOW2_SUBCLUSTER_INVALID, +} QCow2SubclusterType; + typedef enum QCow2MetadataOverlap { QCOW2_OL_MAIN_HEADER_BITNR = 0, QCOW2_OL_ACTIVE_L1_BITNR = 1, @@ -634,9 +686,11 @@ static inline int64_t qcow2_vm_state_offset(BDRVQcow2State *s) static inline QCow2ClusterType qcow2_get_cluster_type(BlockDriverState *bs, uint64_t l2_entry) { + BDRVQcow2State *s = bs->opaque; + if (l2_entry & QCOW_OFLAG_COMPRESSED) { return QCOW2_CLUSTER_COMPRESSED; - } else if (l2_entry & QCOW_OFLAG_ZERO) { + } else if ((l2_entry & QCOW_OFLAG_ZERO) && !has_subclusters(s)) { if (l2_entry & L2E_OFFSET_MASK) { return QCOW2_CLUSTER_ZERO_ALLOC; } @@ -656,6 +710,76 @@ static inline QCow2ClusterType qcow2_get_cluster_type(BlockDriverState *bs, } } +/* + * For an image without extended L2 entries, return the + * QCow2SubclusterType equivalent of a given QCow2ClusterType. + */ +static inline +QCow2SubclusterType qcow2_cluster_to_subcluster_type(QCow2ClusterType type) +{ + switch (type) { + case QCOW2_CLUSTER_COMPRESSED: + return QCOW2_SUBCLUSTER_COMPRESSED; + case QCOW2_CLUSTER_ZERO_PLAIN: + return QCOW2_SUBCLUSTER_ZERO_PLAIN; + case QCOW2_CLUSTER_ZERO_ALLOC: + return QCOW2_SUBCLUSTER_ZERO_ALLOC; + case QCOW2_CLUSTER_NORMAL: + return QCOW2_SUBCLUSTER_NORMAL; + case QCOW2_CLUSTER_UNALLOCATED: + return QCOW2_SUBCLUSTER_UNALLOCATED_PLAIN; + default: + g_assert_not_reached(); + } +} + +/* + * In an image without subsclusters @l2_bitmap is ignored and + * @sc_index must be 0. + * Return QCOW2_SUBCLUSTER_INVALID if an invalid l2 entry is detected + * (this checks the whole entry and bitmap, not only the bits related + * to subcluster @sc_index). + */ +static inline +QCow2SubclusterType qcow2_get_subcluster_type(BlockDriverState *bs, + uint64_t l2_entry, + uint64_t l2_bitmap, + unsigned sc_index) +{ + BDRVQcow2State *s = bs->opaque; + QCow2ClusterType type = qcow2_get_cluster_type(bs, l2_entry); + assert(sc_index < s->subclusters_per_cluster); + + if (has_subclusters(s)) { + switch (type) { + case QCOW2_CLUSTER_COMPRESSED: + return QCOW2_SUBCLUSTER_COMPRESSED; + case QCOW2_CLUSTER_NORMAL: + if ((l2_bitmap >> 32) & l2_bitmap) { + return QCOW2_SUBCLUSTER_INVALID; + } else if (l2_bitmap & QCOW_OFLAG_SUB_ZERO(sc_index)) { + return QCOW2_SUBCLUSTER_ZERO_ALLOC; + } else if (l2_bitmap & QCOW_OFLAG_SUB_ALLOC(sc_index)) { + return QCOW2_SUBCLUSTER_NORMAL; + } else { + return QCOW2_SUBCLUSTER_UNALLOCATED_ALLOC; + } + case QCOW2_CLUSTER_UNALLOCATED: + if (l2_bitmap & QCOW_L2_BITMAP_ALL_ALLOC) { + return QCOW2_SUBCLUSTER_INVALID; + } else if (l2_bitmap & QCOW_OFLAG_SUB_ZERO(sc_index)) { + return QCOW2_SUBCLUSTER_ZERO_PLAIN; + } else { + return QCOW2_SUBCLUSTER_UNALLOCATED_PLAIN; + } + default: + g_assert_not_reached(); + } + } else { + return qcow2_cluster_to_subcluster_type(type); + } +} + /* Check whether refcounts are eager or lazy */ static inline bool qcow2_need_accurate_refcounts(BDRVQcow2State *s) { From patchwork Sun Jun 28 11:02:25 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alberto Garcia X-Patchwork-Id: 279181 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id DF2A5C433E0 for ; Sun, 28 Jun 2020 11:12:30 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id AA8F420B80 for ; Sun, 28 Jun 2020 11:12:30 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=igalia.com header.i=@igalia.com header.b="BMOlXP6r" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org AA8F420B80 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=igalia.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:46248 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jpVEb-0004j7-Tp for qemu-devel@archiver.kernel.org; Sun, 28 Jun 2020 07:12:29 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:48490) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jpV6P-0007QD-NS; Sun, 28 Jun 2020 07:04:01 -0400 Received: from fanzine.igalia.com ([178.60.130.6]:42342) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1jpV6J-0000XB-Tw; Sun, 28 Jun 2020 07:04:01 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From; bh=PelaHdUpXyQLyETSNjZxQedA2munXec4UfgCc0HKoeA=; b=BMOlXP6rD3BdOaATYMfuq/wMjZwBG9bRTBLxN9RgtAxtnDESvRjF0tu/yyln7GdQQXOX9BWlhNWFRhB9zGTiU7fJIB4m5Pg8Hju8f/JYj1vldkUFQ7/DJb1gorciiyvGbeSPXkVqsg5LkOD5gNWrL9+Q/PqKh2Uo/dZWcjcg7Vw9tEb1BGhuvv9Vqaht41QhTuU2bM3ifDNSl0u2rlpUkqeD3J1ats3WtOyjJtdkFY2YXXfTDxr5ogvZ+yeOYw4wl2ZWKxuI/fx4uLClooHY8saDeGPwYdN7W0C5tn6pJ1kVbyzBfikqjPqmZzrXg+JKAIw8e10QzJeApfU5ZeYLbA==; Received: from 26.red-79-158-236.dynamicip.rima-tde.net ([79.158.236.26] helo=perseus.local) by fanzine.igalia.com with esmtpsa (Cipher TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim) id 1jpV5Y-0002gc-4N; Sun, 28 Jun 2020 13:03:09 +0200 Received: from berto by perseus.local with local (Exim 4.92) (envelope-from ) id 1jpV5H-00038d-Um; Sun, 28 Jun 2020 13:02:51 +0200 From: Alberto Garcia To: qemu-devel@nongnu.org Subject: [PATCH v9 16/34] qcow2: Add qcow2_cluster_is_allocated() Date: Sun, 28 Jun 2020 13:02:25 +0200 Message-Id: X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 Received-SPF: pass client-ip=178.60.130.6; envelope-from=berto@igalia.com; helo=fanzine.igalia.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/06/28 07:03:08 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x (no timestamps) [generic] [fuzzy] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , Alberto Garcia , qemu-block@nongnu.org, Derek Su , Max Reitz Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" This helper function tells us if a cluster is allocated (that is, there is an associated host offset for it). Signed-off-by: Alberto Garcia Reviewed-by: Eric Blake --- block/qcow2.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/block/qcow2.h b/block/qcow2.h index 3aec6f452a..ea647c8bb5 100644 --- a/block/qcow2.h +++ b/block/qcow2.h @@ -780,6 +780,12 @@ QCow2SubclusterType qcow2_get_subcluster_type(BlockDriverState *bs, } } +static inline bool qcow2_cluster_is_allocated(QCow2ClusterType type) +{ + return (type == QCOW2_CLUSTER_COMPRESSED || type == QCOW2_CLUSTER_NORMAL || + type == QCOW2_CLUSTER_ZERO_ALLOC); +} + /* Check whether refcounts are eager or lazy */ static inline bool qcow2_need_accurate_refcounts(BDRVQcow2State *s) { From patchwork Sun Jun 28 11:02:27 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alberto Garcia X-Patchwork-Id: 279173 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8255EC433E0 for ; Sun, 28 Jun 2020 11:26:27 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 3C42420720 for ; Sun, 28 Jun 2020 11:26:27 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=igalia.com header.i=@igalia.com header.b="DqQEGSBv" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 3C42420720 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=igalia.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:58152 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jpVS6-0005AN-HT for qemu-devel@archiver.kernel.org; Sun, 28 Jun 2020 07:26:26 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:48824) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jpV6a-0007o6-4E; Sun, 28 Jun 2020 07:04:12 -0400 Received: from fanzine.igalia.com ([178.60.130.6]:42465) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1jpV6M-0000Xj-1i; Sun, 28 Jun 2020 07:04:11 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From; bh=eX0gs7cy4Um4G492fOBEncGdlWNFQIufd+lO6E+xWIQ=; b=DqQEGSBv0Szz728/bnmdRhrd47/ztOVAmNxeW3lziyE1wZtEpA7eF7FwOrnxmM0x5rCcO0QA80zOSrOzx1r6GTNOYPq2oGVUPnwbS6z4ee6vDkFnqY5fjO7wgFh49G+tTeOMw+dpIiX2wrQ6DB5GtPGDRuKll63iUU+0ziuB1f7qXgBdLtnur0aiSDY5WNQo27VZd+nPiJJY0MJrZqY96Uvk8jtvE+wtHyk2Q0i28s2b7y2+tgPjnPTuXf+V0v2tv/pWJmCNE7UNHH2dPrFV+krqDiYYw1mRbsEP03dBM0BCLD8uCjwtUoRb9cAN2HQ/nAytU0i6tB7f1V4+hkziyw==; Received: from 26.red-79-158-236.dynamicip.rima-tde.net ([79.158.236.26] helo=perseus.local) by fanzine.igalia.com with esmtpsa (Cipher TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim) id 1jpV5X-0002ge-WC; Sun, 28 Jun 2020 13:03:10 +0200 Received: from berto by perseus.local with local (Exim 4.92) (envelope-from ) id 1jpV5I-00038h-0W; Sun, 28 Jun 2020 13:02:52 +0200 From: Alberto Garcia To: qemu-devel@nongnu.org Subject: [PATCH v9 18/34] qcow2: Replace QCOW2_CLUSTER_* with QCOW2_SUBCLUSTER_* Date: Sun, 28 Jun 2020 13:02:27 +0200 Message-Id: <58d560d48ff4a96f54fb419e17f1b0de1064f04e.1593342067.git.berto@igalia.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 Received-SPF: pass client-ip=178.60.130.6; envelope-from=berto@igalia.com; helo=fanzine.igalia.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/06/28 07:03:08 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x (no timestamps) [generic] [fuzzy] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , Alberto Garcia , qemu-block@nongnu.org, Derek Su , Max Reitz Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" In order to support extended L2 entries some functions of the qcow2 driver need to start dealing with subclusters instead of clusters. qcow2_get_host_offset() is modified to return the subcluster type instead of the cluster type, and all callers are updated to replace all values of QCow2ClusterType with their QCow2SubclusterType equivalents. This patch only changes the data types, there are no semantic changes. Signed-off-by: Alberto Garcia Reviewed-by: Max Reitz Reviewed-by: Vladimir Sementsov-Ogievskiy --- block/qcow2.h | 2 +- block/qcow2-cluster.c | 10 +++---- block/qcow2.c | 70 ++++++++++++++++++++++--------------------- 3 files changed, 42 insertions(+), 40 deletions(-) diff --git a/block/qcow2.h b/block/qcow2.h index 74f65793bd..5df761edc3 100644 --- a/block/qcow2.h +++ b/block/qcow2.h @@ -894,7 +894,7 @@ int qcow2_encrypt_sectors(BDRVQcow2State *s, int64_t sector_num, int qcow2_get_host_offset(BlockDriverState *bs, uint64_t offset, unsigned int *bytes, uint64_t *host_offset, - QCow2ClusterType *cluster_type); + QCow2SubclusterType *subcluster_type); int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset, unsigned int *bytes, uint64_t *host_offset, QCowL2Meta **m); diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c index 1e5681b0c6..ed7b92dbb2 100644 --- a/block/qcow2-cluster.c +++ b/block/qcow2-cluster.c @@ -564,15 +564,15 @@ static int coroutine_fn do_perform_cow_write(BlockDriverState *bs, * offset that we are interested in. * * On exit, *bytes is the number of bytes starting at offset that have the same - * cluster type and (if applicable) are stored contiguously in the image file. - * The cluster type is stored in *cluster_type. - * Compressed clusters are always returned one by one. + * subcluster type and (if applicable) are stored contiguously in the image + * file. The subcluster type is stored in *subcluster_type. + * Compressed clusters are always processed one by one. * * Returns 0 on success, -errno in error cases. */ int qcow2_get_host_offset(BlockDriverState *bs, uint64_t offset, unsigned int *bytes, uint64_t *host_offset, - QCow2ClusterType *cluster_type) + QCow2SubclusterType *subcluster_type) { BDRVQcow2State *s = bs->opaque; unsigned int l2_index; @@ -713,7 +713,7 @@ out: assert(bytes_available - offset_in_cluster <= UINT_MAX); *bytes = bytes_available - offset_in_cluster; - *cluster_type = type; + *subcluster_type = qcow2_cluster_to_subcluster_type(type); return 0; diff --git a/block/qcow2.c b/block/qcow2.c index 89e17bdaba..2f7a2a7c7a 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -2033,7 +2033,7 @@ static int coroutine_fn qcow2_co_block_status(BlockDriverState *bs, BDRVQcow2State *s = bs->opaque; uint64_t host_offset; unsigned int bytes; - QCow2ClusterType type; + QCow2SubclusterType type; int ret, status = 0; qemu_co_mutex_lock(&s->lock); @@ -2053,15 +2053,16 @@ static int coroutine_fn qcow2_co_block_status(BlockDriverState *bs, *pnum = bytes; - if ((type == QCOW2_CLUSTER_NORMAL || type == QCOW2_CLUSTER_ZERO_ALLOC) && - !s->crypto) { + if ((type == QCOW2_SUBCLUSTER_NORMAL || + type == QCOW2_SUBCLUSTER_ZERO_ALLOC) && !s->crypto) { *map = host_offset; *file = s->data_file->bs; status |= BDRV_BLOCK_OFFSET_VALID; } - if (type == QCOW2_CLUSTER_ZERO_PLAIN || type == QCOW2_CLUSTER_ZERO_ALLOC) { + if (type == QCOW2_SUBCLUSTER_ZERO_PLAIN || + type == QCOW2_SUBCLUSTER_ZERO_ALLOC) { status |= BDRV_BLOCK_ZERO; - } else if (type != QCOW2_CLUSTER_UNALLOCATED) { + } else if (type != QCOW2_SUBCLUSTER_UNALLOCATED_PLAIN) { status |= BDRV_BLOCK_DATA; } if (s->metadata_preallocation && (status & BDRV_BLOCK_DATA) && @@ -2158,7 +2159,7 @@ typedef struct Qcow2AioTask { AioTask task; BlockDriverState *bs; - QCow2ClusterType cluster_type; /* only for read */ + QCow2SubclusterType subcluster_type; /* only for read */ uint64_t host_offset; /* or full descriptor in compressed clusters */ uint64_t offset; uint64_t bytes; @@ -2171,7 +2172,7 @@ static coroutine_fn int qcow2_co_preadv_task_entry(AioTask *task); static coroutine_fn int qcow2_add_task(BlockDriverState *bs, AioTaskPool *pool, AioTaskFunc func, - QCow2ClusterType cluster_type, + QCow2SubclusterType subcluster_type, uint64_t host_offset, uint64_t offset, uint64_t bytes, @@ -2185,7 +2186,7 @@ static coroutine_fn int qcow2_add_task(BlockDriverState *bs, *task = (Qcow2AioTask) { .task.func = func, .bs = bs, - .cluster_type = cluster_type, + .subcluster_type = subcluster_type, .qiov = qiov, .host_offset = host_offset, .offset = offset, @@ -2196,7 +2197,7 @@ static coroutine_fn int qcow2_add_task(BlockDriverState *bs, trace_qcow2_add_task(qemu_coroutine_self(), bs, pool, func == qcow2_co_preadv_task_entry ? "read" : "write", - cluster_type, host_offset, offset, bytes, + subcluster_type, host_offset, offset, bytes, qiov, qiov_offset); if (!pool) { @@ -2209,7 +2210,7 @@ static coroutine_fn int qcow2_add_task(BlockDriverState *bs, } static coroutine_fn int qcow2_co_preadv_task(BlockDriverState *bs, - QCow2ClusterType cluster_type, + QCow2SubclusterType subc_type, uint64_t host_offset, uint64_t offset, uint64_t bytes, QEMUIOVector *qiov, @@ -2217,24 +2218,24 @@ static coroutine_fn int qcow2_co_preadv_task(BlockDriverState *bs, { BDRVQcow2State *s = bs->opaque; - switch (cluster_type) { - case QCOW2_CLUSTER_ZERO_PLAIN: - case QCOW2_CLUSTER_ZERO_ALLOC: + switch (subc_type) { + case QCOW2_SUBCLUSTER_ZERO_PLAIN: + case QCOW2_SUBCLUSTER_ZERO_ALLOC: /* Both zero types are handled in qcow2_co_preadv_part */ g_assert_not_reached(); - case QCOW2_CLUSTER_UNALLOCATED: + case QCOW2_SUBCLUSTER_UNALLOCATED_PLAIN: assert(bs->backing); /* otherwise handled in qcow2_co_preadv_part */ BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING_AIO); return bdrv_co_preadv_part(bs->backing, offset, bytes, qiov, qiov_offset, 0); - case QCOW2_CLUSTER_COMPRESSED: + case QCOW2_SUBCLUSTER_COMPRESSED: return qcow2_co_preadv_compressed(bs, host_offset, offset, bytes, qiov, qiov_offset); - case QCOW2_CLUSTER_NORMAL: + case QCOW2_SUBCLUSTER_NORMAL: if (bs->encrypted) { return qcow2_co_preadv_encrypted(bs, host_offset, offset, bytes, qiov, qiov_offset); @@ -2257,8 +2258,9 @@ static coroutine_fn int qcow2_co_preadv_task_entry(AioTask *task) assert(!t->l2meta); - return qcow2_co_preadv_task(t->bs, t->cluster_type, t->host_offset, - t->offset, t->bytes, t->qiov, t->qiov_offset); + return qcow2_co_preadv_task(t->bs, t->subcluster_type, + t->host_offset, t->offset, t->bytes, + t->qiov, t->qiov_offset); } static coroutine_fn int qcow2_co_preadv_part(BlockDriverState *bs, @@ -2270,7 +2272,7 @@ static coroutine_fn int qcow2_co_preadv_part(BlockDriverState *bs, int ret = 0; unsigned int cur_bytes; /* number of bytes in current iteration */ uint64_t host_offset = 0; - QCow2ClusterType type; + QCow2SubclusterType type; AioTaskPool *aio = NULL; while (bytes != 0 && aio_task_pool_status(aio) == 0) { @@ -2289,9 +2291,9 @@ static coroutine_fn int qcow2_co_preadv_part(BlockDriverState *bs, goto out; } - if (type == QCOW2_CLUSTER_ZERO_PLAIN || - type == QCOW2_CLUSTER_ZERO_ALLOC || - (type == QCOW2_CLUSTER_UNALLOCATED && !bs->backing)) + if (type == QCOW2_SUBCLUSTER_ZERO_PLAIN || + type == QCOW2_SUBCLUSTER_ZERO_ALLOC || + (type == QCOW2_SUBCLUSTER_UNALLOCATED_PLAIN && !bs->backing)) { qemu_iovec_memset(qiov, qiov_offset, 0, cur_bytes); } else { @@ -2524,7 +2526,7 @@ static coroutine_fn int qcow2_co_pwritev_task_entry(AioTask *task) { Qcow2AioTask *t = container_of(task, Qcow2AioTask, task); - assert(!t->cluster_type); + assert(!t->subcluster_type); return qcow2_co_pwritev_task(t->bs, t->host_offset, t->offset, t->bytes, t->qiov, t->qiov_offset, @@ -3844,7 +3846,7 @@ static coroutine_fn int qcow2_co_pwrite_zeroes(BlockDriverState *bs, if (head || tail) { uint64_t off; unsigned int nr; - QCow2ClusterType type; + QCow2SubclusterType type; assert(head + bytes <= s->cluster_size); @@ -3862,9 +3864,9 @@ static coroutine_fn int qcow2_co_pwrite_zeroes(BlockDriverState *bs, nr = s->cluster_size; ret = qcow2_get_host_offset(bs, offset, &nr, &off, &type); if (ret < 0 || - (type != QCOW2_CLUSTER_UNALLOCATED && - type != QCOW2_CLUSTER_ZERO_PLAIN && - type != QCOW2_CLUSTER_ZERO_ALLOC)) { + (type != QCOW2_SUBCLUSTER_UNALLOCATED_PLAIN && + type != QCOW2_SUBCLUSTER_ZERO_PLAIN && + type != QCOW2_SUBCLUSTER_ZERO_ALLOC)) { qemu_co_mutex_unlock(&s->lock); return -ENOTSUP; } @@ -3928,7 +3930,7 @@ qcow2_co_copy_range_from(BlockDriverState *bs, while (bytes != 0) { uint64_t copy_offset = 0; - QCow2ClusterType type; + QCow2SubclusterType type; /* prepare next request */ cur_bytes = MIN(bytes, INT_MAX); cur_write_flags = write_flags; @@ -3940,7 +3942,7 @@ qcow2_co_copy_range_from(BlockDriverState *bs, } switch (type) { - case QCOW2_CLUSTER_UNALLOCATED: + case QCOW2_SUBCLUSTER_UNALLOCATED_PLAIN: if (bs->backing && bs->backing->bs) { int64_t backing_length = bdrv_getlength(bs->backing->bs); if (src_offset >= backing_length) { @@ -3955,16 +3957,16 @@ qcow2_co_copy_range_from(BlockDriverState *bs, } break; - case QCOW2_CLUSTER_ZERO_PLAIN: - case QCOW2_CLUSTER_ZERO_ALLOC: + case QCOW2_SUBCLUSTER_ZERO_PLAIN: + case QCOW2_SUBCLUSTER_ZERO_ALLOC: cur_write_flags |= BDRV_REQ_ZERO_WRITE; break; - case QCOW2_CLUSTER_COMPRESSED: + case QCOW2_SUBCLUSTER_COMPRESSED: ret = -ENOTSUP; goto out; - case QCOW2_CLUSTER_NORMAL: + case QCOW2_SUBCLUSTER_NORMAL: child = s->data_file; break; @@ -4493,7 +4495,7 @@ static coroutine_fn int qcow2_co_pwritev_compressed_task_entry(AioTask *task) { Qcow2AioTask *t = container_of(task, Qcow2AioTask, task); - assert(!t->cluster_type && !t->l2meta); + assert(!t->subcluster_type && !t->l2meta); return qcow2_co_pwritev_compressed_task(t->bs, t->offset, t->bytes, t->qiov, t->qiov_offset); From patchwork Sun Jun 28 11:02:28 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alberto Garcia X-Patchwork-Id: 279183 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 545E9C433DF for ; Sun, 28 Jun 2020 11:10:31 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 1E62A208C7 for ; Sun, 28 Jun 2020 11:10:31 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=igalia.com header.i=@igalia.com header.b="HYO1DwDW" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 1E62A208C7 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=igalia.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:37654 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jpVCg-00016a-Ad for qemu-devel@archiver.kernel.org; Sun, 28 Jun 2020 07:10:30 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:48474) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jpV6O-0007Oa-WD; Sun, 28 Jun 2020 07:04:01 -0400 Received: from fanzine.igalia.com ([178.60.130.6]:42339) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1jpV6J-0000X9-9t; Sun, 28 Jun 2020 07:04:00 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From; bh=JEa0mBV8UvnDyp5H8sfvCfcFuf5ZD0l+4WnlR2HdDiw=; b=HYO1DwDWI9/BcpLvCFhlw23z0zZghXW34SqvfsdoVmV3/2+go/ca9JyVl05IcE4WEMpAQOsEnsniEkYF4y+NmRXUgK/T2p3MH3Lw6ykYDqRoE8Hk2TPMuWYo4q1E41YTAGaNgh48+woQyISYQFgITgR9HeAtZ0GFlU8yZ5nUIC3AA4qYpKIW7QibpKQh3AtWHMBb/q1BHV3JBDQVEMNNNtMXJU9HByUOdAOFUKjcl1XYCpnKm5FPDUXVx02rRohQQGi6kzWegRKjZuT+9h7lmq61cmBRzUsqk7Hrp5oXlje5urHq1FawPRIR94XbmeWsUTJO/VhnJgJ3c1EB10iDnw==; Received: from 26.red-79-158-236.dynamicip.rima-tde.net ([79.158.236.26] helo=perseus.local) by fanzine.igalia.com with esmtpsa (Cipher TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim) id 1jpV5Y-0002gf-6Y; Sun, 28 Jun 2020 13:03:09 +0200 Received: from berto by perseus.local with local (Exim 4.92) (envelope-from ) id 1jpV5I-00038j-1N; Sun, 28 Jun 2020 13:02:52 +0200 From: Alberto Garcia To: qemu-devel@nongnu.org Subject: [PATCH v9 19/34] qcow2: Handle QCOW2_SUBCLUSTER_UNALLOCATED_ALLOC Date: Sun, 28 Jun 2020 13:02:28 +0200 Message-Id: <220b64fa73ba1ab4eb94f2a68cd4df79e5a5cdd8.1593342067.git.berto@igalia.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 Received-SPF: pass client-ip=178.60.130.6; envelope-from=berto@igalia.com; helo=fanzine.igalia.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/06/28 07:03:08 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x (no timestamps) [generic] [fuzzy] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , Alberto Garcia , qemu-block@nongnu.org, Derek Su , Max Reitz Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" When dealing with subcluster types there is a new value called QCOW2_SUBCLUSTER_UNALLOCATED_ALLOC that has no equivalent in QCow2ClusterType. This patch handles that value in all places where subcluster types are processed. Signed-off-by: Alberto Garcia Reviewed-by: Max Reitz Reviewed-by: Vladimir Sementsov-Ogievskiy --- block/qcow2.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/block/qcow2.c b/block/qcow2.c index 2f7a2a7c7a..a3481cd85b 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -2054,7 +2054,8 @@ static int coroutine_fn qcow2_co_block_status(BlockDriverState *bs, *pnum = bytes; if ((type == QCOW2_SUBCLUSTER_NORMAL || - type == QCOW2_SUBCLUSTER_ZERO_ALLOC) && !s->crypto) { + type == QCOW2_SUBCLUSTER_ZERO_ALLOC || + type == QCOW2_SUBCLUSTER_UNALLOCATED_ALLOC) && !s->crypto) { *map = host_offset; *file = s->data_file->bs; status |= BDRV_BLOCK_OFFSET_VALID; @@ -2062,7 +2063,8 @@ static int coroutine_fn qcow2_co_block_status(BlockDriverState *bs, if (type == QCOW2_SUBCLUSTER_ZERO_PLAIN || type == QCOW2_SUBCLUSTER_ZERO_ALLOC) { status |= BDRV_BLOCK_ZERO; - } else if (type != QCOW2_SUBCLUSTER_UNALLOCATED_PLAIN) { + } else if (type != QCOW2_SUBCLUSTER_UNALLOCATED_PLAIN && + type != QCOW2_SUBCLUSTER_UNALLOCATED_ALLOC) { status |= BDRV_BLOCK_DATA; } if (s->metadata_preallocation && (status & BDRV_BLOCK_DATA) && @@ -2225,6 +2227,7 @@ static coroutine_fn int qcow2_co_preadv_task(BlockDriverState *bs, g_assert_not_reached(); case QCOW2_SUBCLUSTER_UNALLOCATED_PLAIN: + case QCOW2_SUBCLUSTER_UNALLOCATED_ALLOC: assert(bs->backing); /* otherwise handled in qcow2_co_preadv_part */ BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING_AIO); @@ -2293,7 +2296,8 @@ static coroutine_fn int qcow2_co_preadv_part(BlockDriverState *bs, if (type == QCOW2_SUBCLUSTER_ZERO_PLAIN || type == QCOW2_SUBCLUSTER_ZERO_ALLOC || - (type == QCOW2_SUBCLUSTER_UNALLOCATED_PLAIN && !bs->backing)) + (type == QCOW2_SUBCLUSTER_UNALLOCATED_PLAIN && !bs->backing) || + (type == QCOW2_SUBCLUSTER_UNALLOCATED_ALLOC && !bs->backing)) { qemu_iovec_memset(qiov, qiov_offset, 0, cur_bytes); } else { @@ -3865,6 +3869,7 @@ static coroutine_fn int qcow2_co_pwrite_zeroes(BlockDriverState *bs, ret = qcow2_get_host_offset(bs, offset, &nr, &off, &type); if (ret < 0 || (type != QCOW2_SUBCLUSTER_UNALLOCATED_PLAIN && + type != QCOW2_SUBCLUSTER_UNALLOCATED_ALLOC && type != QCOW2_SUBCLUSTER_ZERO_PLAIN && type != QCOW2_SUBCLUSTER_ZERO_ALLOC)) { qemu_co_mutex_unlock(&s->lock); @@ -3943,6 +3948,7 @@ qcow2_co_copy_range_from(BlockDriverState *bs, switch (type) { case QCOW2_SUBCLUSTER_UNALLOCATED_PLAIN: + case QCOW2_SUBCLUSTER_UNALLOCATED_ALLOC: if (bs->backing && bs->backing->bs) { int64_t backing_length = bdrv_getlength(bs->backing->bs); if (src_offset >= backing_length) { From patchwork Sun Jun 28 11:02:30 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alberto Garcia X-Patchwork-Id: 279174 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9BE5FC433DF for ; Sun, 28 Jun 2020 11:24:43 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 56346206BE for ; Sun, 28 Jun 2020 11:24:43 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=igalia.com header.i=@igalia.com header.b="XpRvg4ou" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 56346206BE Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=igalia.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:53672 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jpVQQ-000387-JX for qemu-devel@archiver.kernel.org; Sun, 28 Jun 2020 07:24:42 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:48814) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jpV6Z-0007mP-8Z; Sun, 28 Jun 2020 07:04:11 -0400 Received: from fanzine.igalia.com ([178.60.130.6]:42419) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1jpV6M-0000XX-1c; Sun, 28 Jun 2020 07:04:10 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From; bh=HX/BNY9+fnF3/IdpMYeBixighVMLrzZ1bFMk4+G70IU=; b=XpRvg4ouG060uqdEQU4fnj3OZUa8ZSzUaRawCRqz3hFKxJAUGO4u1zXzmXKbv26HRXefXhRL8IBCftN35WPZ1ddKN2s/TFIrqkPZ3WMjbAe2trkzvch2suPKIdzPEsTE8ySDm0hv8L0SAG4G9Hjc6nXLrItFOYSP7wmHQ4aDtWH4m02i84p4pxZyPPSeINZUvfNM4MQlfBA5STeTEdw4cli0oQXoziIMQnaYFIR7nFkGXCi1ON3HvhGuWxf5tUMwSb0k9JEOUydynS6sEiLzKg3mk4rctHwQhXB+j/CFjcx09eI65SjlQUd2d55NSVkxvMaSDeJ0WPMqT9udmsiDwQ==; Received: from 26.red-79-158-236.dynamicip.rima-tde.net ([79.158.236.26] helo=perseus.local) by fanzine.igalia.com with esmtpsa (Cipher TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim) id 1jpV5Y-0002gk-7D; Sun, 28 Jun 2020 13:03:10 +0200 Received: from berto by perseus.local with local (Exim 4.92) (envelope-from ) id 1jpV5I-00038n-3M; Sun, 28 Jun 2020 13:02:52 +0200 From: Alberto Garcia To: qemu-devel@nongnu.org Subject: [PATCH v9 21/34] qcow2: Add subcluster support to qcow2_get_host_offset() Date: Sun, 28 Jun 2020 13:02:30 +0200 Message-Id: X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 Received-SPF: pass client-ip=178.60.130.6; envelope-from=berto@igalia.com; helo=fanzine.igalia.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/06/28 07:03:08 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x (no timestamps) [generic] [fuzzy] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , Alberto Garcia , qemu-block@nongnu.org, Derek Su , Max Reitz Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" The logic of this function remains pretty much the same, except that it uses count_contiguous_subclusters(), which combines the logic of count_contiguous_clusters() / count_contiguous_clusters_unallocated() and checks individual subclusters. qcow2_cluster_to_subcluster_type() is not necessary as a separate function anymore so it's inlined into its caller. Signed-off-by: Alberto Garcia Reviewed-by: Eric Blake --- block/qcow2.h | 38 ++++------- block/qcow2-cluster.c | 150 ++++++++++++++++++++++-------------------- 2 files changed, 92 insertions(+), 96 deletions(-) diff --git a/block/qcow2.h b/block/qcow2.h index 5df761edc3..4fad40b96b 100644 --- a/block/qcow2.h +++ b/block/qcow2.h @@ -710,29 +710,6 @@ static inline QCow2ClusterType qcow2_get_cluster_type(BlockDriverState *bs, } } -/* - * For an image without extended L2 entries, return the - * QCow2SubclusterType equivalent of a given QCow2ClusterType. - */ -static inline -QCow2SubclusterType qcow2_cluster_to_subcluster_type(QCow2ClusterType type) -{ - switch (type) { - case QCOW2_CLUSTER_COMPRESSED: - return QCOW2_SUBCLUSTER_COMPRESSED; - case QCOW2_CLUSTER_ZERO_PLAIN: - return QCOW2_SUBCLUSTER_ZERO_PLAIN; - case QCOW2_CLUSTER_ZERO_ALLOC: - return QCOW2_SUBCLUSTER_ZERO_ALLOC; - case QCOW2_CLUSTER_NORMAL: - return QCOW2_SUBCLUSTER_NORMAL; - case QCOW2_CLUSTER_UNALLOCATED: - return QCOW2_SUBCLUSTER_UNALLOCATED_PLAIN; - default: - g_assert_not_reached(); - } -} - /* * In an image without subsclusters @l2_bitmap is ignored and * @sc_index must be 0. @@ -776,7 +753,20 @@ QCow2SubclusterType qcow2_get_subcluster_type(BlockDriverState *bs, g_assert_not_reached(); } } else { - return qcow2_cluster_to_subcluster_type(type); + switch (type) { + case QCOW2_CLUSTER_COMPRESSED: + return QCOW2_SUBCLUSTER_COMPRESSED; + case QCOW2_CLUSTER_ZERO_PLAIN: + return QCOW2_SUBCLUSTER_ZERO_PLAIN; + case QCOW2_CLUSTER_ZERO_ALLOC: + return QCOW2_SUBCLUSTER_ZERO_ALLOC; + case QCOW2_CLUSTER_NORMAL: + return QCOW2_SUBCLUSTER_NORMAL; + case QCOW2_CLUSTER_UNALLOCATED: + return QCOW2_SUBCLUSTER_UNALLOCATED_PLAIN; + default: + g_assert_not_reached(); + } } } diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c index 59dd9bda29..2f3bd3a882 100644 --- a/block/qcow2-cluster.c +++ b/block/qcow2-cluster.c @@ -426,66 +426,66 @@ static int qcow2_get_subcluster_range_type(BlockDriverState *bs, } /* - * Checks how many clusters in a given L2 slice are contiguous in the image - * file. As soon as one of the flags in the bitmask stop_flags changes compared - * to the first cluster, the search is stopped and the cluster is not counted - * as contiguous. (This allows it, for example, to stop at the first compressed - * cluster which may require a different handling) + * Return the number of contiguous subclusters of the exact same type + * in a given L2 slice, starting from cluster @l2_index, subcluster + * @sc_index. Allocated subclusters are required to be contiguous in + * the image file. + * At most @nb_clusters are checked (note that this means clusters, + * not subclusters). + * Compressed clusters are always processed one by one but for the + * purpose of this count they are treated as if they were divided into + * subclusters of size s->subcluster_size. + * On failure return -errno and update @l2_index to point to the + * invalid entry. */ -static int count_contiguous_clusters(BlockDriverState *bs, int nb_clusters, - int cluster_size, uint64_t *l2_slice, int l2_index, uint64_t stop_flags) +static int count_contiguous_subclusters(BlockDriverState *bs, int nb_clusters, + unsigned sc_index, uint64_t *l2_slice, + unsigned *l2_index) { BDRVQcow2State *s = bs->opaque; - int i; - QCow2ClusterType first_cluster_type; - uint64_t mask = stop_flags | L2E_OFFSET_MASK | QCOW_OFLAG_COMPRESSED; - uint64_t first_entry = get_l2_entry(s, l2_slice, l2_index); - uint64_t offset = first_entry & mask; + int i, count = 0; + bool check_offset; + uint64_t expected_offset; + QCow2SubclusterType expected_type, type; - first_cluster_type = qcow2_get_cluster_type(bs, first_entry); - if (first_cluster_type == QCOW2_CLUSTER_UNALLOCATED) { - return 0; - } - - /* must be allocated */ - assert(first_cluster_type == QCOW2_CLUSTER_NORMAL || - first_cluster_type == QCOW2_CLUSTER_ZERO_ALLOC); + assert(*l2_index + nb_clusters <= s->l2_size); for (i = 0; i < nb_clusters; i++) { - uint64_t l2_entry = get_l2_entry(s, l2_slice, l2_index + i) & mask; - if (offset + (uint64_t) i * cluster_size != l2_entry) { + unsigned first_sc = (i == 0) ? sc_index : 0; + uint64_t l2_entry = get_l2_entry(s, l2_slice, *l2_index + i); + uint64_t l2_bitmap = get_l2_bitmap(s, l2_slice, *l2_index + i); + int ret = qcow2_get_subcluster_range_type(bs, l2_entry, l2_bitmap, + first_sc, &type); + if (ret < 0) { + *l2_index += i; /* Point to the invalid entry */ + return -EIO; + } + if (i == 0) { + if (type == QCOW2_SUBCLUSTER_COMPRESSED) { + /* Compressed clusters are always processed one by one */ + return ret; + } + expected_type = type; + expected_offset = l2_entry & L2E_OFFSET_MASK; + check_offset = (type == QCOW2_SUBCLUSTER_NORMAL || + type == QCOW2_SUBCLUSTER_ZERO_ALLOC || + type == QCOW2_SUBCLUSTER_UNALLOCATED_ALLOC); + } else if (type != expected_type) { break; + } else if (check_offset) { + expected_offset += s->cluster_size; + if (expected_offset != (l2_entry & L2E_OFFSET_MASK)) { + break; + } } - } - - return i; -} - -/* - * Checks how many consecutive unallocated clusters in a given L2 - * slice have the same cluster type. - */ -static int count_contiguous_clusters_unallocated(BlockDriverState *bs, - int nb_clusters, - uint64_t *l2_slice, - int l2_index, - QCow2ClusterType wanted_type) -{ - BDRVQcow2State *s = bs->opaque; - int i; - - assert(wanted_type == QCOW2_CLUSTER_ZERO_PLAIN || - wanted_type == QCOW2_CLUSTER_UNALLOCATED); - for (i = 0; i < nb_clusters; i++) { - uint64_t entry = get_l2_entry(s, l2_slice, l2_index + i); - QCow2ClusterType type = qcow2_get_cluster_type(bs, entry); - - if (type != wanted_type) { + count += ret; + /* Stop if there are type changes before the end of the cluster */ + if (first_sc + ret < s->subclusters_per_cluster) { break; } } - return i; + return count; } static int coroutine_fn do_perform_cow_read(BlockDriverState *bs, @@ -574,12 +574,12 @@ int qcow2_get_host_offset(BlockDriverState *bs, uint64_t offset, QCow2SubclusterType *subcluster_type) { BDRVQcow2State *s = bs->opaque; - unsigned int l2_index; - uint64_t l1_index, l2_offset, *l2_slice, l2_entry; - int c; + unsigned int l2_index, sc_index; + uint64_t l1_index, l2_offset, *l2_slice, l2_entry, l2_bitmap; + int sc; unsigned int offset_in_cluster; uint64_t bytes_available, bytes_needed, nb_clusters; - QCow2ClusterType type; + QCow2SubclusterType type; int ret; offset_in_cluster = offset_into_cluster(s, offset); @@ -600,13 +600,13 @@ int qcow2_get_host_offset(BlockDriverState *bs, uint64_t offset, l1_index = offset_to_l1_index(s, offset); if (l1_index >= s->l1_size) { - type = QCOW2_CLUSTER_UNALLOCATED; + type = QCOW2_SUBCLUSTER_UNALLOCATED_PLAIN; goto out; } l2_offset = s->l1_table[l1_index] & L1E_OFFSET_MASK; if (!l2_offset) { - type = QCOW2_CLUSTER_UNALLOCATED; + type = QCOW2_SUBCLUSTER_UNALLOCATED_PLAIN; goto out; } @@ -627,7 +627,9 @@ int qcow2_get_host_offset(BlockDriverState *bs, uint64_t offset, /* find the cluster offset for the given disk offset */ l2_index = offset_to_l2_slice_index(s, offset); + sc_index = offset_to_sc_index(s, offset); l2_entry = get_l2_entry(s, l2_slice, l2_index); + l2_bitmap = get_l2_bitmap(s, l2_slice, l2_index); nb_clusters = size_to_clusters(s, bytes_needed); /* bytes_needed <= *bytes + offset_in_cluster, both of which are unsigned @@ -635,9 +637,9 @@ int qcow2_get_host_offset(BlockDriverState *bs, uint64_t offset, * true */ assert(nb_clusters <= INT_MAX); - type = qcow2_get_cluster_type(bs, l2_entry); - if (s->qcow_version < 3 && (type == QCOW2_CLUSTER_ZERO_PLAIN || - type == QCOW2_CLUSTER_ZERO_ALLOC)) { + type = qcow2_get_subcluster_type(bs, l2_entry, l2_bitmap, sc_index); + if (s->qcow_version < 3 && (type == QCOW2_SUBCLUSTER_ZERO_PLAIN || + type == QCOW2_SUBCLUSTER_ZERO_ALLOC)) { qcow2_signal_corruption(bs, true, -1, -1, "Zero cluster entry found" " in pre-v3 image (L2 offset: %#" PRIx64 ", L2 index: %#x)", l2_offset, l2_index); @@ -645,7 +647,9 @@ int qcow2_get_host_offset(BlockDriverState *bs, uint64_t offset, goto fail; } switch (type) { - case QCOW2_CLUSTER_COMPRESSED: + case QCOW2_SUBCLUSTER_INVALID: + break; /* This is handled by count_contiguous_subclusters() below */ + case QCOW2_SUBCLUSTER_COMPRESSED: if (has_data_file(bs)) { qcow2_signal_corruption(bs, true, -1, -1, "Compressed cluster " "entry found in image with external data " @@ -654,24 +658,17 @@ int qcow2_get_host_offset(BlockDriverState *bs, uint64_t offset, ret = -EIO; goto fail; } - /* Compressed clusters can only be processed one by one */ - c = 1; *host_offset = l2_entry & L2E_COMPRESSED_OFFSET_SIZE_MASK; break; - case QCOW2_CLUSTER_ZERO_PLAIN: - case QCOW2_CLUSTER_UNALLOCATED: - /* how many empty clusters ? */ - c = count_contiguous_clusters_unallocated(bs, nb_clusters, - l2_slice, l2_index, type); + case QCOW2_SUBCLUSTER_ZERO_PLAIN: + case QCOW2_SUBCLUSTER_UNALLOCATED_PLAIN: *host_offset = 0; break; - case QCOW2_CLUSTER_ZERO_ALLOC: - case QCOW2_CLUSTER_NORMAL: { + case QCOW2_SUBCLUSTER_ZERO_ALLOC: + case QCOW2_SUBCLUSTER_NORMAL: + case QCOW2_SUBCLUSTER_UNALLOCATED_ALLOC: { uint64_t host_cluster_offset = l2_entry & L2E_OFFSET_MASK; *host_offset = host_cluster_offset + offset_in_cluster; - /* how many allocated clusters ? */ - c = count_contiguous_clusters(bs, nb_clusters, s->cluster_size, - l2_slice, l2_index, QCOW_OFLAG_ZERO); if (offset_into_cluster(s, host_cluster_offset)) { qcow2_signal_corruption(bs, true, -1, -1, "Cluster allocation offset %#" @@ -697,9 +694,18 @@ int qcow2_get_host_offset(BlockDriverState *bs, uint64_t offset, abort(); } + sc = count_contiguous_subclusters(bs, nb_clusters, sc_index, + l2_slice, &l2_index); + if (sc < 0) { + qcow2_signal_corruption(bs, true, -1, -1, "Invalid cluster entry found " + " (L2 offset: %#" PRIx64 ", L2 index: %#x)", + l2_offset, l2_index); + ret = -EIO; + goto fail; + } qcow2_cache_put(s->l2_table_cache, (void **) &l2_slice); - bytes_available = (int64_t)c * s->cluster_size; + bytes_available = ((int64_t)sc + sc_index) << s->subcluster_bits; out: if (bytes_available > bytes_needed) { @@ -712,7 +718,7 @@ out: assert(bytes_available - offset_in_cluster <= UINT_MAX); *bytes = bytes_available - offset_in_cluster; - *subcluster_type = qcow2_cluster_to_subcluster_type(type); + *subcluster_type = type; return 0; From patchwork Sun Jun 28 11:02:31 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alberto Garcia X-Patchwork-Id: 279178 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7ACECC433DF for ; Sun, 28 Jun 2020 11:16:05 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 4529720B80 for ; Sun, 28 Jun 2020 11:16:05 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=igalia.com header.i=@igalia.com header.b="WA4O9jQ7" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 4529720B80 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=igalia.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:33316 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jpVI4-0002k0-Co for qemu-devel@archiver.kernel.org; Sun, 28 Jun 2020 07:16:04 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:48458) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jpV6O-0007NF-HE; Sun, 28 Jun 2020 07:04:00 -0400 Received: from fanzine.igalia.com ([178.60.130.6]:42398) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1jpV6J-0000XR-U9; Sun, 28 Jun 2020 07:04:00 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From; bh=9sinAT98PUzgL4pBz7R1BbWSmbQmOO5Lnaa9e5wFELw=; b=WA4O9jQ7JPNVC2xRTTbdadG9QSxrpZ5HON01X7Bh8SL1kF2JhwxT2KZn+gXu5ttLpU207TMKbdiWFnJaUkaoCqloMfPR7UDG+KtG+84+wxlJnU46tDL+RvrMdiVuu02NKva8eZz8S8rIvRP22Vg9xiBeIdsPOqFwYHuyKGZF49av0T9gecPEBu/mvImemnV+ltCrVKaWHKdMAoEgsa+ZB8CwAv5EoIkfS09Mwc34JPUqEm75kp4hXru2mGUPRG5yhG/+zLmMIgRvIy2DgWQPazRcylIkgZO0k4H2SxVv5i5GByTjjmg0MPgCTdhK62g3von7OieFi9/yfGWrEin1jA==; Received: from 26.red-79-158-236.dynamicip.rima-tde.net ([79.158.236.26] helo=perseus.local) by fanzine.igalia.com with esmtpsa (Cipher TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim) id 1jpV5Y-0002gl-8y; Sun, 28 Jun 2020 13:03:09 +0200 Received: from berto by perseus.local with local (Exim 4.92) (envelope-from ) id 1jpV5I-00038v-4D; Sun, 28 Jun 2020 13:02:52 +0200 From: Alberto Garcia To: qemu-devel@nongnu.org Subject: [PATCH v9 22/34] qcow2: Add subcluster support to zero_in_l2_slice() Date: Sun, 28 Jun 2020 13:02:31 +0200 Message-Id: <7551704955c6ea570af4053fb86da5b3a33493c4.1593342067.git.berto@igalia.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 Received-SPF: pass client-ip=178.60.130.6; envelope-from=berto@igalia.com; helo=fanzine.igalia.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/06/28 07:03:08 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x (no timestamps) [generic] [fuzzy] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , Alberto Garcia , qemu-block@nongnu.org, Derek Su , Max Reitz Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" The QCOW_OFLAG_ZERO bit that indicates that a cluster reads as zeroes is only used in standard L2 entries. Extended L2 entries use individual 'all zeroes' bits for each subcluster. This must be taken into account when updating the L2 entry and also when deciding that an existing entry does not need to be updated. Signed-off-by: Alberto Garcia Reviewed-by: Eric Blake --- block/qcow2-cluster.c | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c index 2f3bd3a882..4e59bbd545 100644 --- a/block/qcow2-cluster.c +++ b/block/qcow2-cluster.c @@ -1956,7 +1956,6 @@ static int zero_in_l2_slice(BlockDriverState *bs, uint64_t offset, int l2_index; int ret; int i; - bool unmap = !!(flags & BDRV_REQ_MAY_UNMAP); ret = get_cluster_table(bs, offset, &l2_slice, &l2_index); if (ret < 0) { @@ -1968,28 +1967,31 @@ static int zero_in_l2_slice(BlockDriverState *bs, uint64_t offset, assert(nb_clusters <= INT_MAX); for (i = 0; i < nb_clusters; i++) { - uint64_t old_offset; - QCow2ClusterType cluster_type; + uint64_t old_l2_entry = get_l2_entry(s, l2_slice, l2_index + i); + uint64_t old_l2_bitmap = get_l2_bitmap(s, l2_slice, l2_index + i); + QCow2ClusterType type = qcow2_get_cluster_type(bs, old_l2_entry); + bool unmap = (type == QCOW2_CLUSTER_COMPRESSED) || + ((flags & BDRV_REQ_MAY_UNMAP) && qcow2_cluster_is_allocated(type)); + uint64_t new_l2_entry = unmap ? 0 : old_l2_entry; + uint64_t new_l2_bitmap = old_l2_bitmap; - old_offset = get_l2_entry(s, l2_slice, l2_index + i); + if (has_subclusters(s)) { + new_l2_bitmap = QCOW_L2_BITMAP_ALL_ZEROES; + } else { + new_l2_entry |= QCOW_OFLAG_ZERO; + } - /* - * Minimize L2 changes if the cluster already reads back as - * zeroes with correct allocation. - */ - cluster_type = qcow2_get_cluster_type(bs, old_offset); - if (cluster_type == QCOW2_CLUSTER_ZERO_PLAIN || - (cluster_type == QCOW2_CLUSTER_ZERO_ALLOC && !unmap)) { + if (old_l2_entry == new_l2_entry && old_l2_bitmap == new_l2_bitmap) { continue; } qcow2_cache_entry_mark_dirty(s->l2_table_cache, l2_slice); - if (cluster_type == QCOW2_CLUSTER_COMPRESSED || unmap) { - set_l2_entry(s, l2_slice, l2_index + i, QCOW_OFLAG_ZERO); - qcow2_free_any_clusters(bs, old_offset, 1, QCOW2_DISCARD_REQUEST); - } else { - uint64_t entry = get_l2_entry(s, l2_slice, l2_index + i); - set_l2_entry(s, l2_slice, l2_index + i, entry | QCOW_OFLAG_ZERO); + if (unmap) { + qcow2_free_any_clusters(bs, old_l2_entry, 1, QCOW2_DISCARD_REQUEST); + } + set_l2_entry(s, l2_slice, l2_index + i, new_l2_entry); + if (has_subclusters(s)) { + set_l2_bitmap(s, l2_slice, l2_index + i, new_l2_bitmap); } } From patchwork Sun Jun 28 11:02:32 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alberto Garcia X-Patchwork-Id: 279175 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A3F2BC433DF for ; Sun, 28 Jun 2020 11:21:00 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 6C41B206BE for ; Sun, 28 Jun 2020 11:21:00 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=igalia.com header.i=@igalia.com header.b="YvAyKF8U" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 6C41B206BE Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=igalia.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:46080 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jpVMp-00087d-Jc for qemu-devel@archiver.kernel.org; Sun, 28 Jun 2020 07:20:59 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:48748) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jpV6W-0007fY-BE; Sun, 28 Jun 2020 07:04:08 -0400 Received: from fanzine.igalia.com ([178.60.130.6]:42386) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1jpV6M-0000XP-1j; Sun, 28 Jun 2020 07:04:07 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From; bh=wwP+F61UHuBD2MYWJK+ZYjI142FX+Mf725oBfkWGky0=; b=YvAyKF8UG7g8uN7nAyM2EEFQVCviVEbvKc3BYVsTTrNu4r9Ks7wU6RkS24kaOzKj9YrFAC1akMqcFDVSUq0FpDyRrrM6+71puEFc7tstIXkQxdmWW+RKkWZp20gd049EML7jahQMHuKnOGNan9CQdc7gAUaOusQSAKH2maXqSRgd8a/N9UVOm1YrjgWmKry7OuUHTBCTH//kDyhTPqx58HBZOETDxZ4+vG8NzY4w6ehB9mxWMSFMzEZqsXFnSklWyeOYPdeWFo96X5yKjeVIzYCsNquO6TRJS3HgMc7eWZxUKCei1crwZIbhvmJCEG/E1wfq7a0rgu2JBMbz5ICopQ==; Received: from 26.red-79-158-236.dynamicip.rima-tde.net ([79.158.236.26] helo=perseus.local) by fanzine.igalia.com with esmtpsa (Cipher TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim) id 1jpV5Y-0002gm-5E; Sun, 28 Jun 2020 13:03:09 +0200 Received: from berto by perseus.local with local (Exim 4.92) (envelope-from ) id 1jpV5I-000390-5G; Sun, 28 Jun 2020 13:02:52 +0200 From: Alberto Garcia To: qemu-devel@nongnu.org Subject: [PATCH v9 23/34] qcow2: Add subcluster support to discard_in_l2_slice() Date: Sun, 28 Jun 2020 13:02:32 +0200 Message-Id: <42685fa7a479b996eca7c185acfebe09483331b3.1593342067.git.berto@igalia.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 Received-SPF: pass client-ip=178.60.130.6; envelope-from=berto@igalia.com; helo=fanzine.igalia.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/06/28 07:03:08 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x (no timestamps) [generic] [fuzzy] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , Alberto Garcia , qemu-block@nongnu.org, Derek Su , Max Reitz Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Two things need to be taken into account here: 1) With full_discard == true the L2 entry must be cleared completely. This also includes the L2 bitmap if the image has extended L2 entries. 2) With full_discard == false we have to make the discarded cluster read back as zeroes. With normal L2 entries this is done with the QCOW_OFLAG_ZERO bit, whereas with extended L2 entries this is done with the individual 'all zeroes' bits for each subcluster. Note however that QCOW_OFLAG_ZERO is not supported in v2 qcow2 images so, if there is a backing file, discard cannot guarantee that the image will read back as zeroes. If this is important for the caller it should forbid it as qcow2_co_pdiscard() does (see 80f5c01183 for more details). Signed-off-by: Alberto Garcia Reviewed-by: Eric Blake --- block/qcow2-cluster.c | 52 +++++++++++++++++++------------------------ 1 file changed, 23 insertions(+), 29 deletions(-) diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c index 4e59bbd545..edfc8ea91c 100644 --- a/block/qcow2-cluster.c +++ b/block/qcow2-cluster.c @@ -1847,11 +1847,17 @@ static int discard_in_l2_slice(BlockDriverState *bs, uint64_t offset, assert(nb_clusters <= INT_MAX); for (i = 0; i < nb_clusters; i++) { - uint64_t old_l2_entry; - - old_l2_entry = get_l2_entry(s, l2_slice, l2_index + i); + uint64_t old_l2_entry = get_l2_entry(s, l2_slice, l2_index + i); + uint64_t old_l2_bitmap = get_l2_bitmap(s, l2_slice, l2_index + i); + uint64_t new_l2_entry = old_l2_entry; + uint64_t new_l2_bitmap = old_l2_bitmap; + QCow2ClusterType cluster_type = + qcow2_get_cluster_type(bs, old_l2_entry); /* + * If full_discard is true, the cluster should not read back as zeroes, + * but rather fall through to the backing file. + * * If full_discard is false, make sure that a discarded area reads back * as zeroes for v3 images (we cannot do it for v2 without actually * writing a zero-filled buffer). We can skip the operation if the @@ -1860,40 +1866,28 @@ static int discard_in_l2_slice(BlockDriverState *bs, uint64_t offset, * * TODO We might want to use bdrv_block_status(bs) here, but we're * holding s->lock, so that doesn't work today. - * - * If full_discard is true, the sector should not read back as zeroes, - * but rather fall through to the backing file. */ - switch (qcow2_get_cluster_type(bs, old_l2_entry)) { - case QCOW2_CLUSTER_UNALLOCATED: - if (full_discard || !bs->backing) { - continue; + if (full_discard) { + new_l2_entry = new_l2_bitmap = 0; + } else if (bs->backing || qcow2_cluster_is_allocated(cluster_type)) { + if (has_subclusters(s)) { + new_l2_entry = 0; + new_l2_bitmap = QCOW_L2_BITMAP_ALL_ZEROES; + } else { + new_l2_entry = s->qcow_version >= 3 ? QCOW_OFLAG_ZERO : 0; } - break; + } - case QCOW2_CLUSTER_ZERO_PLAIN: - if (!full_discard) { - continue; - } - break; - - case QCOW2_CLUSTER_ZERO_ALLOC: - case QCOW2_CLUSTER_NORMAL: - case QCOW2_CLUSTER_COMPRESSED: - break; - - default: - abort(); + if (old_l2_entry == new_l2_entry && old_l2_bitmap == new_l2_bitmap) { + continue; } /* First remove L2 entries */ qcow2_cache_entry_mark_dirty(s->l2_table_cache, l2_slice); - if (!full_discard && s->qcow_version >= 3) { - set_l2_entry(s, l2_slice, l2_index + i, QCOW_OFLAG_ZERO); - } else { - set_l2_entry(s, l2_slice, l2_index + i, 0); + set_l2_entry(s, l2_slice, l2_index + i, new_l2_entry); + if (has_subclusters(s)) { + set_l2_bitmap(s, l2_slice, l2_index + i, new_l2_bitmap); } - /* Then decrease the refcount */ qcow2_free_any_clusters(bs, old_l2_entry, 1, type); } From patchwork Sun Jun 28 11:02:40 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alberto Garcia X-Patchwork-Id: 279171 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 993F5C433DF for ; Sun, 28 Jun 2020 11:32:07 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id F299220720 for ; Sun, 28 Jun 2020 11:32:06 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=igalia.com header.i=@igalia.com header.b="aS+TogjE" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org F299220720 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=igalia.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:41410 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jpVXa-0001pF-71 for qemu-devel@archiver.kernel.org; Sun, 28 Jun 2020 07:32:06 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:48956) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jpV6e-0007wQ-0C; Sun, 28 Jun 2020 07:04:16 -0400 Received: from fanzine.igalia.com ([178.60.130.6]:42511) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1jpV6M-0000YV-1e; Sun, 28 Jun 2020 07:04:15 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From; bh=x7Vglv2JsP8bv8+DFdHp9enj76xs/MQ0sDjW2GxCI+w=; b=aS+TogjESW1oQyof3uHBb26CJk6IddDsevexxtYYuHuJL/CUG6WojUMRRV20EvHcirERtCVgH+1AQtrb5un6o33Xej0DCzy89WN0v88XfEHz/8sgHxFrF6Ctytu7TJQTYfIChjsvo3Lw8In9T3zntq36DXr3DpCXWidFH2ILYFL9eIHj/czZksoqmZsQ8WYVVxIK/0uzVU6+k97gQ2XmtoKD4YnezoRC/5hWdX1qqqPzkE8UgMKxx/DAbbNOHO9IhwbZWIw7GMzhGT62ib20nF1X+YSbvLUGkuJbGlKrUHScROEW1BjRbnhOZ6UxkUiPGt8ARjQpZg1hR+cLkHVvAg==; Received: from 26.red-79-158-236.dynamicip.rima-tde.net ([79.158.236.26] helo=perseus.local) by fanzine.igalia.com with esmtpsa (Cipher TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim) id 1jpV5Y-0002gu-Fe; Sun, 28 Jun 2020 13:03:12 +0200 Received: from berto by perseus.local with local (Exim 4.92) (envelope-from ) id 1jpV5I-00039y-DV; Sun, 28 Jun 2020 13:02:52 +0200 From: Alberto Garcia To: qemu-devel@nongnu.org Subject: [PATCH v9 31/34] qcow2: Add the 'extended_l2' option and the QCOW2_INCOMPAT_EXTL2 bit Date: Sun, 28 Jun 2020 13:02:40 +0200 Message-Id: X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 Received-SPF: pass client-ip=178.60.130.6; envelope-from=berto@igalia.com; helo=fanzine.igalia.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/06/28 07:03:08 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x (no timestamps) [generic] [fuzzy] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , Alberto Garcia , qemu-block@nongnu.org, Derek Su , Max Reitz Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Now that the implementation of subclusters is complete we can finally add the necessary options to create and read images with this feature, which we call "extended L2 entries". Signed-off-by: Alberto Garcia Reviewed-by: Eric Blake --- qapi/block-core.json | 7 +++ block/qcow2.h | 8 ++- include/block/block_int.h | 1 + block/qcow2.c | 74 ++++++++++++++++++++-- tests/qemu-iotests/031.out | 8 +-- tests/qemu-iotests/036.out | 4 +- tests/qemu-iotests/049.out | 102 +++++++++++++++---------------- tests/qemu-iotests/060.out | 1 + tests/qemu-iotests/061.out | 20 +++--- tests/qemu-iotests/065 | 12 ++-- tests/qemu-iotests/082.out | 48 ++++++++++++--- tests/qemu-iotests/085.out | 38 ++++++------ tests/qemu-iotests/144.out | 4 +- tests/qemu-iotests/182.out | 2 +- tests/qemu-iotests/185.out | 8 +-- tests/qemu-iotests/198.out | 2 + tests/qemu-iotests/206.out | 4 ++ tests/qemu-iotests/242.out | 5 ++ tests/qemu-iotests/255.out | 8 +-- tests/qemu-iotests/274.out | 49 ++++++++------- tests/qemu-iotests/280.out | 2 +- tests/qemu-iotests/291.out | 6 +- tests/qemu-iotests/common.filter | 1 + 23 files changed, 272 insertions(+), 142 deletions(-) diff --git a/qapi/block-core.json b/qapi/block-core.json index 0e1c6a59f2..24e002ebae 100644 --- a/qapi/block-core.json +++ b/qapi/block-core.json @@ -66,6 +66,9 @@ # standalone (read-only) raw image without looking at qcow2 # metadata (since: 4.0) # +# @extended-l2: true if the image has extended L2 entries; only valid for +# compat >= 1.1 (since 5.1) +# # @lazy-refcounts: on or off; only valid for compat >= 1.1 # # @corrupt: true if the image has been marked corrupt; only valid for @@ -87,6 +90,7 @@ 'compat': 'str', '*data-file': 'str', '*data-file-raw': 'bool', + '*extended-l2': 'bool', '*lazy-refcounts': 'bool', '*corrupt': 'bool', 'refcount-bits': 'int', @@ -4318,6 +4322,8 @@ # @data-file-raw: True if the external data file must stay valid as a # standalone (read-only) raw image without looking at qcow2 # metadata (default: false; since: 4.0) +# @extended-l2 True to make the image have extended L2 entries +# (default: false; since 5.1) # @size: Size of the virtual disk in bytes # @version: Compatibility level (default: v3) # @backing-file: File name of the backing file if a backing file @@ -4338,6 +4344,7 @@ 'data': { 'file': 'BlockdevRef', '*data-file': 'BlockdevRef', '*data-file-raw': 'bool', + '*extended-l2': 'bool', 'size': 'size', '*version': 'BlockdevQcow2Version', '*backing-file': 'str', diff --git a/block/qcow2.h b/block/qcow2.h index f3499e53bf..065ec3df0b 100644 --- a/block/qcow2.h +++ b/block/qcow2.h @@ -246,15 +246,18 @@ enum { QCOW2_INCOMPAT_CORRUPT_BITNR = 1, QCOW2_INCOMPAT_DATA_FILE_BITNR = 2, QCOW2_INCOMPAT_COMPRESSION_BITNR = 3, + QCOW2_INCOMPAT_EXTL2_BITNR = 4, QCOW2_INCOMPAT_DIRTY = 1 << QCOW2_INCOMPAT_DIRTY_BITNR, QCOW2_INCOMPAT_CORRUPT = 1 << QCOW2_INCOMPAT_CORRUPT_BITNR, QCOW2_INCOMPAT_DATA_FILE = 1 << QCOW2_INCOMPAT_DATA_FILE_BITNR, QCOW2_INCOMPAT_COMPRESSION = 1 << QCOW2_INCOMPAT_COMPRESSION_BITNR, + QCOW2_INCOMPAT_EXTL2 = 1 << QCOW2_INCOMPAT_EXTL2_BITNR, QCOW2_INCOMPAT_MASK = QCOW2_INCOMPAT_DIRTY | QCOW2_INCOMPAT_CORRUPT | QCOW2_INCOMPAT_DATA_FILE - | QCOW2_INCOMPAT_COMPRESSION, + | QCOW2_INCOMPAT_COMPRESSION + | QCOW2_INCOMPAT_EXTL2, }; /* Compatible feature bits */ @@ -581,8 +584,7 @@ typedef enum QCow2MetadataOverlap { static inline bool has_subclusters(BDRVQcow2State *s) { - /* FIXME: Return false until this feature is complete */ - return false; + return s->incompatible_features & QCOW2_INCOMPAT_EXTL2; } static inline size_t l2_entry_size(BDRVQcow2State *s) diff --git a/include/block/block_int.h b/include/block/block_int.h index 791de6a59c..36e1993788 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -58,6 +58,7 @@ #define BLOCK_OPT_DATA_FILE "data_file" #define BLOCK_OPT_DATA_FILE_RAW "data_file_raw" #define BLOCK_OPT_COMPRESSION_TYPE "compression_type" +#define BLOCK_OPT_EXTL2 "extended_l2" #define BLOCK_PROBE_BUF_SIZE 512 diff --git a/block/qcow2.c b/block/qcow2.c index 003f166024..37bfae823c 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -1438,6 +1438,12 @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options, s->subcluster_size = s->cluster_size / s->subclusters_per_cluster; s->subcluster_bits = ctz32(s->subcluster_size); + if (s->subcluster_size < (1 << MIN_CLUSTER_BITS)) { + error_setg(errp, "Unsupported subcluster size: %d", s->subcluster_size); + ret = -EINVAL; + goto fail; + } + /* Check support for various header values */ if (header.refcount_order > 6) { error_setg(errp, "Reference count entry width too large; may not " @@ -2924,6 +2930,11 @@ int qcow2_update_header(BlockDriverState *bs) .bit = QCOW2_INCOMPAT_COMPRESSION_BITNR, .name = "compression type", }, + { + .type = QCOW2_FEAT_TYPE_INCOMPATIBLE, + .bit = QCOW2_INCOMPAT_EXTL2_BITNR, + .name = "extended L2 entries", + }, { .type = QCOW2_FEAT_TYPE_COMPATIBLE, .bit = QCOW2_COMPAT_LAZY_REFCOUNTS_BITNR, @@ -3271,7 +3282,8 @@ static int64_t qcow2_calc_prealloc_size(int64_t total_size, return meta_size + aligned_total_size; } -static bool validate_cluster_size(size_t cluster_size, Error **errp) +static bool validate_cluster_size(size_t cluster_size, bool extended_l2, + Error **errp) { int cluster_bits = ctz32(cluster_size); if (cluster_bits < MIN_CLUSTER_BITS || cluster_bits > MAX_CLUSTER_BITS || @@ -3281,16 +3293,28 @@ static bool validate_cluster_size(size_t cluster_size, Error **errp) "%dk", 1 << MIN_CLUSTER_BITS, 1 << (MAX_CLUSTER_BITS - 10)); return false; } + + if (extended_l2) { + unsigned min_cluster_size = + (1 << MIN_CLUSTER_BITS) * QCOW_EXTL2_SUBCLUSTERS_PER_CLUSTER; + if (cluster_size < min_cluster_size) { + error_setg(errp, "Extended L2 entries are only supported with " + "cluster sizes of at least %u bytes", min_cluster_size); + return false; + } + } + return true; } -static size_t qcow2_opt_get_cluster_size_del(QemuOpts *opts, Error **errp) +static size_t qcow2_opt_get_cluster_size_del(QemuOpts *opts, bool extended_l2, + Error **errp) { size_t cluster_size; cluster_size = qemu_opt_get_size_del(opts, BLOCK_OPT_CLUSTER_SIZE, DEFAULT_CLUSTER_SIZE); - if (!validate_cluster_size(cluster_size, errp)) { + if (!validate_cluster_size(cluster_size, extended_l2, errp)) { return 0; } return cluster_size; @@ -3405,7 +3429,20 @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp) cluster_size = DEFAULT_CLUSTER_SIZE; } - if (!validate_cluster_size(cluster_size, errp)) { + if (!qcow2_opts->has_extended_l2) { + qcow2_opts->extended_l2 = false; + } + if (qcow2_opts->extended_l2) { + if (version < 3) { + error_setg(errp, "Extended L2 entries are only supported with " + "compatibility level 1.1 and above (use version=v3 or " + "greater)"); + ret = -EINVAL; + goto out; + } + } + + if (!validate_cluster_size(cluster_size, qcow2_opts->extended_l2, errp)) { ret = -EINVAL; goto out; } @@ -3556,6 +3593,11 @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp) cpu_to_be64(QCOW2_INCOMPAT_COMPRESSION); } + if (qcow2_opts->extended_l2) { + header->incompatible_features |= + cpu_to_be64(QCOW2_INCOMPAT_EXTL2); + } + ret = blk_pwrite(blk, 0, header, cluster_size, 0); g_free(header); if (ret < 0) { @@ -3736,6 +3778,7 @@ static int coroutine_fn qcow2_co_create_opts(BlockDriver *drv, { BLOCK_OPT_BACKING_FMT, "backing-fmt" }, { BLOCK_OPT_CLUSTER_SIZE, "cluster-size" }, { BLOCK_OPT_LAZY_REFCOUNTS, "lazy-refcounts" }, + { BLOCK_OPT_EXTL2, "extended-l2" }, { BLOCK_OPT_REFCOUNT_BITS, "refcount-bits" }, { BLOCK_OPT_ENCRYPT, BLOCK_OPT_ENCRYPT_FORMAT }, { BLOCK_OPT_COMPAT_LEVEL, "version" }, @@ -4854,11 +4897,14 @@ static BlockMeasureInfo *qcow2_measure(QemuOpts *opts, BlockDriverState *in_bs, PreallocMode prealloc; bool has_backing_file; bool has_luks; - bool extended_l2 = false; /* Set to false until the option is added */ + bool extended_l2; size_t l2e_size; /* Parse image creation options */ - cluster_size = qcow2_opt_get_cluster_size_del(opts, &local_err); + extended_l2 = qemu_opt_get_bool_del(opts, BLOCK_OPT_EXTL2, false); + + cluster_size = qcow2_opt_get_cluster_size_del(opts, extended_l2, + &local_err); if (local_err) { goto err; } @@ -5062,6 +5108,8 @@ static ImageInfoSpecific *qcow2_get_specific_info(BlockDriverState *bs, .corrupt = s->incompatible_features & QCOW2_INCOMPAT_CORRUPT, .has_corrupt = true, + .has_extended_l2 = true, + .extended_l2 = has_subclusters(s), .refcount_bits = s->refcount_bits, .has_bitmaps = !!bitmaps, .bitmaps = bitmaps, @@ -5491,6 +5539,14 @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts, "is not supported"); return -ENOTSUP; } + } else if (!strcmp(desc->name, BLOCK_OPT_EXTL2)) { + bool extended_l2 = qemu_opt_get_bool(opts, BLOCK_OPT_EXTL2, + has_subclusters(s)); + if (extended_l2 != has_subclusters(s)) { + error_setg(errp, "Toggling extended L2 entries " + "is not supported"); + return -EINVAL; + } } else { /* if this point is reached, this probably means a new option was * added without having it covered here */ @@ -5751,6 +5807,12 @@ static QemuOptsList qcow2_create_opts = { .help = "Postpone refcount updates", .def_value_str = "off" }, + { + .name = BLOCK_OPT_EXTL2, + .type = QEMU_OPT_BOOL, + .help = "Extended L2 tables", + .def_value_str = "off" + }, { .name = BLOCK_OPT_REFCOUNT_BITS, .type = QEMU_OPT_NUMBER, diff --git a/tests/qemu-iotests/031.out b/tests/qemu-iotests/031.out index 4b21d6a9ba..0054c2ed97 100644 --- a/tests/qemu-iotests/031.out +++ b/tests/qemu-iotests/031.out @@ -117,7 +117,7 @@ header_length 112 Header extension: magic 0x6803f857 (Feature table) -length 336 +length 384 data Header extension: @@ -150,7 +150,7 @@ header_length 112 Header extension: magic 0x6803f857 (Feature table) -length 336 +length 384 data Header extension: @@ -164,7 +164,7 @@ No errors were found on the image. magic 0x514649fb version 3 -backing_file_offset 0x210 +backing_file_offset 0x240 backing_file_size 0x17 cluster_bits 16 size 67108864 @@ -188,7 +188,7 @@ data 'host_device' Header extension: magic 0x6803f857 (Feature table) -length 336 +length 384 data Header extension: diff --git a/tests/qemu-iotests/036.out b/tests/qemu-iotests/036.out index a9bed828e5..1fa7cad28d 100644 --- a/tests/qemu-iotests/036.out +++ b/tests/qemu-iotests/036.out @@ -26,7 +26,7 @@ compatible_features [] autoclear_features [63] Header extension: magic 0x6803f857 (Feature table) -length 336 +length 384 data @@ -38,7 +38,7 @@ compatible_features [] autoclear_features [] Header extension: magic 0x6803f857 (Feature table) -length 336 +length 384 data *** done diff --git a/tests/qemu-iotests/049.out b/tests/qemu-iotests/049.out index c54ae21b86..c8356be551 100644 --- a/tests/qemu-iotests/049.out +++ b/tests/qemu-iotests/049.out @@ -4,90 +4,90 @@ QA output created by 049 == 1. Traditional size parameter == qemu-img create -f qcow2 TEST_DIR/t.qcow2 1024 -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib qemu-img create -f qcow2 TEST_DIR/t.qcow2 1024b -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib qemu-img create -f qcow2 TEST_DIR/t.qcow2 1k -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib qemu-img create -f qcow2 TEST_DIR/t.qcow2 1K -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib qemu-img create -f qcow2 TEST_DIR/t.qcow2 1M -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1048576 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1048576 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib qemu-img create -f qcow2 TEST_DIR/t.qcow2 1G -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1073741824 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1073741824 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib qemu-img create -f qcow2 TEST_DIR/t.qcow2 1T -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1099511627776 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1099511627776 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib qemu-img create -f qcow2 TEST_DIR/t.qcow2 1024.0 -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib qemu-img create -f qcow2 TEST_DIR/t.qcow2 1024.0b -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib qemu-img create -f qcow2 TEST_DIR/t.qcow2 1.5k -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1536 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1536 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib qemu-img create -f qcow2 TEST_DIR/t.qcow2 1.5K -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1536 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1536 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib qemu-img create -f qcow2 TEST_DIR/t.qcow2 1.5M -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1572864 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1572864 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib qemu-img create -f qcow2 TEST_DIR/t.qcow2 1.5G -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1610612736 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1610612736 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib qemu-img create -f qcow2 TEST_DIR/t.qcow2 1.5T -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1649267441664 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1649267441664 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib == 2. Specifying size via -o == qemu-img create -f qcow2 -o size=1024 TEST_DIR/t.qcow2 -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib qemu-img create -f qcow2 -o size=1024b TEST_DIR/t.qcow2 -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib qemu-img create -f qcow2 -o size=1k TEST_DIR/t.qcow2 -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib qemu-img create -f qcow2 -o size=1K TEST_DIR/t.qcow2 -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib qemu-img create -f qcow2 -o size=1M TEST_DIR/t.qcow2 -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1048576 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1048576 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib qemu-img create -f qcow2 -o size=1G TEST_DIR/t.qcow2 -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1073741824 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1073741824 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib qemu-img create -f qcow2 -o size=1T TEST_DIR/t.qcow2 -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1099511627776 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1099511627776 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib qemu-img create -f qcow2 -o size=1024.0 TEST_DIR/t.qcow2 -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib qemu-img create -f qcow2 -o size=1024.0b TEST_DIR/t.qcow2 -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1024 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib qemu-img create -f qcow2 -o size=1.5k TEST_DIR/t.qcow2 -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1536 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1536 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib qemu-img create -f qcow2 -o size=1.5K TEST_DIR/t.qcow2 -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1536 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1536 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib qemu-img create -f qcow2 -o size=1.5M TEST_DIR/t.qcow2 -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1572864 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1572864 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib qemu-img create -f qcow2 -o size=1.5G TEST_DIR/t.qcow2 -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1610612736 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1610612736 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib qemu-img create -f qcow2 -o size=1.5T TEST_DIR/t.qcow2 -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1649267441664 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=1649267441664 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib == 3. Invalid sizes == @@ -129,84 +129,84 @@ qemu-img: TEST_DIR/t.qcow2: The image size must be specified only once == Check correct interpretation of suffixes for cluster size == qemu-img create -f qcow2 -o cluster_size=1024 TEST_DIR/t.qcow2 64M -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=1024 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=1024 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib qemu-img create -f qcow2 -o cluster_size=1024b TEST_DIR/t.qcow2 64M -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=1024 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=1024 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib qemu-img create -f qcow2 -o cluster_size=1k TEST_DIR/t.qcow2 64M -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=1024 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=1024 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib qemu-img create -f qcow2 -o cluster_size=1K TEST_DIR/t.qcow2 64M -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=1024 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=1024 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib qemu-img create -f qcow2 -o cluster_size=1M TEST_DIR/t.qcow2 64M -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=1048576 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=1048576 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib qemu-img create -f qcow2 -o cluster_size=1024.0 TEST_DIR/t.qcow2 64M -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=1024 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=1024 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib qemu-img create -f qcow2 -o cluster_size=1024.0b TEST_DIR/t.qcow2 64M -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=1024 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=1024 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib qemu-img create -f qcow2 -o cluster_size=0.5k TEST_DIR/t.qcow2 64M -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=512 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=512 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib qemu-img create -f qcow2 -o cluster_size=0.5K TEST_DIR/t.qcow2 64M -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=512 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=512 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib qemu-img create -f qcow2 -o cluster_size=0.5M TEST_DIR/t.qcow2 64M -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=524288 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=524288 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib == Check compat level option == qemu-img create -f qcow2 -o compat=0.10 TEST_DIR/t.qcow2 64M -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=0.10 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=0.10 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib qemu-img create -f qcow2 -o compat=1.1 TEST_DIR/t.qcow2 64M -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=1.1 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=1.1 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib qemu-img create -f qcow2 -o compat=0.42 TEST_DIR/t.qcow2 64M qemu-img: TEST_DIR/t.qcow2: Invalid parameter '0.42' -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=0.42 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=0.42 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib qemu-img create -f qcow2 -o compat=foobar TEST_DIR/t.qcow2 64M qemu-img: TEST_DIR/t.qcow2: Invalid parameter 'foobar' -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=foobar cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=foobar cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib == Check preallocation option == qemu-img create -f qcow2 -o preallocation=off TEST_DIR/t.qcow2 64M -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=65536 preallocation=off lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=65536 preallocation=off lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib qemu-img create -f qcow2 -o preallocation=metadata TEST_DIR/t.qcow2 64M -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=65536 preallocation=metadata lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=65536 preallocation=metadata lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib qemu-img create -f qcow2 -o preallocation=1234 TEST_DIR/t.qcow2 64M qemu-img: TEST_DIR/t.qcow2: Invalid parameter '1234' -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=65536 preallocation=1234 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 cluster_size=65536 preallocation=1234 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib == Check encryption option == qemu-img create -f qcow2 -o encryption=off TEST_DIR/t.qcow2 64M -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib qemu-img create -f qcow2 --object secret,id=sec0,data=123456 -o encryption=on,encrypt.key-secret=sec0 TEST_DIR/t.qcow2 64M -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=on encrypt.key-secret=sec0 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 encryption=on encrypt.key-secret=sec0 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib == Check lazy_refcounts option (only with v3) == qemu-img create -f qcow2 -o compat=1.1,lazy_refcounts=off TEST_DIR/t.qcow2 64M -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=1.1 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=1.1 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib qemu-img create -f qcow2 -o compat=1.1,lazy_refcounts=on TEST_DIR/t.qcow2 64M -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=1.1 cluster_size=65536 lazy_refcounts=on refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=1.1 cluster_size=65536 lazy_refcounts=on extended_l2=off refcount_bits=16 compression_type=zlib qemu-img create -f qcow2 -o compat=0.10,lazy_refcounts=off TEST_DIR/t.qcow2 64M -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=0.10 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=0.10 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib qemu-img create -f qcow2 -o compat=0.10,lazy_refcounts=on TEST_DIR/t.qcow2 64M qemu-img: TEST_DIR/t.qcow2: Lazy refcounts only supported with compatibility level 1.1 and above (use version=v3 or greater) -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=0.10 cluster_size=65536 lazy_refcounts=on refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 compat=0.10 cluster_size=65536 lazy_refcounts=on extended_l2=off refcount_bits=16 compression_type=zlib *** done diff --git a/tests/qemu-iotests/060.out b/tests/qemu-iotests/060.out index fa3d68f0df..bb98fa5db8 100644 --- a/tests/qemu-iotests/060.out +++ b/tests/qemu-iotests/060.out @@ -21,6 +21,7 @@ Format specific information: lazy refcounts: false refcount bits: 16 corrupt: true + extended l2: false qemu-io: can't open device TEST_DIR/t.IMGFMT: IMGFMT: Image is corrupt; cannot be opened read/write no file open, try 'help open' read 512/512 bytes at offset 0 diff --git a/tests/qemu-iotests/061.out b/tests/qemu-iotests/061.out index 2f03cf045c..f618259d47 100644 --- a/tests/qemu-iotests/061.out +++ b/tests/qemu-iotests/061.out @@ -26,7 +26,7 @@ header_length 112 Header extension: magic 0x6803f857 (Feature table) -length 336 +length 384 data magic 0x514649fb @@ -84,7 +84,7 @@ header_length 112 Header extension: magic 0x6803f857 (Feature table) -length 336 +length 384 data magic 0x514649fb @@ -140,7 +140,7 @@ header_length 112 Header extension: magic 0x6803f857 (Feature table) -length 336 +length 384 data ERROR cluster 5 refcount=0 reference=1 @@ -195,7 +195,7 @@ header_length 112 Header extension: magic 0x6803f857 (Feature table) -length 336 +length 384 data magic 0x514649fb @@ -264,7 +264,7 @@ header_length 112 Header extension: magic 0x6803f857 (Feature table) -length 336 +length 384 data read 65536/65536 bytes at offset 44040192 @@ -326,7 +326,7 @@ header_length 112 Header extension: magic 0x6803f857 (Feature table) -length 336 +length 384 data ERROR cluster 5 refcount=0 reference=1 @@ -355,7 +355,7 @@ header_length 112 Header extension: magic 0x6803f857 (Feature table) -length 336 +length 384 data read 131072/131072 bytes at offset 0 @@ -525,6 +525,7 @@ Format specific information: data file: TEST_DIR/t.IMGFMT.data data file raw: false corrupt: false + extended l2: false No errors were found on the image. === Try changing the external data file === @@ -546,6 +547,7 @@ Format specific information: data file: foo data file raw: false corrupt: false + extended l2: false qemu-img: Could not open 'TEST_DIR/t.IMGFMT': 'data-file' is required for this image image: TEST_DIR/t.IMGFMT @@ -559,6 +561,7 @@ Format specific information: refcount bits: 16 data file raw: false corrupt: false + extended l2: false === Clearing and setting data-file-raw === @@ -575,6 +578,7 @@ Format specific information: data file: TEST_DIR/t.IMGFMT.data data file raw: true corrupt: false + extended l2: false No errors were found on the image. image: TEST_DIR/t.IMGFMT file format: IMGFMT @@ -588,6 +592,7 @@ Format specific information: data file: TEST_DIR/t.IMGFMT.data data file raw: false corrupt: false + extended l2: false No errors were found on the image. qemu-img: data-file-raw cannot be set on existing images image: TEST_DIR/t.IMGFMT @@ -602,5 +607,6 @@ Format specific information: data file: TEST_DIR/t.IMGFMT.data data file raw: false corrupt: false + extended l2: false No errors were found on the image. *** done diff --git a/tests/qemu-iotests/065 b/tests/qemu-iotests/065 index 18dc488c7a..29a7f7ad60 100755 --- a/tests/qemu-iotests/065 +++ b/tests/qemu-iotests/065 @@ -98,20 +98,20 @@ class TestQCow3NotLazy(TestQemuImgInfo): img_options = 'compat=1.1,lazy_refcounts=off' json_compare = { 'compat': '1.1', 'lazy-refcounts': False, 'refcount-bits': 16, 'corrupt': False, - 'compression-type': 'zlib' } + 'compression-type': 'zlib', 'extended-l2': False } human_compare = [ 'compat: 1.1', 'compression type: zlib', 'lazy refcounts: false', 'refcount bits: 16', - 'corrupt: false' ] + 'corrupt: false', 'extended l2: false' ] class TestQCow3Lazy(TestQemuImgInfo): '''Testing a qcow2 version 3 image with lazy refcounts enabled''' img_options = 'compat=1.1,lazy_refcounts=on' json_compare = { 'compat': '1.1', 'lazy-refcounts': True, 'refcount-bits': 16, 'corrupt': False, - 'compression-type': 'zlib' } + 'compression-type': 'zlib', 'extended-l2': False } human_compare = [ 'compat: 1.1', 'compression type: zlib', 'lazy refcounts: true', 'refcount bits: 16', - 'corrupt: false' ] + 'corrupt: false', 'extended l2: false' ] class TestQCow3NotLazyQMP(TestQMP): '''Testing a qcow2 version 3 image with lazy refcounts disabled, opening @@ -120,7 +120,7 @@ class TestQCow3NotLazyQMP(TestQMP): qemu_options = 'lazy-refcounts=on' compare = { 'compat': '1.1', 'lazy-refcounts': False, 'refcount-bits': 16, 'corrupt': False, - 'compression-type': 'zlib' } + 'compression-type': 'zlib', 'extended-l2': False } class TestQCow3LazyQMP(TestQMP): @@ -130,7 +130,7 @@ class TestQCow3LazyQMP(TestQMP): qemu_options = 'lazy-refcounts=off' compare = { 'compat': '1.1', 'lazy-refcounts': True, 'refcount-bits': 16, 'corrupt': False, - 'compression-type': 'zlib' } + 'compression-type': 'zlib', 'extended-l2': False } TestImageInfoSpecific = None TestQemuImgInfo = None diff --git a/tests/qemu-iotests/082.out b/tests/qemu-iotests/082.out index 529a1214e1..efc0328e8d 100644 --- a/tests/qemu-iotests/082.out +++ b/tests/qemu-iotests/082.out @@ -3,14 +3,14 @@ QA output created by 082 === create: Options specified more than once === Testing: create -f foo -f qcow2 TEST_DIR/t.qcow2 128M -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib image: TEST_DIR/t.IMGFMT file format: IMGFMT virtual size: 128 MiB (134217728 bytes) cluster_size: 65536 Testing: create -f qcow2 -o cluster_size=4k -o lazy_refcounts=on TEST_DIR/t.qcow2 128M -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 cluster_size=4096 lazy_refcounts=on refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 cluster_size=4096 lazy_refcounts=on extended_l2=off refcount_bits=16 compression_type=zlib image: TEST_DIR/t.IMGFMT file format: IMGFMT virtual size: 128 MiB (134217728 bytes) @@ -21,9 +21,10 @@ Format specific information: lazy refcounts: true refcount bits: 16 corrupt: false + extended l2: false Testing: create -f qcow2 -o cluster_size=4k -o lazy_refcounts=on -o cluster_size=8k TEST_DIR/t.qcow2 128M -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 cluster_size=8192 lazy_refcounts=on refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 cluster_size=8192 lazy_refcounts=on extended_l2=off refcount_bits=16 compression_type=zlib image: TEST_DIR/t.IMGFMT file format: IMGFMT virtual size: 128 MiB (134217728 bytes) @@ -34,9 +35,10 @@ Format specific information: lazy refcounts: true refcount bits: 16 corrupt: false + extended l2: false Testing: create -f qcow2 -o cluster_size=4k,cluster_size=8k TEST_DIR/t.qcow2 128M -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 cluster_size=8192 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 cluster_size=8192 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib image: TEST_DIR/t.IMGFMT file format: IMGFMT virtual size: 128 MiB (134217728 bytes) @@ -62,6 +64,7 @@ Supported options: encrypt.ivgen-hash-alg= - Name of IV generator hash algorithm encrypt.key-secret= - ID of secret providing qcow AES key or LUKS passphrase encryption= - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) + extended_l2= - Extended L2 tables lazy_refcounts= - Postpone refcount updates nocow= - Turn off copy-on-write (valid only on btrfs) preallocation= - Preallocation mode (allowed values: off, metadata, falloc, full) @@ -86,6 +89,7 @@ Supported options: encrypt.ivgen-hash-alg= - Name of IV generator hash algorithm encrypt.key-secret= - ID of secret providing qcow AES key or LUKS passphrase encryption= - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) + extended_l2= - Extended L2 tables lazy_refcounts= - Postpone refcount updates nocow= - Turn off copy-on-write (valid only on btrfs) preallocation= - Preallocation mode (allowed values: off, metadata, falloc, full) @@ -110,6 +114,7 @@ Supported options: encrypt.ivgen-hash-alg= - Name of IV generator hash algorithm encrypt.key-secret= - ID of secret providing qcow AES key or LUKS passphrase encryption= - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) + extended_l2= - Extended L2 tables lazy_refcounts= - Postpone refcount updates nocow= - Turn off copy-on-write (valid only on btrfs) preallocation= - Preallocation mode (allowed values: off, metadata, falloc, full) @@ -134,6 +139,7 @@ Supported options: encrypt.ivgen-hash-alg= - Name of IV generator hash algorithm encrypt.key-secret= - ID of secret providing qcow AES key or LUKS passphrase encryption= - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) + extended_l2= - Extended L2 tables lazy_refcounts= - Postpone refcount updates nocow= - Turn off copy-on-write (valid only on btrfs) preallocation= - Preallocation mode (allowed values: off, metadata, falloc, full) @@ -158,6 +164,7 @@ Supported options: encrypt.ivgen-hash-alg= - Name of IV generator hash algorithm encrypt.key-secret= - ID of secret providing qcow AES key or LUKS passphrase encryption= - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) + extended_l2= - Extended L2 tables lazy_refcounts= - Postpone refcount updates nocow= - Turn off copy-on-write (valid only on btrfs) preallocation= - Preallocation mode (allowed values: off, metadata, falloc, full) @@ -182,6 +189,7 @@ Supported options: encrypt.ivgen-hash-alg= - Name of IV generator hash algorithm encrypt.key-secret= - ID of secret providing qcow AES key or LUKS passphrase encryption= - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) + extended_l2= - Extended L2 tables lazy_refcounts= - Postpone refcount updates nocow= - Turn off copy-on-write (valid only on btrfs) preallocation= - Preallocation mode (allowed values: off, metadata, falloc, full) @@ -206,6 +214,7 @@ Supported options: encrypt.ivgen-hash-alg= - Name of IV generator hash algorithm encrypt.key-secret= - ID of secret providing qcow AES key or LUKS passphrase encryption= - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) + extended_l2= - Extended L2 tables lazy_refcounts= - Postpone refcount updates nocow= - Turn off copy-on-write (valid only on btrfs) preallocation= - Preallocation mode (allowed values: off, metadata, falloc, full) @@ -230,6 +239,7 @@ Supported options: encrypt.ivgen-hash-alg= - Name of IV generator hash algorithm encrypt.key-secret= - ID of secret providing qcow AES key or LUKS passphrase encryption= - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) + extended_l2= - Extended L2 tables lazy_refcounts= - Postpone refcount updates nocow= - Turn off copy-on-write (valid only on btrfs) preallocation= - Preallocation mode (allowed values: off, metadata, falloc, full) @@ -237,10 +247,10 @@ Supported options: size= - Virtual disk size Testing: create -f qcow2 -u -o backing_file=TEST_DIR/t.qcow2,,help TEST_DIR/t.qcow2 128M -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/t.qcow2,,help cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/t.qcow2,,help cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib Testing: create -f qcow2 -u -o backing_file=TEST_DIR/t.qcow2,,? TEST_DIR/t.qcow2 128M -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/t.qcow2,,? cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/t.qcow2,,? cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib Testing: create -f qcow2 -o backing_file=TEST_DIR/t.qcow2, -o help TEST_DIR/t.qcow2 128M qemu-img: Invalid option list: backing_file=TEST_DIR/t.qcow2, @@ -269,6 +279,7 @@ Supported qcow2 options: encrypt.ivgen-hash-alg= - Name of IV generator hash algorithm encrypt.key-secret= - ID of secret providing qcow AES key or LUKS passphrase encryption= - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) + extended_l2= - Extended L2 tables lazy_refcounts= - Postpone refcount updates preallocation= - Preallocation mode (allowed values: off, metadata, falloc, full) refcount_bits= - Width of a reference count entry in bits @@ -290,7 +301,7 @@ qemu-img: Format driver 'bochs' does not support image creation === convert: Options specified more than once === Testing: create -f qcow2 TEST_DIR/t.qcow2 128M -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib Testing: convert -f foo -f qcow2 TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base image: TEST_DIR/t.IMGFMT.base @@ -314,6 +325,7 @@ Format specific information: lazy refcounts: true refcount bits: 16 corrupt: false + extended l2: false Testing: convert -O qcow2 -o cluster_size=4k -o lazy_refcounts=on -o cluster_size=8k TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base image: TEST_DIR/t.IMGFMT.base @@ -326,6 +338,7 @@ Format specific information: lazy refcounts: true refcount bits: 16 corrupt: false + extended l2: false Testing: convert -O qcow2 -o cluster_size=4k,cluster_size=8k TEST_DIR/t.qcow2 TEST_DIR/t.qcow2.base image: TEST_DIR/t.IMGFMT.base @@ -353,6 +366,7 @@ Supported options: encrypt.ivgen-hash-alg= - Name of IV generator hash algorithm encrypt.key-secret= - ID of secret providing qcow AES key or LUKS passphrase encryption= - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) + extended_l2= - Extended L2 tables lazy_refcounts= - Postpone refcount updates nocow= - Turn off copy-on-write (valid only on btrfs) preallocation= - Preallocation mode (allowed values: off, metadata, falloc, full) @@ -377,6 +391,7 @@ Supported options: encrypt.ivgen-hash-alg= - Name of IV generator hash algorithm encrypt.key-secret= - ID of secret providing qcow AES key or LUKS passphrase encryption= - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) + extended_l2= - Extended L2 tables lazy_refcounts= - Postpone refcount updates nocow= - Turn off copy-on-write (valid only on btrfs) preallocation= - Preallocation mode (allowed values: off, metadata, falloc, full) @@ -401,6 +416,7 @@ Supported options: encrypt.ivgen-hash-alg= - Name of IV generator hash algorithm encrypt.key-secret= - ID of secret providing qcow AES key or LUKS passphrase encryption= - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) + extended_l2= - Extended L2 tables lazy_refcounts= - Postpone refcount updates nocow= - Turn off copy-on-write (valid only on btrfs) preallocation= - Preallocation mode (allowed values: off, metadata, falloc, full) @@ -425,6 +441,7 @@ Supported options: encrypt.ivgen-hash-alg= - Name of IV generator hash algorithm encrypt.key-secret= - ID of secret providing qcow AES key or LUKS passphrase encryption= - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) + extended_l2= - Extended L2 tables lazy_refcounts= - Postpone refcount updates nocow= - Turn off copy-on-write (valid only on btrfs) preallocation= - Preallocation mode (allowed values: off, metadata, falloc, full) @@ -449,6 +466,7 @@ Supported options: encrypt.ivgen-hash-alg= - Name of IV generator hash algorithm encrypt.key-secret= - ID of secret providing qcow AES key or LUKS passphrase encryption= - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) + extended_l2= - Extended L2 tables lazy_refcounts= - Postpone refcount updates nocow= - Turn off copy-on-write (valid only on btrfs) preallocation= - Preallocation mode (allowed values: off, metadata, falloc, full) @@ -473,6 +491,7 @@ Supported options: encrypt.ivgen-hash-alg= - Name of IV generator hash algorithm encrypt.key-secret= - ID of secret providing qcow AES key or LUKS passphrase encryption= - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) + extended_l2= - Extended L2 tables lazy_refcounts= - Postpone refcount updates nocow= - Turn off copy-on-write (valid only on btrfs) preallocation= - Preallocation mode (allowed values: off, metadata, falloc, full) @@ -497,6 +516,7 @@ Supported options: encrypt.ivgen-hash-alg= - Name of IV generator hash algorithm encrypt.key-secret= - ID of secret providing qcow AES key or LUKS passphrase encryption= - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) + extended_l2= - Extended L2 tables lazy_refcounts= - Postpone refcount updates nocow= - Turn off copy-on-write (valid only on btrfs) preallocation= - Preallocation mode (allowed values: off, metadata, falloc, full) @@ -521,6 +541,7 @@ Supported options: encrypt.ivgen-hash-alg= - Name of IV generator hash algorithm encrypt.key-secret= - ID of secret providing qcow AES key or LUKS passphrase encryption= - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) + extended_l2= - Extended L2 tables lazy_refcounts= - Postpone refcount updates nocow= - Turn off copy-on-write (valid only on btrfs) preallocation= - Preallocation mode (allowed values: off, metadata, falloc, full) @@ -560,6 +581,7 @@ Supported qcow2 options: encrypt.ivgen-hash-alg= - Name of IV generator hash algorithm encrypt.key-secret= - ID of secret providing qcow AES key or LUKS passphrase encryption= - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) + extended_l2= - Extended L2 tables lazy_refcounts= - Postpone refcount updates preallocation= - Preallocation mode (allowed values: off, metadata, falloc, full) refcount_bits= - Width of a reference count entry in bits @@ -605,6 +627,7 @@ Format specific information: lazy refcounts: true refcount bits: 16 corrupt: false + extended l2: false Testing: amend -f qcow2 -o size=130M -o lazy_refcounts=off TEST_DIR/t.qcow2 image: TEST_DIR/t.IMGFMT @@ -617,6 +640,7 @@ Format specific information: lazy refcounts: false refcount bits: 16 corrupt: false + extended l2: false Testing: amend -f qcow2 -o size=8M -o lazy_refcounts=on -o size=132M TEST_DIR/t.qcow2 image: TEST_DIR/t.IMGFMT @@ -629,6 +653,7 @@ Format specific information: lazy refcounts: true refcount bits: 16 corrupt: false + extended l2: false Testing: amend -f qcow2 -o size=4M,size=148M TEST_DIR/t.qcow2 image: TEST_DIR/t.IMGFMT @@ -656,6 +681,7 @@ Creation options for 'qcow2': encrypt.ivgen-hash-alg= - Name of IV generator hash algorithm encrypt.key-secret= - ID of secret providing qcow AES key or LUKS passphrase encryption= - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) + extended_l2= - Extended L2 tables lazy_refcounts= - Postpone refcount updates preallocation= - Preallocation mode (allowed values: off, metadata, falloc, full) refcount_bits= - Width of a reference count entry in bits @@ -681,6 +707,7 @@ Creation options for 'qcow2': encrypt.ivgen-hash-alg= - Name of IV generator hash algorithm encrypt.key-secret= - ID of secret providing qcow AES key or LUKS passphrase encryption= - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) + extended_l2= - Extended L2 tables lazy_refcounts= - Postpone refcount updates preallocation= - Preallocation mode (allowed values: off, metadata, falloc, full) refcount_bits= - Width of a reference count entry in bits @@ -706,6 +733,7 @@ Creation options for 'qcow2': encrypt.ivgen-hash-alg= - Name of IV generator hash algorithm encrypt.key-secret= - ID of secret providing qcow AES key or LUKS passphrase encryption= - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) + extended_l2= - Extended L2 tables lazy_refcounts= - Postpone refcount updates preallocation= - Preallocation mode (allowed values: off, metadata, falloc, full) refcount_bits= - Width of a reference count entry in bits @@ -731,6 +759,7 @@ Creation options for 'qcow2': encrypt.ivgen-hash-alg= - Name of IV generator hash algorithm encrypt.key-secret= - ID of secret providing qcow AES key or LUKS passphrase encryption= - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) + extended_l2= - Extended L2 tables lazy_refcounts= - Postpone refcount updates preallocation= - Preallocation mode (allowed values: off, metadata, falloc, full) refcount_bits= - Width of a reference count entry in bits @@ -756,6 +785,7 @@ Creation options for 'qcow2': encrypt.ivgen-hash-alg= - Name of IV generator hash algorithm encrypt.key-secret= - ID of secret providing qcow AES key or LUKS passphrase encryption= - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) + extended_l2= - Extended L2 tables lazy_refcounts= - Postpone refcount updates preallocation= - Preallocation mode (allowed values: off, metadata, falloc, full) refcount_bits= - Width of a reference count entry in bits @@ -781,6 +811,7 @@ Creation options for 'qcow2': encrypt.ivgen-hash-alg= - Name of IV generator hash algorithm encrypt.key-secret= - ID of secret providing qcow AES key or LUKS passphrase encryption= - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) + extended_l2= - Extended L2 tables lazy_refcounts= - Postpone refcount updates preallocation= - Preallocation mode (allowed values: off, metadata, falloc, full) refcount_bits= - Width of a reference count entry in bits @@ -806,6 +837,7 @@ Creation options for 'qcow2': encrypt.ivgen-hash-alg= - Name of IV generator hash algorithm encrypt.key-secret= - ID of secret providing qcow AES key or LUKS passphrase encryption= - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) + extended_l2= - Extended L2 tables lazy_refcounts= - Postpone refcount updates preallocation= - Preallocation mode (allowed values: off, metadata, falloc, full) refcount_bits= - Width of a reference count entry in bits @@ -831,6 +863,7 @@ Creation options for 'qcow2': encrypt.ivgen-hash-alg= - Name of IV generator hash algorithm encrypt.key-secret= - ID of secret providing qcow AES key or LUKS passphrase encryption= - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) + extended_l2= - Extended L2 tables lazy_refcounts= - Postpone refcount updates preallocation= - Preallocation mode (allowed values: off, metadata, falloc, full) refcount_bits= - Width of a reference count entry in bits @@ -873,6 +906,7 @@ Creation options for 'qcow2': encrypt.ivgen-hash-alg= - Name of IV generator hash algorithm encrypt.key-secret= - ID of secret providing qcow AES key or LUKS passphrase encryption= - Encrypt the image with format 'aes'. (Deprecated in favor of encrypt.format=aes) + extended_l2= - Extended L2 tables lazy_refcounts= - Postpone refcount updates preallocation= - Preallocation mode (allowed values: off, metadata, falloc, full) refcount_bits= - Width of a reference count entry in bits diff --git a/tests/qemu-iotests/085.out b/tests/qemu-iotests/085.out index a822ff4ef6..0431743808 100644 --- a/tests/qemu-iotests/085.out +++ b/tests/qemu-iotests/085.out @@ -13,7 +13,7 @@ Formatting 'TEST_DIR/t.IMGFMT.2', fmt=IMGFMT size=134217728 === Create a single snapshot on virtio0 === { 'execute': 'blockdev-snapshot-sync', 'arguments': { 'device': 'virtio0', 'snapshot-file':'TEST_DIR/1-snapshot-v0.IMGFMT', 'format': 'IMGFMT' } } -Formatting 'TEST_DIR/1-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/t.qcow2.1 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/1-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/t.qcow2.1 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib {"return": {}} === Invalid command - missing device and nodename === @@ -30,40 +30,40 @@ Formatting 'TEST_DIR/1-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file === Create several transactional group snapshots === { 'execute': 'transaction', 'arguments': {'actions': [ { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio0', 'snapshot-file': 'TEST_DIR/2-snapshot-v0.IMGFMT' } }, { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio1', 'snapshot-file': 'TEST_DIR/2-snapshot-v1.IMGFMT' } } ] } } -Formatting 'TEST_DIR/2-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/1-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib -Formatting 'TEST_DIR/2-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/t.qcow2.2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/2-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/1-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/2-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/t.qcow2.2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib {"return": {}} { 'execute': 'transaction', 'arguments': {'actions': [ { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio0', 'snapshot-file': 'TEST_DIR/3-snapshot-v0.IMGFMT' } }, { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio1', 'snapshot-file': 'TEST_DIR/3-snapshot-v1.IMGFMT' } } ] } } -Formatting 'TEST_DIR/3-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/2-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib -Formatting 'TEST_DIR/3-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/2-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/3-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/2-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/3-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/2-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib {"return": {}} { 'execute': 'transaction', 'arguments': {'actions': [ { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio0', 'snapshot-file': 'TEST_DIR/4-snapshot-v0.IMGFMT' } }, { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio1', 'snapshot-file': 'TEST_DIR/4-snapshot-v1.IMGFMT' } } ] } } -Formatting 'TEST_DIR/4-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/3-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib -Formatting 'TEST_DIR/4-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/3-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/4-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/3-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/4-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/3-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib {"return": {}} { 'execute': 'transaction', 'arguments': {'actions': [ { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio0', 'snapshot-file': 'TEST_DIR/5-snapshot-v0.IMGFMT' } }, { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio1', 'snapshot-file': 'TEST_DIR/5-snapshot-v1.IMGFMT' } } ] } } -Formatting 'TEST_DIR/5-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/4-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib -Formatting 'TEST_DIR/5-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/4-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/5-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/4-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/5-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/4-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib {"return": {}} { 'execute': 'transaction', 'arguments': {'actions': [ { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio0', 'snapshot-file': 'TEST_DIR/6-snapshot-v0.IMGFMT' } }, { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio1', 'snapshot-file': 'TEST_DIR/6-snapshot-v1.IMGFMT' } } ] } } -Formatting 'TEST_DIR/6-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/5-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib -Formatting 'TEST_DIR/6-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/5-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/6-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/5-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/6-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/5-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib {"return": {}} { 'execute': 'transaction', 'arguments': {'actions': [ { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio0', 'snapshot-file': 'TEST_DIR/7-snapshot-v0.IMGFMT' } }, { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio1', 'snapshot-file': 'TEST_DIR/7-snapshot-v1.IMGFMT' } } ] } } -Formatting 'TEST_DIR/7-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/6-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib -Formatting 'TEST_DIR/7-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/6-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/7-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/6-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/7-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/6-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib {"return": {}} { 'execute': 'transaction', 'arguments': {'actions': [ { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio0', 'snapshot-file': 'TEST_DIR/8-snapshot-v0.IMGFMT' } }, { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio1', 'snapshot-file': 'TEST_DIR/8-snapshot-v1.IMGFMT' } } ] } } -Formatting 'TEST_DIR/8-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/7-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib -Formatting 'TEST_DIR/8-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/7-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/8-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/7-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/8-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/7-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib {"return": {}} { 'execute': 'transaction', 'arguments': {'actions': [ { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio0', 'snapshot-file': 'TEST_DIR/9-snapshot-v0.IMGFMT' } }, { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio1', 'snapshot-file': 'TEST_DIR/9-snapshot-v1.IMGFMT' } } ] } } -Formatting 'TEST_DIR/9-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/8-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib -Formatting 'TEST_DIR/9-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/8-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/9-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/8-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/9-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/8-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib {"return": {}} { 'execute': 'transaction', 'arguments': {'actions': [ { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio0', 'snapshot-file': 'TEST_DIR/10-snapshot-v0.IMGFMT' } }, { 'type': 'blockdev-snapshot-sync', 'data' : { 'device': 'virtio1', 'snapshot-file': 'TEST_DIR/10-snapshot-v1.IMGFMT' } } ] } } -Formatting 'TEST_DIR/10-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/9-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib -Formatting 'TEST_DIR/10-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/9-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/10-snapshot-v0.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/9-snapshot-v0.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/10-snapshot-v1.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/9-snapshot-v1.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib {"return": {}} === Create a couple of snapshots using blockdev-snapshot === diff --git a/tests/qemu-iotests/144.out b/tests/qemu-iotests/144.out index 885a8874a5..a2627f0cc5 100644 --- a/tests/qemu-iotests/144.out +++ b/tests/qemu-iotests/144.out @@ -9,7 +9,7 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=536870912 { 'execute': 'qmp_capabilities' } {"return": {}} { 'execute': 'blockdev-snapshot-sync', 'arguments': { 'device': 'virtio0', 'snapshot-file':'TEST_DIR/tmp.IMGFMT', 'format': 'IMGFMT' } } -Formatting 'TEST_DIR/tmp.qcow2', fmt=qcow2 size=536870912 backing_file=TEST_DIR/t.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/tmp.qcow2', fmt=qcow2 size=536870912 backing_file=TEST_DIR/t.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib {"return": {}} === Performing block-commit on active layer === @@ -31,6 +31,6 @@ Formatting 'TEST_DIR/tmp.qcow2', fmt=qcow2 size=536870912 backing_file=TEST_DIR/ === Performing Live Snapshot 2 === { 'execute': 'blockdev-snapshot-sync', 'arguments': { 'device': 'virtio0', 'snapshot-file':'TEST_DIR/tmp2.IMGFMT', 'format': 'IMGFMT' } } -Formatting 'TEST_DIR/tmp2.qcow2', fmt=qcow2 size=536870912 backing_file=TEST_DIR/t.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/tmp2.qcow2', fmt=qcow2 size=536870912 backing_file=TEST_DIR/t.qcow2 backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib {"return": {}} *** done diff --git a/tests/qemu-iotests/182.out b/tests/qemu-iotests/182.out index ae43654d32..e4290ec028 100644 --- a/tests/qemu-iotests/182.out +++ b/tests/qemu-iotests/182.out @@ -13,7 +13,7 @@ Is another process using the image [TEST_DIR/t.qcow2]? {'execute': 'blockdev-add', 'arguments': { 'node-name': 'node0', 'driver': 'file', 'filename': 'TEST_DIR/t.IMGFMT', 'locking': 'on' } } {"return": {}} {'execute': 'blockdev-snapshot-sync', 'arguments': { 'node-name': 'node0', 'snapshot-file': 'TEST_DIR/t.IMGFMT.overlay', 'snapshot-node-name': 'node1' } } -Formatting 'TEST_DIR/t.qcow2.overlay', fmt=qcow2 size=197120 backing_file=TEST_DIR/t.qcow2 backing_fmt=file cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2.overlay', fmt=qcow2 size=197120 backing_file=TEST_DIR/t.qcow2 backing_fmt=file cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib {"return": {}} {'execute': 'blockdev-add', 'arguments': { 'node-name': 'node1', 'driver': 'file', 'filename': 'TEST_DIR/t.IMGFMT', 'locking': 'on' } } {"return": {}} diff --git a/tests/qemu-iotests/185.out b/tests/qemu-iotests/185.out index ac5ab16bc8..4e0f018bf2 100644 --- a/tests/qemu-iotests/185.out +++ b/tests/qemu-iotests/185.out @@ -9,14 +9,14 @@ Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864 === Creating backing chain === { 'execute': 'blockdev-snapshot-sync', 'arguments': { 'device': 'disk', 'snapshot-file': 'TEST_DIR/t.IMGFMT.mid', 'format': 'IMGFMT', 'mode': 'absolute-paths' } } -Formatting 'TEST_DIR/t.qcow2.mid', fmt=qcow2 size=67108864 backing_file=TEST_DIR/t.qcow2.base backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2.mid', fmt=qcow2 size=67108864 backing_file=TEST_DIR/t.qcow2.base backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib {"return": {}} { 'execute': 'human-monitor-command', 'arguments': { 'command-line': 'qemu-io disk "write 0 4M"' } } wrote 4194304/4194304 bytes at offset 0 4 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) {"return": ""} { 'execute': 'blockdev-snapshot-sync', 'arguments': { 'device': 'disk', 'snapshot-file': 'TEST_DIR/t.IMGFMT', 'format': 'IMGFMT', 'mode': 'absolute-paths' } } -Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 backing_file=TEST_DIR/t.qcow2.mid backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 backing_file=TEST_DIR/t.qcow2.mid backing_fmt=qcow2 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib {"return": {}} === Start commit job and exit qemu === @@ -48,7 +48,7 @@ Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=67108864 backing_file=TEST_DIR/t.q { 'execute': 'qmp_capabilities' } {"return": {}} { 'execute': 'drive-mirror', 'arguments': { 'device': 'disk', 'target': 'TEST_DIR/t.IMGFMT.copy', 'format': 'IMGFMT', 'sync': 'full', 'speed': 65536 } } -Formatting 'TEST_DIR/t.qcow2.copy', fmt=qcow2 size=67108864 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2.copy', fmt=qcow2 size=67108864 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "disk"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "disk"}} {"return": {}} @@ -62,7 +62,7 @@ Formatting 'TEST_DIR/t.qcow2.copy', fmt=qcow2 size=67108864 cluster_size=65536 l { 'execute': 'qmp_capabilities' } {"return": {}} { 'execute': 'drive-backup', 'arguments': { 'device': 'disk', 'target': 'TEST_DIR/t.IMGFMT.copy', 'format': 'IMGFMT', 'sync': 'full', 'speed': 65536 } } -Formatting 'TEST_DIR/t.qcow2.copy', fmt=qcow2 size=67108864 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/t.qcow2.copy', fmt=qcow2 size=67108864 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "created", "id": "disk"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "running", "id": "disk"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "JOB_STATUS_CHANGE", "data": {"status": "paused", "id": "disk"}} diff --git a/tests/qemu-iotests/198.out b/tests/qemu-iotests/198.out index 6280ae6eed..821a052bb1 100644 --- a/tests/qemu-iotests/198.out +++ b/tests/qemu-iotests/198.out @@ -73,6 +73,7 @@ Format specific information: key offset: 1810432 payload offset: 2068480 master key iters: 1024 + extended l2: false == checking image layer == image: json:{ /* filtered */ } @@ -117,4 +118,5 @@ Format specific information: key offset: 1810432 payload offset: 2068480 master key iters: 1024 + extended l2: false *** done diff --git a/tests/qemu-iotests/206.out b/tests/qemu-iotests/206.out index 1a14255a83..363c5abe35 100644 --- a/tests/qemu-iotests/206.out +++ b/tests/qemu-iotests/206.out @@ -22,6 +22,7 @@ Format specific information: lazy refcounts: false refcount bits: 16 corrupt: false + extended l2: false === Successful image creation (inline blockdev-add, explicit defaults) === @@ -45,6 +46,7 @@ Format specific information: lazy refcounts: false refcount bits: 16 corrupt: false + extended l2: false === Successful image creation (v3 non-default options) === @@ -68,6 +70,7 @@ Format specific information: lazy refcounts: true refcount bits: 1 corrupt: false + extended l2: false === Successful image creation (v2 non-default options) === @@ -146,6 +149,7 @@ Format specific information: payload offset: 528384 master key iters: XXX corrupt: false + extended l2: false === Invalid BlockdevRef === diff --git a/tests/qemu-iotests/242.out b/tests/qemu-iotests/242.out index 091b9126ce..3759c99284 100644 --- a/tests/qemu-iotests/242.out +++ b/tests/qemu-iotests/242.out @@ -16,6 +16,7 @@ Format specific information: lazy refcounts: false refcount bits: 16 corrupt: false + extended l2: false No bitmap in JSON format output @@ -42,6 +43,7 @@ Format specific information: granularity: 32768 refcount bits: 16 corrupt: false + extended l2: false The same bitmaps in JSON format: [ @@ -80,6 +82,7 @@ Format specific information: granularity: 65536 refcount bits: 16 corrupt: false + extended l2: false The same bitmaps in JSON format: [ @@ -123,6 +126,7 @@ Format specific information: granularity: 65536 refcount bits: 16 corrupt: false + extended l2: false The same bitmaps in JSON format: [ @@ -167,5 +171,6 @@ Format specific information: granularity: 16384 refcount bits: 16 corrupt: false + extended l2: false Test complete diff --git a/tests/qemu-iotests/255.out b/tests/qemu-iotests/255.out index a3c99fd62e..38ac1a4e95 100644 --- a/tests/qemu-iotests/255.out +++ b/tests/qemu-iotests/255.out @@ -3,9 +3,9 @@ Finishing a commit job with background reads === Create backing chain and start VM === -Formatting 'TEST_DIR/PID-t.qcow2.mid', fmt=qcow2 size=134217728 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/PID-t.qcow2.mid', fmt=qcow2 size=134217728 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib -Formatting 'TEST_DIR/PID-t.qcow2', fmt=qcow2 size=134217728 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/PID-t.qcow2', fmt=qcow2 size=134217728 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib === Start background read requests === @@ -23,9 +23,9 @@ Closing the VM while a job is being cancelled === Create images and start VM === -Formatting 'TEST_DIR/PID-src.qcow2', fmt=qcow2 size=134217728 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/PID-src.qcow2', fmt=qcow2 size=134217728 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib -Formatting 'TEST_DIR/PID-dst.qcow2', fmt=qcow2 size=134217728 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/PID-dst.qcow2', fmt=qcow2 size=134217728 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib wrote 1048576/1048576 bytes at offset 0 1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) diff --git a/tests/qemu-iotests/274.out b/tests/qemu-iotests/274.out index d24ff681af..47edc3c423 100644 --- a/tests/qemu-iotests/274.out +++ b/tests/qemu-iotests/274.out @@ -1,9 +1,9 @@ == Commit tests == -Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=2097152 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=2097152 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib -Formatting 'TEST_DIR/PID-mid', fmt=qcow2 size=1048576 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/PID-mid', fmt=qcow2 size=1048576 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib -Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=2097152 backing_file=TEST_DIR/PID-mid cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=2097152 backing_file=TEST_DIR/PID-mid cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib wrote 2097152/2097152 bytes at offset 0 2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) @@ -56,6 +56,7 @@ Format specific information: lazy refcounts: false refcount bits: 16 corrupt: false + extended l2: false read 1048576/1048576 bytes at offset 0 1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) @@ -64,11 +65,11 @@ read 1048576/1048576 bytes at offset 1048576 1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) === Testing HMP commit (top -> mid) === -Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=2097152 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=2097152 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib -Formatting 'TEST_DIR/PID-mid', fmt=qcow2 size=1048576 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/PID-mid', fmt=qcow2 size=1048576 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib -Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=2097152 backing_file=TEST_DIR/PID-mid cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=2097152 backing_file=TEST_DIR/PID-mid cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib wrote 2097152/2097152 bytes at offset 0 2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) @@ -86,6 +87,7 @@ Format specific information: lazy refcounts: false refcount bits: 16 corrupt: false + extended l2: false read 1048576/1048576 bytes at offset 0 1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) @@ -94,11 +96,11 @@ read 1048576/1048576 bytes at offset 1048576 1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) === Testing QMP active commit (top -> mid) === -Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=2097152 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=2097152 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib -Formatting 'TEST_DIR/PID-mid', fmt=qcow2 size=1048576 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/PID-mid', fmt=qcow2 size=1048576 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib -Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=2097152 backing_file=TEST_DIR/PID-mid cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=2097152 backing_file=TEST_DIR/PID-mid cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib wrote 2097152/2097152 bytes at offset 0 2 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) @@ -122,6 +124,7 @@ Format specific information: lazy refcounts: false refcount bits: 16 corrupt: false + extended l2: false read 1048576/1048576 bytes at offset 0 1 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) @@ -131,9 +134,9 @@ read 1048576/1048576 bytes at offset 1048576 == Resize tests == === preallocation=off === -Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=6442450944 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=6442450944 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib -Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=1073741824 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=1073741824 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib wrote 65536/65536 bytes at offset 5368709120 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) @@ -150,9 +153,9 @@ read 65536/65536 bytes at offset 5368709120 { "start": 1073741824, "length": 7516192768, "depth": 0, "zero": true, "data": false}] === preallocation=metadata === -Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=34359738368 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=34359738368 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib -Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=32212254720 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=32212254720 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib wrote 65536/65536 bytes at offset 33285996544 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) @@ -174,9 +177,9 @@ read 65536/65536 bytes at offset 33285996544 { "start": 34896609280, "length": 536870912, "depth": 0, "zero": true, "data": false, "offset": 2685075456}] === preallocation=falloc === -Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=10485760 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=10485760 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib -Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=5242880 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=5242880 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib wrote 65536/65536 bytes at offset 9437184 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) @@ -193,9 +196,9 @@ read 65536/65536 bytes at offset 9437184 { "start": 5242880, "length": 10485760, "depth": 0, "zero": false, "data": true, "offset": 327680}] === preallocation=full === -Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=16777216 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=16777216 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib -Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=8388608 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=8388608 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib wrote 65536/65536 bytes at offset 11534336 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) @@ -212,9 +215,9 @@ read 65536/65536 bytes at offset 11534336 { "start": 8388608, "length": 4194304, "depth": 0, "zero": false, "data": true, "offset": 327680}] === preallocation=off === -Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=393216 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=393216 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib -Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=259072 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=259072 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib wrote 65536/65536 bytes at offset 259072 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) @@ -232,9 +235,9 @@ read 65536/65536 bytes at offset 259072 { "start": 262144, "length": 262144, "depth": 0, "zero": true, "data": false}] === preallocation=off === -Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=409600 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=409600 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib -Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=262144 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=262144 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib wrote 65536/65536 bytes at offset 344064 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) @@ -251,9 +254,9 @@ read 65536/65536 bytes at offset 344064 { "start": 262144, "length": 262144, "depth": 0, "zero": true, "data": false}] === preallocation=off === -Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=524288 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=524288 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib -Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=262144 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/PID-top', fmt=qcow2 size=262144 backing_file=TEST_DIR/PID-base cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib wrote 65536/65536 bytes at offset 446464 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) diff --git a/tests/qemu-iotests/280.out b/tests/qemu-iotests/280.out index 92e4d14079..372e9f70ad 100644 --- a/tests/qemu-iotests/280.out +++ b/tests/qemu-iotests/280.out @@ -1,4 +1,4 @@ -Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=67108864 cluster_size=65536 lazy_refcounts=off refcount_bits=16 compression_type=zlib +Formatting 'TEST_DIR/PID-base', fmt=qcow2 size=67108864 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 compression_type=zlib === Launch VM === Enabling migration QMP events on VM... diff --git a/tests/qemu-iotests/291.out b/tests/qemu-iotests/291.out index 08bfaaaa6b..83e3ec821c 100644 --- a/tests/qemu-iotests/291.out +++ b/tests/qemu-iotests/291.out @@ -22,7 +22,7 @@ data 'qcow2' Header extension: magic 0x6803f857 (Feature table) -length 336 +length 384 data Header extension: @@ -60,6 +60,7 @@ Format specific information: granularity: 65536 refcount bits: 16 corrupt: false + extended l2: false image: TEST_DIR/t.IMGFMT file format: IMGFMT virtual size: 10 MiB (10485760 bytes) @@ -84,10 +85,11 @@ Format specific information: granularity: 65536 refcount bits: 16 corrupt: false + extended l2: false Check resulting qcow2 header extensions: Header extension: magic 0x6803f857 (Feature table) -length 336 +length 384 data Header extension: diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter index 03e4f71808..2ca66de0f0 100644 --- a/tests/qemu-iotests/common.filter +++ b/tests/qemu-iotests/common.filter @@ -146,6 +146,7 @@ _filter_img_create() -e "s# adapter_type=[^ ]*##g" \ -e "s# hwversion=[^ ]*##g" \ -e "s# lazy_refcounts=\\(on\\|off\\)##g" \ + -e "s# extended_l2=\\(on\\|off\\)##g" \ -e "s# block_size=[0-9]\\+##g" \ -e "s# block_state_zero=\\(on\\|off\\)##g" \ -e "s# log_size=[0-9]\\+##g" \ From patchwork Sun Jun 28 11:02:41 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alberto Garcia X-Patchwork-Id: 279177 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 182B6C433E0 for ; Sun, 28 Jun 2020 11:17:24 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id D5B3620B80 for ; Sun, 28 Jun 2020 11:17:23 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=igalia.com header.i=@igalia.com header.b="b9wA4h9g" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org D5B3620B80 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=igalia.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:37676 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jpVJL-0004Ws-2F for qemu-devel@archiver.kernel.org; Sun, 28 Jun 2020 07:17:23 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:48742) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jpV6W-0007f5-5H; Sun, 28 Jun 2020 07:04:08 -0400 Received: from fanzine.igalia.com ([178.60.130.6]:42475) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1jpV6M-0000Xq-1d; Sun, 28 Jun 2020 07:04:07 -0400 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From; bh=5q86OzsOKt/Py3cpreHKFjhS5m2/WJcDnGCV9QFfQgo=; b=b9wA4h9gBjtQORW4uEodrII6js+NjZbL78LCcbrfZAcuog7Ljg3J161d5HD4ulzYAoGvsi4Xkeqq/z5thQo0Jm3W8RyZH6t1/lCis+41+KqlynTO9pc4sCnDGAJtplIhCoWHkeiMMmb2CmTpRL7xMZBS8oQMAw2+VBW7cHTu0O799BHkP0f5H47qzVauVpcSe34BsLX0Dc1ew6SUhsX/3WMZc9X1j0w05GEh3NBLEKa7hY1sLbAMXHS3fBCMMtzlrMXVhZs6mSf59jGgiAiKGrNxaKCkK9n9J9JOUIQcL3BtpktL2Skds6WRU1PSKt6YtEY3PI4PjSSLIXIir4ioqg==; Received: from 26.red-79-158-236.dynamicip.rima-tde.net ([79.158.236.26] helo=perseus.local) by fanzine.igalia.com with esmtpsa (Cipher TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim) id 1jpV5Y-0002gv-Dm; Sun, 28 Jun 2020 13:03:10 +0200 Received: from berto by perseus.local with local (Exim 4.92) (envelope-from ) id 1jpV5I-0003A6-EV; Sun, 28 Jun 2020 13:02:52 +0200 From: Alberto Garcia To: qemu-devel@nongnu.org Subject: [PATCH v9 32/34] qcow2: Allow preallocation and backing files if extended_l2 is set Date: Sun, 28 Jun 2020 13:02:41 +0200 Message-Id: <7bc65fa80f741d90be50ab25ede29b8e27aad677.1593342067.git.berto@igalia.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: References: MIME-Version: 1.0 Received-SPF: pass client-ip=178.60.130.6; envelope-from=berto@igalia.com; helo=fanzine.igalia.com X-detected-operating-system: by eggs.gnu.org: First seen = 2020/06/28 07:03:08 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x (no timestamps) [generic] [fuzzy] X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, URIBL_BLOCKED=0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , Alberto Garcia , qemu-block@nongnu.org, Derek Su , Max Reitz Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" Traditional qcow2 images don't allow preallocation if a backing file is set. This is because once a cluster is allocated there is no way to tell that its data should be read from the backing file. Extended L2 entries have individual allocation bits for each subcluster, and therefore it is perfectly possible to have an allocated cluster with all its subclusters unallocated. Signed-off-by: Alberto Garcia Reviewed-by: Eric Blake --- block/qcow2.c | 7 ++++--- tests/qemu-iotests/206.out | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/block/qcow2.c b/block/qcow2.c index 37bfae823c..1ea8d3b87e 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -3451,10 +3451,11 @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp) qcow2_opts->preallocation = PREALLOC_MODE_OFF; } if (qcow2_opts->has_backing_file && - qcow2_opts->preallocation != PREALLOC_MODE_OFF) + qcow2_opts->preallocation != PREALLOC_MODE_OFF && + !qcow2_opts->extended_l2) { - error_setg(errp, "Backing file and preallocation cannot be used at " - "the same time"); + error_setg(errp, "Backing file and preallocation can only be used at " + "the same time if extended_l2 is on"); ret = -EINVAL; goto out; } diff --git a/tests/qemu-iotests/206.out b/tests/qemu-iotests/206.out index 363c5abe35..a100849fcb 100644 --- a/tests/qemu-iotests/206.out +++ b/tests/qemu-iotests/206.out @@ -203,7 +203,7 @@ Job failed: Different refcount widths than 16 bits require compatibility level 1 === Invalid backing file options === {"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"backing-file": "/dev/null", "driver": "qcow2", "file": "node0", "preallocation": "full", "size": 67108864}}} {"return": {}} -Job failed: Backing file and preallocation cannot be used at the same time +Job failed: Backing file and preallocation can only be used at the same time if extended_l2 is on {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}}