From patchwork Mon Apr 16 15:02:00 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kevin Wolf X-Patchwork-Id: 152884 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id BDBD3B7005 for ; Tue, 17 Apr 2012 00:59:06 +1000 (EST) Received: from localhost ([::1]:53887 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SJnOS-0002HN-Kc for incoming@patchwork.ozlabs.org; Mon, 16 Apr 2012 10:59:04 -0400 Received: from eggs.gnu.org ([208.118.235.92]:40531) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SJnO6-0001xL-Gu for qemu-devel@nongnu.org; Mon, 16 Apr 2012 10:58:48 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SJnO3-0007jL-VB for qemu-devel@nongnu.org; Mon, 16 Apr 2012 10:58:42 -0400 Received: from mx1.redhat.com ([209.132.183.28]:56105) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SJnO3-0007jA-N7 for qemu-devel@nongnu.org; Mon, 16 Apr 2012 10:58:39 -0400 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q3GEwbNw009427 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Mon, 16 Apr 2012 10:58:37 -0400 Received: from dhcp-5-188.str.redhat.com (vpn1-5-41.ams2.redhat.com [10.36.5.41]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id q3GEwVUi010388; Mon, 16 Apr 2012 10:58:35 -0400 From: Kevin Wolf To: qemu-devel@nongnu.org Date: Mon, 16 Apr 2012 17:02:00 +0200 Message-Id: <1334588536-16313-3-git-send-email-kwolf@redhat.com> In-Reply-To: <1334588536-16313-1-git-send-email-kwolf@redhat.com> References: <1334588536-16313-1-git-send-email-kwolf@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.132.183.28 Cc: kwolf@redhat.com, stefanha@gmail.com, freddy77@gmail.com, pbonzini@redhat.com Subject: [Qemu-devel] [PATCH v2 02/18] qcow2: Save disk size in snapshot header X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org This allows that different snapshots of an image can have different sizes, which is a requirement for enabling image resizing even with images that have internal snapshots. We don't do the actual support for it now, but make sure that the additional field is present and not completely ignored in all version 3 images. When trying to load a snapshot of different size, it returns an error. Signed-off-by: Kevin Wolf --- block/qcow2-snapshot.c | 16 ++++++++++++++++ block/qcow2.h | 1 + 2 files changed, 17 insertions(+), 0 deletions(-) diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c index 7d3fde5..42f971b 100644 --- a/block/qcow2-snapshot.c +++ b/block/qcow2-snapshot.c @@ -48,6 +48,7 @@ typedef struct QEMU_PACKED QCowSnapshotHeader { typedef struct QEMU_PACKED QCowSnapshotExtraData { uint64_t vm_state_size_large; + uint64_t disk_size; } QCowSnapshotExtraData; void qcow2_free_snapshots(BlockDriverState *bs) @@ -117,6 +118,12 @@ int qcow2_read_snapshots(BlockDriverState *bs) sn->vm_state_size = be64_to_cpu(extra.vm_state_size_large); } + if (extra_data_size >= 16) { + sn->disk_size = be64_to_cpu(extra.disk_size); + } else { + sn->disk_size = bs->total_sectors * BDRV_SECTOR_SIZE; + } + /* Read snapshot ID */ sn->id_str = g_malloc(id_str_size + 1); ret = bdrv_pread(bs->file, offset, sn->id_str, id_str_size); @@ -197,6 +204,7 @@ static int qcow2_write_snapshots(BlockDriverState *bs) memset(&extra, 0, sizeof(extra)); extra.vm_state_size_large = cpu_to_be64(sn->vm_state_size); + extra.disk_size = cpu_to_be64(sn->disk_size); id_str_size = strlen(sn->id_str); name_size = strlen(sn->name); @@ -330,6 +338,7 @@ int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info) sn->id_str = g_strdup(sn_info->id_str); sn->name = g_strdup(sn_info->name); + sn->disk_size = bs->total_sectors * BDRV_SECTOR_SIZE; sn->vm_state_size = sn_info->vm_state_size; sn->date_sec = sn_info->date_sec; sn->date_nsec = sn_info->date_nsec; @@ -426,6 +435,13 @@ int qcow2_snapshot_goto(BlockDriverState *bs, const char *snapshot_id) } sn = &s->snapshots[snapshot_index]; + if (sn->disk_size != bs->total_sectors * BDRV_SECTOR_SIZE) { + error_report("qcow2: Loading snapshots with different disk " + "size is not implemented"); + ret = -ENOTSUP; + goto fail; + } + /* * Make sure that the current L1 table is big enough to contain the whole * L1 table of the snapshot. If the snapshot L1 table is smaller, the diff --git a/block/qcow2.h b/block/qcow2.h index e4ac366..ddb976a 100644 --- a/block/qcow2.h +++ b/block/qcow2.h @@ -78,6 +78,7 @@ typedef struct QCowSnapshot { uint32_t l1_size; char *id_str; char *name; + uint64_t disk_size; uint64_t vm_state_size; uint32_t date_sec; uint32_t date_nsec;