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