From patchwork Mon Sep 2 07:25:05 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Max Reitz X-Patchwork-Id: 271690 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 A67C92C009E for ; Mon, 2 Sep 2013 17:26:15 +1000 (EST) Received: from localhost ([::1]:37559 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VGOWb-0004w0-Hw for incoming@patchwork.ozlabs.org; Mon, 02 Sep 2013 03:26:13 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:57280) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VGOW1-0004uU-IW for qemu-devel@nongnu.org; Mon, 02 Sep 2013 03:25:43 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1VGOVv-0003w9-Hu for qemu-devel@nongnu.org; Mon, 02 Sep 2013 03:25:37 -0400 Received: from mx1.redhat.com ([209.132.183.28]:55546) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VGOVv-0003w5-8A for qemu-devel@nongnu.org; Mon, 02 Sep 2013 03:25:31 -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 r827PUIc014441 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Mon, 2 Sep 2013 03:25:30 -0400 Received: from localhost (dhcp-200-247.str.redhat.com [10.33.200.247]) by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id r827PT1f032226 (version=TLSv1/SSLv3 cipher=AES128-SHA bits=128 verify=NO); Mon, 2 Sep 2013 03:25:30 -0400 From: Max Reitz To: qemu-devel@nongnu.org Date: Mon, 2 Sep 2013 09:25:05 +0200 Message-Id: <1378106712-29856-2-git-send-email-mreitz@redhat.com> In-Reply-To: <1378106712-29856-1-git-send-email-mreitz@redhat.com> References: <1378106712-29856-1-git-send-email-mreitz@redhat.com> 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: Kevin Wolf , Stefan Hajnoczi , Max Reitz Subject: [Qemu-devel] [PATCH v5 1/8] qcow2: Add corrupt bit 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 adds an incompatible bit indicating corruption to qcow2. Any image with this bit set may not be written to unless for repairing (and subsequently clearing the bit if the repair has been successful). Signed-off-by: Max Reitz --- block/qcow2.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++ block/qcow2.h | 7 ++++++- docs/specs/qcow2.txt | 7 ++++++- tests/qemu-iotests/031.out | 12 ++++++------ tests/qemu-iotests/036.out | 2 +- 5 files changed, 66 insertions(+), 9 deletions(-) diff --git a/block/qcow2.c b/block/qcow2.c index 78097e5..16c9898 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -272,6 +272,37 @@ static int qcow2_mark_clean(BlockDriverState *bs) return 0; } +/* + * Marks the image as corrupt. + */ +int qcow2_mark_corrupt(BlockDriverState *bs) +{ + BDRVQcowState *s = bs->opaque; + + s->incompatible_features |= QCOW2_INCOMPAT_CORRUPT; + return qcow2_update_header(bs); +} + +/* + * Marks the image as consistent, i.e., unsets the corrupt bit, and flushes + * before if necessary. + */ +int qcow2_mark_consistent(BlockDriverState *bs) +{ + BDRVQcowState *s = bs->opaque; + + if (s->incompatible_features & QCOW2_INCOMPAT_CORRUPT) { + int ret = bdrv_flush(bs); + if (ret < 0) { + return ret; + } + + s->incompatible_features &= ~QCOW2_INCOMPAT_CORRUPT; + return qcow2_update_header(bs); + } + return 0; +} + static int qcow2_check(BlockDriverState *bs, BdrvCheckResult *result, BdrvCheckMode fix) { @@ -402,6 +433,17 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags) goto fail; } + if (s->incompatible_features & QCOW2_INCOMPAT_CORRUPT) { + /* Corrupt images may not be written to unless they are being repaired + */ + if ((flags & BDRV_O_RDWR) && !(flags & BDRV_O_CHECK)) { + error_report("qcow2: Image is corrupt; cannot be opened " + "read/write."); + ret = -EACCES; + goto fail; + } + } + /* Check support for various header values */ if (header.refcount_order != 4) { report_unsupported(bs, "%d bit reference counts", @@ -1130,6 +1172,11 @@ int qcow2_update_header(BlockDriverState *bs) .name = "dirty bit", }, { + .type = QCOW2_FEAT_TYPE_INCOMPATIBLE, + .bit = QCOW2_INCOMPAT_CORRUPT_BITNR, + .name = "corrupt bit", + }, + { .type = QCOW2_FEAT_TYPE_COMPATIBLE, .bit = QCOW2_COMPAT_LAZY_REFCOUNTS_BITNR, .name = "lazy refcounts", diff --git a/block/qcow2.h b/block/qcow2.h index dba9771..4297487 100644 --- a/block/qcow2.h +++ b/block/qcow2.h @@ -119,9 +119,12 @@ enum { /* Incompatible feature bits */ enum { QCOW2_INCOMPAT_DIRTY_BITNR = 0, + QCOW2_INCOMPAT_CORRUPT_BITNR = 1, QCOW2_INCOMPAT_DIRTY = 1 << QCOW2_INCOMPAT_DIRTY_BITNR, + QCOW2_INCOMPAT_CORRUPT = 1 << QCOW2_INCOMPAT_CORRUPT_BITNR, - QCOW2_INCOMPAT_MASK = QCOW2_INCOMPAT_DIRTY, + QCOW2_INCOMPAT_MASK = QCOW2_INCOMPAT_DIRTY + | QCOW2_INCOMPAT_CORRUPT, }; /* Compatible feature bits */ @@ -361,6 +364,8 @@ int qcow2_backing_read1(BlockDriverState *bs, QEMUIOVector *qiov, int64_t sector_num, int nb_sectors); int qcow2_mark_dirty(BlockDriverState *bs); +int qcow2_mark_corrupt(BlockDriverState *bs); +int qcow2_mark_consistent(BlockDriverState *bs); int qcow2_update_header(BlockDriverState *bs); /* qcow2-refcount.c functions */ diff --git a/docs/specs/qcow2.txt b/docs/specs/qcow2.txt index 36a559d..33eca36 100644 --- a/docs/specs/qcow2.txt +++ b/docs/specs/qcow2.txt @@ -80,7 +80,12 @@ in the description of a field. tables to repair refcounts before accessing the image. - Bits 1-63: Reserved (set to 0) + Bit 1: Corrupt bit. If this bit is set then any data + structure may be corrupt and the image must not + be written to (unless for regaining + consistency). + + Bits 2-63: Reserved (set to 0) 80 - 87: compatible_features Bitmask of compatible features. An implementation can diff --git a/tests/qemu-iotests/031.out b/tests/qemu-iotests/031.out index 796c993..a943344 100644 --- a/tests/qemu-iotests/031.out +++ b/tests/qemu-iotests/031.out @@ -54,7 +54,7 @@ header_length 72 Header extension: magic 0x6803f857 -length 96 +length 144 data Header extension: @@ -68,7 +68,7 @@ No errors were found on the image. magic 0x514649fb version 2 -backing_file_offset 0xf8 +backing_file_offset 0x128 backing_file_size 0x17 cluster_bits 16 size 67108864 @@ -92,7 +92,7 @@ data 'host_device' Header extension: magic 0x6803f857 -length 96 +length 144 data Header extension: @@ -155,7 +155,7 @@ header_length 104 Header extension: magic 0x6803f857 -length 96 +length 144 data Header extension: @@ -169,7 +169,7 @@ No errors were found on the image. magic 0x514649fb version 3 -backing_file_offset 0x118 +backing_file_offset 0x148 backing_file_size 0x17 cluster_bits 16 size 67108864 @@ -193,7 +193,7 @@ data 'host_device' Header extension: magic 0x6803f857 -length 96 +length 144 data Header extension: diff --git a/tests/qemu-iotests/036.out b/tests/qemu-iotests/036.out index 063ca22..55a3e6e 100644 --- a/tests/qemu-iotests/036.out +++ b/tests/qemu-iotests/036.out @@ -46,7 +46,7 @@ header_length 104 Header extension: magic 0x6803f857 -length 96 +length 144 data *** done