From patchwork Wed Jul 24 17:54:42 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Cody X-Patchwork-Id: 261484 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 833F42C0082 for ; Thu, 25 Jul 2013 03:58:41 +1000 (EST) Received: from localhost ([::1]:59180 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V23Kh-0000ee-9K for incoming@patchwork.ozlabs.org; Wed, 24 Jul 2013 13:58:39 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41124) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V23HN-0004R1-RX for qemu-devel@nongnu.org; Wed, 24 Jul 2013 13:55:16 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1V23HH-0001wg-4D for qemu-devel@nongnu.org; Wed, 24 Jul 2013 13:55:13 -0400 Received: from mx1.redhat.com ([209.132.183.28]:43174) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V23HG-0001wN-S2 for qemu-devel@nongnu.org; Wed, 24 Jul 2013 13:55:07 -0400 Received: from int-mx11.intmail.prod.int.phx2.redhat.com (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r6OHt6V4031582 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Wed, 24 Jul 2013 13:55:06 -0400 Received: from localhost ([10.3.112.10]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id r6OHt3GR027588 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES128-SHA bits=128 verify=NO); Wed, 24 Jul 2013 13:55:05 -0400 From: Jeff Cody To: qemu-devel@nongnu.org Date: Wed, 24 Jul 2013 13:54:42 -0400 Message-Id: <3f8e3c52562aef30e182cd81be1320cf3e0d94c7.1374687002.git.jcody@redhat.com> In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: kwolf@redhat.com, stefanha@redhat.com Subject: [Qemu-devel] [PATCH 6/9] block: vhdx - update log guid in header, and first write tracker 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 Allow tracking of first file write in the VHDX image, as well as the ability to update the GUID in the header. This is in preparation for log support. Signed-off-by: Jeff Cody --- block/vhdx.c | 28 +++++++++++++++++++++++----- block/vhdx.h | 7 +++++-- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/block/vhdx.c b/block/vhdx.c index 9f7f04f..f5689c3 100644 --- a/block/vhdx.c +++ b/block/vhdx.c @@ -233,7 +233,8 @@ static int vhdx_probe(const uint8_t *buf, int buf_size, const char *filename) * * - non-current header is updated with largest sequence number */ -static int vhdx_update_header(BlockDriverState *bs, BDRVVHDXState *s, bool rw) +static int vhdx_update_header(BlockDriverState *bs, BDRVVHDXState *s, bool rw, + MSGUID *log_guid) { int ret = 0; int hdr_idx = 0; @@ -266,6 +267,11 @@ static int vhdx_update_header(BlockDriverState *bs, BDRVVHDXState *s, bool rw) vhdx_guid_generate(&inactive_header->data_write_guid); } + /* update the log guid if present */ + if (log_guid) { + memcpy(&inactive_header->log_guid, log_guid, sizeof(MSGUID)); + } + /* the header checksum is not over just the packed size of VHDXHeader, * but rather over the entire 'reserved' range for the header, which is * 4KB (VHDX_HEADER_SIZE). */ @@ -293,15 +299,16 @@ fail: * The VHDX spec calls for header updates to be performed twice, so that both * the current and non-current header have valid info */ -static int vhdx_update_headers(BlockDriverState *bs, BDRVVHDXState *s, bool rw) +int vhdx_update_headers(BlockDriverState *bs, BDRVVHDXState *s, bool rw, + MSGUID *log_guid) { int ret; - ret = vhdx_update_header(bs, s, rw); + ret = vhdx_update_header(bs, s, rw, log_guid); if (ret < 0) { return ret; } - ret = vhdx_update_header(bs, s, rw); + ret = vhdx_update_header(bs, s, rw, log_guid); return ret; } @@ -781,6 +788,7 @@ static int vhdx_open(BlockDriverState *bs, QDict *options, int flags) s->bat = NULL; + s->first_visible_write = true; qemu_co_mutex_init(&s->lock); @@ -861,7 +869,7 @@ static int vhdx_open(BlockDriverState *bs, QDict *options, int flags) } if (flags & BDRV_O_RDWR) { - vhdx_update_headers(bs, s, false); + vhdx_update_headers(bs, s, false, NULL); } /* TODO: differencing files, write */ @@ -998,6 +1006,16 @@ exit: +/* Per the spec, on the first write of guest-visible data to the file the + * data write guid must be updated in the header */ +void vhdx_user_visible_write(BlockDriverState *bs, BDRVVHDXState *s) +{ + if (s->first_visible_write) { + s->first_visible_write = false; + vhdx_update_headers(bs, s, true, NULL); + } +} + static coroutine_fn int vhdx_co_writev(BlockDriverState *bs, int64_t sector_num, int nb_sectors, QEMUIOVector *qiov) { diff --git a/block/vhdx.h b/block/vhdx.h index 5e0a1d3..cb3ce0e 100644 --- a/block/vhdx.h +++ b/block/vhdx.h @@ -366,6 +366,7 @@ typedef struct BDRVVHDXState { VHDXBatEntry *bat; uint64_t bat_offset; + bool first_visible_write; MSGUID session_guid; VHDXLogEntries log; @@ -377,6 +378,9 @@ typedef struct BDRVVHDXState { void vhdx_guid_generate(MSGUID *guid); +int vhdx_update_headers(BlockDriverState *bs, BDRVVHDXState *s, bool rw, + MSGUID *log_guid); + uint32_t vhdx_update_checksum(uint8_t *buf, size_t size, int crc_offset); uint32_t vhdx_checksum_calc(uint32_t crc, uint8_t *buf, size_t size, int crc_offset); @@ -406,8 +410,7 @@ void vhdx_log_data_le_export(VHDXLogDataSector *d); void vhdx_log_entry_hdr_le_import(VHDXLogEntryHeader *hdr); void vhdx_log_entry_hdr_le_export(VHDXLogEntryHeader *hdr); - - +void vhdx_user_visible_write(BlockDriverState *bs, BDRVVHDXState *s);