[20/29] qcow2-bitmap: add AUTO flag
diff mbox

Message ID 1470668720-211300-21-git-send-email-vsementsov@virtuozzo.com
State New
Headers show

Commit Message

Vladimir Sementsov-Ogievskiy Aug. 8, 2016, 3:05 p.m. UTC
The bitmap should be auto-loaded if auto flag is set.

Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
---
 block/qcow2-bitmap.c | 40 +++++++++++++++++++++++++++++++++++++++-
 1 file changed, 39 insertions(+), 1 deletion(-)

Patch
diff mbox

diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
index bfc1db8..1c46dcb 100644
--- a/block/qcow2-bitmap.c
+++ b/block/qcow2-bitmap.c
@@ -44,8 +44,9 @@ 
 #define BME_MAX_NAME_SIZE 1023
 
 /* Bitmap directory entry flags */
-#define BME_RESERVED_FLAGS 0xfffffffe
+#define BME_RESERVED_FLAGS 0xfffffffc
 #define BME_FLAG_IN_USE 1
+#define BME_FLAG_AUTO   (1U << 1)
 
 /* bits [1, 8] U [56, 63] are reserved */
 #define BME_TABLE_ENTRY_RESERVED_MASK 0xff000000000001fe
@@ -68,6 +69,9 @@  static inline bool can_write(BlockDriverState *bs)
     return !bdrv_is_read_only(bs) && !(bdrv_get_flags(bs) & BDRV_O_INACTIVE);
 }
 
+static BdrvDirtyBitmap *load_bitmap(BlockDriverState *bs, QCow2BitmapHeader *h,
+                                    Error **errp);
+
 void qcow2_free_bitmaps(BlockDriverState *bs)
 {
     BDRVQcow2State *s = bs->opaque;
@@ -214,8 +218,31 @@  fail:
     return NULL;
 }
 
+static int load_autoload_bitmaps(BlockDriverState *bs, Error **errp)
+{
+    BDRVQcow2State *s = bs->opaque;
+    QCow2BitmapHeader *h;
+
+    for_each_bitmap_header(h, s) {
+        uint32_t fl = h->flags;
+
+        if ((fl & BME_FLAG_AUTO) && !(fl & BME_FLAG_IN_USE)) {
+            BdrvDirtyBitmap *bitmap = load_bitmap(bs, h, errp);
+            if (bitmap == NULL) {
+                return -1;
+            }
+
+            bdrv_dirty_bitmap_set_persistance(bitmap, true);
+            bdrv_dirty_bitmap_set_autoload(bitmap, true);
+        }
+    }
+
+    return 0;
+}
+
 int qcow2_read_bitmaps(BlockDriverState *bs, Error **errp)
 {
+    int ret;
     BDRVQcow2State *s = bs->opaque;
 
     if (s->bitmap_directory != NULL) {
@@ -234,7 +261,18 @@  int qcow2_read_bitmaps(BlockDriverState *bs, Error **errp)
         return -EINVAL;
     }
 
+    ret = load_autoload_bitmaps(bs, errp);
+    if (ret < 0) {
+        goto fail;
+    }
+
     return 0;
+
+fail:
+    g_free(s->bitmap_directory);
+    s->bitmap_directory = NULL;
+
+    return ret;
 }
 
 static QCow2BitmapHeader *find_bitmap_by_name(BlockDriverState *bs,