From nobody Sun Nov 9 23:22:19 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (209.51.188.17 [209.51.188.17]) by mx.zohomail.com with SMTPS id 1552423186895783.8390175357875; Tue, 12 Mar 2019 13:39:46 -0700 (PDT) Received: from localhost ([127.0.0.1]:32967 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h3oBW-0000oq-D5 for importer@patchew.org; Tue, 12 Mar 2019 16:39:38 -0400 Received: from eggs.gnu.org ([209.51.188.92]:50882) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1h3nxQ-0005Bx-VD for qemu-devel@nongnu.org; Tue, 12 Mar 2019 16:25:06 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1h3nxP-0002uQ-KH for qemu-devel@nongnu.org; Tue, 12 Mar 2019 16:25:04 -0400 Received: from mx1.redhat.com ([209.132.183.28]:38351) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1h3nxP-0002tv-9v for qemu-devel@nongnu.org; Tue, 12 Mar 2019 16:25:03 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 76D27DF5A7; Tue, 12 Mar 2019 20:25:02 +0000 (UTC) Received: from probe.redhat.com (ovpn-125-62.rdu2.redhat.com [10.10.125.62]) by smtp.corp.redhat.com (Postfix) with ESMTP id B6E2060BF7; Tue, 12 Mar 2019 20:24:54 +0000 (UTC) From: John Snow To: qemu-devel@nongnu.org Date: Tue, 12 Mar 2019 16:23:36 -0400 Message-Id: <20190312202337.5278-22-jsnow@redhat.com> In-Reply-To: <20190312202337.5278-1-jsnow@redhat.com> References: <20190312202337.5278-1-jsnow@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Tue, 12 Mar 2019 20:25:02 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 21/22] block/qcow2-bitmap: Allow resizes with persistent bitmaps X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, Vladimir Sementsov-Ogievskiy , jsnow@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Since we now load all bitmaps into memory anyway, we can just truncate them in-memory and then flush them back to disk. Just in case, we will still check and enforce that this shortcut is valid -- i.e. that any bitmap described on-disk is indeed in-memory and can be modified. If there are any inconsistent bitmaps, we refuse to allow the truncate as we do not actually load these bitmaps into memory, and it isn't safe or reasonable to attempt to truncate corrupted data. Signed-off-by: John Snow Signed-off-by: Vladimir Sementsov-Ogievskiy Message-id: 20190311185147.52309-4-vsementsov@virtuozzo.com [vsementsov: drop bitmap flushing, fix block comments style] Signed-off-by: John Snow --- block/qcow2.h | 1 + block/qcow2-bitmap.c | 46 ++++++++++++++++++++++++++++++++++++++++++++ block/qcow2.c | 4 +--- 3 files changed, 48 insertions(+), 3 deletions(-) diff --git a/block/qcow2.h b/block/qcow2.h index de2a3bdfc5..fdee297f33 100644 --- a/block/qcow2.h +++ b/block/qcow2.h @@ -723,6 +723,7 @@ Qcow2BitmapInfoList *qcow2_get_bitmap_info_list(BlockDr= iverState *bs, int qcow2_reopen_bitmaps_rw_hint(BlockDriverState *bs, bool *header_update= d, Error **errp); int qcow2_reopen_bitmaps_rw(BlockDriverState *bs, Error **errp); +int qcow2_truncate_bitmaps_check(BlockDriverState *bs, Error **errp); void qcow2_store_persistent_dirty_bitmaps(BlockDriverState *bs, Error **er= rp); int qcow2_reopen_bitmaps_ro(BlockDriverState *bs, Error **errp); bool qcow2_can_store_new_dirty_bitmap(BlockDriverState *bs, diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c index 92cef1cfd4..e53a1609d7 100644 --- a/block/qcow2-bitmap.c +++ b/block/qcow2-bitmap.c @@ -1175,6 +1175,52 @@ int qcow2_reopen_bitmaps_rw(BlockDriverState *bs, Er= ror **errp) return qcow2_reopen_bitmaps_rw_hint(bs, NULL, errp); } =20 +/* Checks to see if it's safe to resize bitmaps */ +int qcow2_truncate_bitmaps_check(BlockDriverState *bs, Error **errp) +{ + BDRVQcow2State *s =3D bs->opaque; + Qcow2BitmapList *bm_list; + Qcow2Bitmap *bm; + int ret =3D 0; + + if (s->nb_bitmaps =3D=3D 0) { + return 0; + } + + bm_list =3D bitmap_list_load(bs, s->bitmap_directory_offset, + s->bitmap_directory_size, errp); + if (bm_list =3D=3D NULL) { + return -EINVAL; + } + + QSIMPLEQ_FOREACH(bm, bm_list, entry) { + BdrvDirtyBitmap *bitmap =3D bdrv_find_dirty_bitmap(bs, bm->name); + if (bitmap =3D=3D NULL) { + /* + * We rely on all bitmaps being in-memory to be able to resize= them, + * Otherwise, we'd need to resize them on disk explicitly + */ + error_setg(errp, "Cannot resize qcow2 with persistent bitmaps = that " + "were not loaded into memory"); + ret =3D -ENOTSUP; + goto out; + } + + /* + * The checks against readonly and busy are redundant, but certain= ly + * do no harm. checks against inconsistent are crucial: + */ + if (bdrv_dirty_bitmap_check(bitmap, BDRV_BITMAP_DEFAULT, errp)) { + ret =3D -ENOTSUP; + goto out; + } + } + +out: + bitmap_list_free(bm_list); + return ret; +} + /* store_bitmap_data() * Store bitmap to image, filling bitmap table accordingly. */ diff --git a/block/qcow2.c b/block/qcow2.c index c4dd876fb4..d48e2e56f7 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -3646,9 +3646,7 @@ static int coroutine_fn qcow2_co_truncate(BlockDriver= State *bs, int64_t offset, } =20 /* cannot proceed if image has bitmaps */ - if (s->nb_bitmaps) { - /* TODO: resize bitmaps in the image */ - error_setg(errp, "Can't resize an image which has bitmaps"); + if (qcow2_truncate_bitmaps_check(bs, errp)) { ret =3D -ENOTSUP; goto fail; } --=20 2.17.2