qemu-block
[Top][All Lists]
Advanced

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

[PATCH v5 14/22] parallels: Preserve extensions cluster for non-transien


From: Alexander Ivanov
Subject: [PATCH v5 14/22] parallels: Preserve extensions cluster for non-transient extensions
Date: Mon, 11 Mar 2024 19:18:42 +0100

There could be non-transient extensions that require presence of the
extensions cluster during work. Mark extensions cluster as used at
extensions loading end nullify l1 tables of dirty bitmaps.
Use this cluster at dirty bitmap saving if it exists.

Signed-off-by: Alexander Ivanov <alexander.ivanov@virtuozzo.com>
---
 block/parallels-ext.c | 49 ++++++++++++++++++++++++++++++-------------
 1 file changed, 35 insertions(+), 14 deletions(-)

diff --git a/block/parallels-ext.c b/block/parallels-ext.c
index 2d839006a4..1ec23aa1e7 100644
--- a/block/parallels-ext.c
+++ b/block/parallels-ext.c
@@ -122,7 +122,7 @@ finish:
  */
 static BdrvDirtyBitmap * GRAPH_RDLOCK
 parallels_load_bitmap(BlockDriverState *bs, uint8_t *data, size_t data_size,
-                      Error **errp)
+                      int64_t ext_off, Error **errp)
 {
     int ret;
     ParallelsDirtyBitmapFeature bf;
@@ -130,6 +130,7 @@ parallels_load_bitmap(BlockDriverState *bs, uint8_t *data, 
size_t data_size,
     BdrvDirtyBitmap *bitmap;
     QemuUUID uuid;
     char uuidstr[UUID_STR_LEN];
+    int64_t l1_off;
     int i;
 
     if (data_size < sizeof(bf)) {
@@ -171,16 +172,29 @@ parallels_load_bitmap(BlockDriverState *bs, uint8_t 
*data, size_t data_size,
 
     ret = parallels_load_bitmap_data(bs, l1_table, bf.l1_size, bitmap, errp);
     if (ret < 0) {
-        bdrv_release_dirty_bitmap(bitmap);
-        return NULL;
+        goto err;
+    }
+
+    if (!(bs->open_flags & BDRV_O_RDWR)) {
+        return bitmap;
+    }
+
+    l1_off = ext_off + sizeof(ParallelsDirtyBitmapFeature);
+    ret = bdrv_pwrite_zeroes(bs->file, l1_off,
+                             bf.l1_size * sizeof(uint64_t), 0);
+    if (ret < 0) {
+        goto err;
     }
 
     return bitmap;
+err:
+    bdrv_release_dirty_bitmap(bitmap);
+    return NULL;
 }
 
 static int GRAPH_RDLOCK
-parallels_parse_format_extension(BlockDriverState *bs, uint8_t *ext_cluster,
-                                 Error **errp)
+parallels_parse_format_extension(BlockDriverState *bs, int64_t ext_off,
+                                 uint8_t *ext_cluster, Error **errp)
 {
     BDRVParallelsState *s = bs->opaque;
     int ret;
@@ -259,7 +273,8 @@ parallels_parse_format_extension(BlockDriverState *bs, 
uint8_t *ext_cluster,
                  */
                 break;
             }
-            bitmap = parallels_load_bitmap(bs, pos, fh.data_size, errp);
+            bitmap = parallels_load_bitmap(bs, pos, fh.data_size,
+                                           ext_off + pos - ext_cluster, errp);
             if (!bitmap) {
                 goto fail;
             }
@@ -298,7 +313,11 @@ int parallels_read_format_extension(BlockDriverState *bs,
         goto out;
     }
 
-    ret = parallels_parse_format_extension(bs, ext_cluster, errp);
+    ret = parallels_parse_format_extension(bs, ext_off, ext_cluster, errp);
+    if (ret == 0) {
+        ret = parallels_mark_used(bs, s->used_bmap, s->used_bmap_size,
+                                  ext_off, 1);
+    }
 
 out:
     qemu_vfree(ext_cluster);
@@ -429,8 +448,6 @@ parallels_store_persistent_dirty_bitmaps(BlockDriverState 
*bs, Error **errp)
     size_t hash_len = 0;
     int ret;
 
-    s->header->ext_off = 0;
-
     if (!bdrv_has_named_bitmaps(bs)) {
         return 0;
     }
@@ -447,11 +464,15 @@ parallels_store_persistent_dirty_bitmaps(BlockDriverState 
*bs, Error **errp)
         parallels_save_bitmap(bs, bitmap, &pos, &remaining);
     }
 
-    header_off = parallels_allocate_host_clusters(bs, &alloc_size);
-    if (header_off < 0) {
-        error_report("Can't save dirty bitmap: cluster allocation error");
-        ret = header_off;
-        goto end;
+    if (s->header->ext_off) {
+        header_off = le64_to_cpu(s->header->ext_off) << BDRV_SECTOR_BITS;
+    } else {
+        header_off = parallels_allocate_host_clusters(bs, &alloc_size);
+        if (header_off < 0) {
+            error_report("Can't save dirty bitmap: cluster allocation error");
+            ret = header_off;
+            goto end;
+        }
     }
 
     ret = qcrypto_hash_bytes(QCRYPTO_HASH_ALG_MD5,
-- 
2.40.1




reply via email to

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