|
|
9ae3a8 |
From 0e79ef6691f77a7c0da31dff9276b6dad42441a0 Mon Sep 17 00:00:00 2001
|
|
|
9ae3a8 |
From: Max Reitz <mreitz@redhat.com>
|
|
|
9ae3a8 |
Date: Mon, 4 Nov 2013 22:31:59 +0100
|
|
|
9ae3a8 |
Subject: [PATCH 06/87] qcow2: Add corrupt bit
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
RH-Author: Max Reitz <mreitz@redhat.com>
|
|
|
9ae3a8 |
Message-id: <1383604354-12743-9-git-send-email-mreitz@redhat.com>
|
|
|
9ae3a8 |
Patchwork-id: 55308
|
|
|
9ae3a8 |
O-Subject: [RHEL-7.0 qemu-kvm PATCH 08/43] qcow2: Add corrupt bit
|
|
|
9ae3a8 |
Bugzilla: 1004347
|
|
|
9ae3a8 |
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
|
|
|
9ae3a8 |
RH-Acked-by: Laszlo Ersek <lersek@redhat.com>
|
|
|
9ae3a8 |
RH-Acked-by: Fam Zheng <famz@redhat.com>
|
|
|
9ae3a8 |
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
BZ: 1004347
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
This adds an incompatible bit indicating corruption to qcow2. Any image
|
|
|
9ae3a8 |
with this bit set may not be written to unless for repairing (and
|
|
|
9ae3a8 |
subsequently clearing the bit if the repair has been successful).
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Signed-off-by: Max Reitz <mreitz@redhat.com>
|
|
|
9ae3a8 |
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
|
|
9ae3a8 |
(cherry picked from commit 69c98726537627e708abb8fcb33e3a2b10e40bf1)
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Signed-off-by: Max Reitz <mreitz@redhat.com>
|
|
|
9ae3a8 |
---
|
|
|
9ae3a8 |
block/qcow2.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
9ae3a8 |
block/qcow2.h | 7 ++++++-
|
|
|
9ae3a8 |
docs/specs/qcow2.txt | 7 ++++++-
|
|
|
9ae3a8 |
tests/qemu-iotests/031.out | 12 ++++++------
|
|
|
9ae3a8 |
tests/qemu-iotests/036.out | 2 +-
|
|
|
9ae3a8 |
5 files changed, 66 insertions(+), 9 deletions(-)
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
9ae3a8 |
---
|
|
|
9ae3a8 |
block/qcow2.c | 47 ++++++++++++++++++++++++++++++++++++++++++++
|
|
|
9ae3a8 |
block/qcow2.h | 7 +++++-
|
|
|
9ae3a8 |
docs/specs/qcow2.txt | 7 +++++-
|
|
|
9ae3a8 |
tests/qemu-iotests/031.out | 12 +++++-----
|
|
|
9ae3a8 |
tests/qemu-iotests/036.out | 2 +-
|
|
|
9ae3a8 |
5 files changed, 66 insertions(+), 9 deletions(-)
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
diff --git a/block/qcow2.c b/block/qcow2.c
|
|
|
9ae3a8 |
index c2728c9..aa9dd23 100644
|
|
|
9ae3a8 |
--- a/block/qcow2.c
|
|
|
9ae3a8 |
+++ b/block/qcow2.c
|
|
|
9ae3a8 |
@@ -272,6 +272,37 @@ static int qcow2_mark_clean(BlockDriverState *bs)
|
|
|
9ae3a8 |
return 0;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
+/*
|
|
|
9ae3a8 |
+ * Marks the image as corrupt.
|
|
|
9ae3a8 |
+ */
|
|
|
9ae3a8 |
+int qcow2_mark_corrupt(BlockDriverState *bs)
|
|
|
9ae3a8 |
+{
|
|
|
9ae3a8 |
+ BDRVQcowState *s = bs->opaque;
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+ s->incompatible_features |= QCOW2_INCOMPAT_CORRUPT;
|
|
|
9ae3a8 |
+ return qcow2_update_header(bs);
|
|
|
9ae3a8 |
+}
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+/*
|
|
|
9ae3a8 |
+ * Marks the image as consistent, i.e., unsets the corrupt bit, and flushes
|
|
|
9ae3a8 |
+ * before if necessary.
|
|
|
9ae3a8 |
+ */
|
|
|
9ae3a8 |
+int qcow2_mark_consistent(BlockDriverState *bs)
|
|
|
9ae3a8 |
+{
|
|
|
9ae3a8 |
+ BDRVQcowState *s = bs->opaque;
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+ if (s->incompatible_features & QCOW2_INCOMPAT_CORRUPT) {
|
|
|
9ae3a8 |
+ int ret = bdrv_flush(bs);
|
|
|
9ae3a8 |
+ if (ret < 0) {
|
|
|
9ae3a8 |
+ return ret;
|
|
|
9ae3a8 |
+ }
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+ s->incompatible_features &= ~QCOW2_INCOMPAT_CORRUPT;
|
|
|
9ae3a8 |
+ return qcow2_update_header(bs);
|
|
|
9ae3a8 |
+ }
|
|
|
9ae3a8 |
+ return 0;
|
|
|
9ae3a8 |
+}
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
static int qcow2_check(BlockDriverState *bs, BdrvCheckResult *result,
|
|
|
9ae3a8 |
BdrvCheckMode fix)
|
|
|
9ae3a8 |
{
|
|
|
9ae3a8 |
@@ -402,6 +433,17 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags)
|
|
|
9ae3a8 |
goto fail;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
+ if (s->incompatible_features & QCOW2_INCOMPAT_CORRUPT) {
|
|
|
9ae3a8 |
+ /* Corrupt images may not be written to unless they are being repaired
|
|
|
9ae3a8 |
+ */
|
|
|
9ae3a8 |
+ if ((flags & BDRV_O_RDWR) && !(flags & BDRV_O_CHECK)) {
|
|
|
9ae3a8 |
+ error_report("qcow2: Image is corrupt; cannot be opened "
|
|
|
9ae3a8 |
+ "read/write.");
|
|
|
9ae3a8 |
+ ret = -EACCES;
|
|
|
9ae3a8 |
+ goto fail;
|
|
|
9ae3a8 |
+ }
|
|
|
9ae3a8 |
+ }
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
/* Check support for various header values */
|
|
|
9ae3a8 |
if (header.refcount_order != 4) {
|
|
|
9ae3a8 |
report_unsupported(bs, "%d bit reference counts",
|
|
|
9ae3a8 |
@@ -1140,6 +1182,11 @@ int qcow2_update_header(BlockDriverState *bs)
|
|
|
9ae3a8 |
.name = "dirty bit",
|
|
|
9ae3a8 |
},
|
|
|
9ae3a8 |
{
|
|
|
9ae3a8 |
+ .type = QCOW2_FEAT_TYPE_INCOMPATIBLE,
|
|
|
9ae3a8 |
+ .bit = QCOW2_INCOMPAT_CORRUPT_BITNR,
|
|
|
9ae3a8 |
+ .name = "corrupt bit",
|
|
|
9ae3a8 |
+ },
|
|
|
9ae3a8 |
+ {
|
|
|
9ae3a8 |
.type = QCOW2_FEAT_TYPE_COMPATIBLE,
|
|
|
9ae3a8 |
.bit = QCOW2_COMPAT_LAZY_REFCOUNTS_BITNR,
|
|
|
9ae3a8 |
.name = "lazy refcounts",
|
|
|
9ae3a8 |
diff --git a/block/qcow2.h b/block/qcow2.h
|
|
|
9ae3a8 |
index dba9771..4297487 100644
|
|
|
9ae3a8 |
--- a/block/qcow2.h
|
|
|
9ae3a8 |
+++ b/block/qcow2.h
|
|
|
9ae3a8 |
@@ -119,9 +119,12 @@ enum {
|
|
|
9ae3a8 |
/* Incompatible feature bits */
|
|
|
9ae3a8 |
enum {
|
|
|
9ae3a8 |
QCOW2_INCOMPAT_DIRTY_BITNR = 0,
|
|
|
9ae3a8 |
+ QCOW2_INCOMPAT_CORRUPT_BITNR = 1,
|
|
|
9ae3a8 |
QCOW2_INCOMPAT_DIRTY = 1 << QCOW2_INCOMPAT_DIRTY_BITNR,
|
|
|
9ae3a8 |
+ QCOW2_INCOMPAT_CORRUPT = 1 << QCOW2_INCOMPAT_CORRUPT_BITNR,
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
- QCOW2_INCOMPAT_MASK = QCOW2_INCOMPAT_DIRTY,
|
|
|
9ae3a8 |
+ QCOW2_INCOMPAT_MASK = QCOW2_INCOMPAT_DIRTY
|
|
|
9ae3a8 |
+ | QCOW2_INCOMPAT_CORRUPT,
|
|
|
9ae3a8 |
};
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
/* Compatible feature bits */
|
|
|
9ae3a8 |
@@ -361,6 +364,8 @@ int qcow2_backing_read1(BlockDriverState *bs, QEMUIOVector *qiov,
|
|
|
9ae3a8 |
int64_t sector_num, int nb_sectors);
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
int qcow2_mark_dirty(BlockDriverState *bs);
|
|
|
9ae3a8 |
+int qcow2_mark_corrupt(BlockDriverState *bs);
|
|
|
9ae3a8 |
+int qcow2_mark_consistent(BlockDriverState *bs);
|
|
|
9ae3a8 |
int qcow2_update_header(BlockDriverState *bs);
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
/* qcow2-refcount.c functions */
|
|
|
9ae3a8 |
diff --git a/docs/specs/qcow2.txt b/docs/specs/qcow2.txt
|
|
|
9ae3a8 |
index 36a559d..33eca36 100644
|
|
|
9ae3a8 |
--- a/docs/specs/qcow2.txt
|
|
|
9ae3a8 |
+++ b/docs/specs/qcow2.txt
|
|
|
9ae3a8 |
@@ -80,7 +80,12 @@ in the description of a field.
|
|
|
9ae3a8 |
tables to repair refcounts before accessing the
|
|
|
9ae3a8 |
image.
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
- Bits 1-63: Reserved (set to 0)
|
|
|
9ae3a8 |
+ Bit 1: Corrupt bit. If this bit is set then any data
|
|
|
9ae3a8 |
+ structure may be corrupt and the image must not
|
|
|
9ae3a8 |
+ be written to (unless for regaining
|
|
|
9ae3a8 |
+ consistency).
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+ Bits 2-63: Reserved (set to 0)
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
80 - 87: compatible_features
|
|
|
9ae3a8 |
Bitmask of compatible features. An implementation can
|
|
|
9ae3a8 |
diff --git a/tests/qemu-iotests/031.out b/tests/qemu-iotests/031.out
|
|
|
9ae3a8 |
index 796c993..a943344 100644
|
|
|
9ae3a8 |
--- a/tests/qemu-iotests/031.out
|
|
|
9ae3a8 |
+++ b/tests/qemu-iotests/031.out
|
|
|
9ae3a8 |
@@ -54,7 +54,7 @@ header_length 72
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Header extension:
|
|
|
9ae3a8 |
magic 0x6803f857
|
|
|
9ae3a8 |
-length 96
|
|
|
9ae3a8 |
+length 144
|
|
|
9ae3a8 |
data <binary>
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Header extension:
|
|
|
9ae3a8 |
@@ -68,7 +68,7 @@ No errors were found on the image.
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
magic 0x514649fb
|
|
|
9ae3a8 |
version 2
|
|
|
9ae3a8 |
-backing_file_offset 0xf8
|
|
|
9ae3a8 |
+backing_file_offset 0x128
|
|
|
9ae3a8 |
backing_file_size 0x17
|
|
|
9ae3a8 |
cluster_bits 16
|
|
|
9ae3a8 |
size 67108864
|
|
|
9ae3a8 |
@@ -92,7 +92,7 @@ data 'host_device'
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Header extension:
|
|
|
9ae3a8 |
magic 0x6803f857
|
|
|
9ae3a8 |
-length 96
|
|
|
9ae3a8 |
+length 144
|
|
|
9ae3a8 |
data <binary>
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Header extension:
|
|
|
9ae3a8 |
@@ -155,7 +155,7 @@ header_length 104
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Header extension:
|
|
|
9ae3a8 |
magic 0x6803f857
|
|
|
9ae3a8 |
-length 96
|
|
|
9ae3a8 |
+length 144
|
|
|
9ae3a8 |
data <binary>
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Header extension:
|
|
|
9ae3a8 |
@@ -169,7 +169,7 @@ No errors were found on the image.
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
magic 0x514649fb
|
|
|
9ae3a8 |
version 3
|
|
|
9ae3a8 |
-backing_file_offset 0x118
|
|
|
9ae3a8 |
+backing_file_offset 0x148
|
|
|
9ae3a8 |
backing_file_size 0x17
|
|
|
9ae3a8 |
cluster_bits 16
|
|
|
9ae3a8 |
size 67108864
|
|
|
9ae3a8 |
@@ -193,7 +193,7 @@ data 'host_device'
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Header extension:
|
|
|
9ae3a8 |
magic 0x6803f857
|
|
|
9ae3a8 |
-length 96
|
|
|
9ae3a8 |
+length 144
|
|
|
9ae3a8 |
data <binary>
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Header extension:
|
|
|
9ae3a8 |
diff --git a/tests/qemu-iotests/036.out b/tests/qemu-iotests/036.out
|
|
|
9ae3a8 |
index 063ca22..55a3e6e 100644
|
|
|
9ae3a8 |
--- a/tests/qemu-iotests/036.out
|
|
|
9ae3a8 |
+++ b/tests/qemu-iotests/036.out
|
|
|
9ae3a8 |
@@ -46,7 +46,7 @@ header_length 104
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Header extension:
|
|
|
9ae3a8 |
magic 0x6803f857
|
|
|
9ae3a8 |
-length 96
|
|
|
9ae3a8 |
+length 144
|
|
|
9ae3a8 |
data <binary>
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
*** done
|
|
|
9ae3a8 |
--
|
|
|
9ae3a8 |
1.7.1
|
|
|
9ae3a8 |
|