Patchwork [v3,2/6] block: Add ImageInfoSpecific to BlockDriverInfo

login
register
mail settings
Submitter Max Reitz
Date Sept. 10, 2013, 9:33 a.m.
Message ID <1378805602-24044-3-git-send-email-mreitz@redhat.com>
Download mbox | patch
Permalink /patch/273797/
State New
Headers show

Comments

Max Reitz - Sept. 10, 2013, 9:33 a.m.
Add the new ImageInfoSpecific type also to BlockDriverInfo, as well as a
bdrv_put_info function which releases all data allocated by
bdrv_get_info from BlockDriverInfo (such as the new ImageInfoSpecific
field).

To prevent memory leaks, bdrv_put_info has to be called on every
BlockDriverInfo object when it is no longer required (and bdrv_get_info
has been successful).

Signed-off-by: Max Reitz <mreitz@redhat.com>
---
 block.c               | 16 +++++++++++++++-
 block/mirror.c        | 16 +++++++++++-----
 block/qapi.c          |  4 ++++
 include/block/block.h |  3 +++
 qemu-img.c            |  1 +
 qemu-io-cmds.c        |  2 ++
 6 files changed, 36 insertions(+), 6 deletions(-)

Patch

diff --git a/block.c b/block.c
index 26639e8..2e74fc0 100644
--- a/block.c
+++ b/block.c
@@ -1922,8 +1922,10 @@  void bdrv_round_to_clusters(BlockDriverState *bs,
                             int *cluster_nb_sectors)
 {
     BlockDriverInfo bdi;
+    int ret;
 
-    if (bdrv_get_info(bs, &bdi) < 0 || bdi.cluster_size == 0) {
+    ret = bdrv_get_info(bs, &bdi);
+    if (ret < 0 || bdi.cluster_size == 0) {
         *cluster_sector_num = sector_num;
         *cluster_nb_sectors = nb_sectors;
     } else {
@@ -1932,6 +1934,9 @@  void bdrv_round_to_clusters(BlockDriverState *bs,
         *cluster_nb_sectors = QEMU_ALIGN_UP(sector_num - *cluster_sector_num +
                                             nb_sectors, c);
     }
+    if (ret >= 0) {
+        bdrv_put_info(bs, &bdi);
+    }
 }
 
 static bool tracked_request_overlaps(BdrvTrackedRequest *req,
@@ -3229,6 +3234,15 @@  int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
     return drv->bdrv_get_info(bs, bdi);
 }
 
+/**
+ * Releases all data which has been allocated through bdrv_get_info. This
+ * function should be called if and only if bdrv_get_info was successful.
+ */
+void bdrv_put_info(BlockDriverState *bs, BlockDriverInfo *bdi)
+{
+    qapi_free_ImageInfoSpecific(bdi->format_specific);
+}
+
 int bdrv_save_vmstate(BlockDriverState *bs, const uint8_t *buf,
                       int64_t pos, int size)
 {
diff --git a/block/mirror.c b/block/mirror.c
index 86de458..9549add 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -320,10 +320,12 @@  static void coroutine_fn mirror_run(void *opaque)
     bdrv_get_backing_filename(s->target, backing_filename,
                               sizeof(backing_filename));
     if (backing_filename[0] && !s->target->backing_hd) {
-        bdrv_get_info(s->target, &bdi);
-        if (s->granularity < bdi.cluster_size) {
-            s->buf_size = MAX(s->buf_size, bdi.cluster_size);
-            s->cow_bitmap = bitmap_new(length);
+        if (bdrv_get_info(s->target, &bdi) >= 0) {
+            if (s->granularity < bdi.cluster_size) {
+                s->buf_size = MAX(s->buf_size, bdi.cluster_size);
+                s->cow_bitmap = bitmap_new(length);
+            }
+            bdrv_put_info(s->target, &bdi);
         }
     }
 
@@ -545,12 +547,16 @@  void mirror_start(BlockDriverState *bs, BlockDriverState *target,
         /* Choose the default granularity based on the target file's cluster
          * size, clamped between 4k and 64k.  */
         BlockDriverInfo bdi;
-        if (bdrv_get_info(target, &bdi) >= 0 && bdi.cluster_size != 0) {
+        int ret = bdrv_get_info(target, &bdi);
+        if (ret >= 0 && bdi.cluster_size != 0) {
             granularity = MAX(4096, bdi.cluster_size);
             granularity = MIN(65536, granularity);
         } else {
             granularity = 65536;
         }
+        if (ret >= 0) {
+            bdrv_put_info(target, &bdi);
+        }
     }
 
     assert ((granularity & (granularity - 1)) == 0);
diff --git a/block/qapi.c b/block/qapi.c
index a4bc411..86c399c 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -133,6 +133,10 @@  void bdrv_query_image_info(BlockDriverState *bs,
         }
         info->dirty_flag = bdi.is_dirty;
         info->has_dirty_flag = true;
+        if (bdi.format_specific) {
+            info->format_specific = bdi.format_specific;
+            info->has_format_specific = true;
+        }
     }
     backing_filename = bs->backing_file;
     if (backing_filename[0] != '\0') {
diff --git a/include/block/block.h b/include/block/block.h
index e6b391c..20f17a1 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -18,6 +18,8 @@  typedef struct BlockDriverInfo {
     /* offset at which the VM state can be saved (0 if not possible) */
     int64_t vm_state_offset;
     bool is_dirty;
+    /* additional information; NULL if none */
+    ImageInfoSpecific *format_specific;
 } BlockDriverInfo;
 
 typedef struct BlockFragInfo {
@@ -312,6 +314,7 @@  int bdrv_get_flags(BlockDriverState *bs);
 int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num,
                           const uint8_t *buf, int nb_sectors);
 int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi);
+void bdrv_put_info(BlockDriverState *bs, BlockDriverInfo *bdi);
 void bdrv_round_to_clusters(BlockDriverState *bs,
                             int64_t sector_num, int nb_sectors,
                             int64_t *cluster_sector_num,
diff --git a/qemu-img.c b/qemu-img.c
index b9a848d..32ae114 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -1370,6 +1370,7 @@  static int img_convert(int argc, char **argv)
             goto out;
         }
         cluster_size = bdi.cluster_size;
+        bdrv_put_info(out_bs, &bdi);
         if (cluster_size <= 0 || cluster_size > IO_BUF_SIZE) {
             error_report("invalid cluster size");
             ret = -1;
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
index f91b6c4..a639546 100644
--- a/qemu-io-cmds.c
+++ b/qemu-io-cmds.c
@@ -1699,6 +1699,8 @@  static int info_f(BlockDriverState *bs, int argc, char **argv)
     printf("cluster size: %s\n", s1);
     printf("vm state offset: %s\n", s2);
 
+    bdrv_put_info(bs, &bdi);
+
     return 0;
 }