qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 12/17] qcow2-dirty-bitmap: add autoclear bit


From: Vladimir Sementsov-Ogievskiy
Subject: [Qemu-devel] [PATCH 12/17] qcow2-dirty-bitmap: add autoclear bit
Date: Sat, 5 Sep 2015 19:43:54 +0300

Add autoclear bit for handling rewriting image by old qemu version.

If autoclear bit is not set, but Dirty bitmaps extension is found it
would not be loaded and warning will be generated.

Signed-off-by: Vladimir Sementsov-Ogievskiy <address@hidden>
---
 block/qcow2-dirty-bitmap.c |  4 ++++
 block/qcow2.c              | 12 ++++++++++--
 block/qcow2.h              |  9 +++++++++
 3 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/block/qcow2-dirty-bitmap.c b/block/qcow2-dirty-bitmap.c
index 2687edc..e96ee18 100644
--- a/block/qcow2-dirty-bitmap.c
+++ b/block/qcow2-dirty-bitmap.c
@@ -448,6 +448,7 @@ static int directory_push_entry(BlockDriverState *bs, 
QCowDirtyBitmapHeader *hea
     int64_t new_offset = 0, old_offset = 0;
     uint64_t new_size = s->dirty_bitmap_directory_size + entry_size, old_size 
= 0;
     void *p;
+    uint64_t old_autocl;
 
     if (new_size > QCOW_MAX_DIRTY_BITMAP_DIRECTORY_SIZE) {
         return -EINVAL;
@@ -460,6 +461,7 @@ static int directory_push_entry(BlockDriverState *bs, 
QCowDirtyBitmapHeader *hea
 
     old_offset = s->dirty_bitmap_directory_offset;
     old_size = s->dirty_bitmap_directory_size;
+    old_autocl = s->autoclear_features;
 
     uint8_t *new_dir = g_try_malloc(new_size);
     if (new_dir == NULL) {
@@ -481,6 +483,7 @@ static int directory_push_entry(BlockDriverState *bs, 
QCowDirtyBitmapHeader *hea
 
     s->dirty_bitmap_directory_offset = new_offset;
     s->dirty_bitmap_directory_size = new_size;
+    s->autoclear_features |= QCOW2_AUTOCLEAR_DIRTY_BITMAPS;
 
     ret = update_header_sync(bs);
     if (ret < 0) {
@@ -502,6 +505,7 @@ fail:
         qcow2_free_clusters(bs, new_offset, new_size, QCOW2_DISCARD_ALWAYS);
         s->dirty_bitmap_directory_offset = old_offset;
         s->dirty_bitmap_directory_size = old_size;
+        s->autoclear_features = old_autocl;
     }
 
     p = g_try_realloc(s->dirty_bitmap_directory, 
s->dirty_bitmap_directory_size);
diff --git a/block/qcow2.c b/block/qcow2.c
index 36f404c..8791081 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -162,6 +162,13 @@ static int qcow2_read_extensions(BlockDriverState *bs, 
uint64_t start_offset,
             break;
 
         case QCOW2_EXT_MAGIC_DIRTY_BITMAPS:
+            if (!(s->autoclear_features & QCOW2_AUTOCLEAR_DIRTY_BITMAPS)) {
+                fprintf(stderr,
+                        "WARNING: dirty_bitmaps_ext: autoclear flag is not "
+                        "set, all bitmaps will be considered as inconsistent");
+                break;
+            }
+
             ret = bdrv_pread(bs->file, offset, &dirty_bitmaps_ext, ext.len);
             if (ret < 0) {
                 error_setg_errno(errp, -ret, "ERROR: dirty_bitmaps_ext: "
@@ -961,8 +968,9 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, 
int flags,
     }
 
     /* Clear unknown autoclear feature bits */
-    if (!bs->read_only && !(flags & BDRV_O_INCOMING) && s->autoclear_features) 
{
-        s->autoclear_features = 0;
+    if (!bs->read_only && !(flags & BDRV_O_INCOMING) &&
+        (s->autoclear_features & ~QCOW2_AUTOCLEAR_MASK)) {
+        s->autoclear_features &= QCOW2_AUTOCLEAR_MASK;
         ret = qcow2_update_header(bs);
         if (ret < 0) {
             error_setg_errno(errp, -ret, "Could not update qcow2 header");
diff --git a/block/qcow2.h b/block/qcow2.h
index 05f59e0..e699d39 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -216,6 +216,15 @@ enum {
     QCOW2_COMPAT_FEAT_MASK            = QCOW2_COMPAT_LAZY_REFCOUNTS,
 };
 
+/* Autoclear feature bits */
+enum {
+    QCOW2_AUTOCLEAR_DIRTY_BITMAPS_BITNR = 0,
+    QCOW2_AUTOCLEAR_DIRTY_BITMAPS       =
+        1 << QCOW2_AUTOCLEAR_DIRTY_BITMAPS_BITNR,
+
+    QCOW2_AUTOCLEAR_MASK                = QCOW2_AUTOCLEAR_DIRTY_BITMAPS,
+};
+
 enum qcow2_discard_type {
     QCOW2_DISCARD_NEVER = 0,
     QCOW2_DISCARD_ALWAYS,
-- 
2.1.4




reply via email to

[Prev in Thread] Current Thread [Next in Thread]