Blame 0101-block-Close-backing-file-early-in-bdrv_img_create.patch

cba9c9
From 62a30a970548466900ac45962a0fe8c051514329 Mon Sep 17 00:00:00 2001
46c39e
From: Max Reitz <mreitz@redhat.com>
cba9c9
Date: Tue, 3 Dec 2013 14:57:52 +0100
46c39e
Subject: [PATCH] block: Close backing file early in bdrv_img_create
46c39e
46c39e
Leaving the backing file open although it is not needed anymore can
46c39e
cause problems if it is opened through a block driver which allows
46c39e
exclusive access only and if the create function of the block driver
46c39e
used for the top image (the one being created) tries to close and reopen
46c39e
the image file (which will include opening the backing file a second
46c39e
time).
46c39e
46c39e
In particular, this will happen with a backing file opened through
46c39e
qemu-nbd and using qcow2 as the top image file format (which reopens the
46c39e
image to flush it to disk).
46c39e
cba9c9
In addition, the BlockDriverState in bdrv_img_create() is used for the
cba9c9
backing file only; it should therefore be made local to the respective
cba9c9
block.
cba9c9
46c39e
Signed-off-by: Max Reitz <mreitz@redhat.com>
46c39e
---
cba9c9
 block.c | 8 ++++----
cba9c9
 1 file changed, 4 insertions(+), 4 deletions(-)
46c39e
46c39e
diff --git a/block.c b/block.c
cba9c9
index 382ea71..0468765 100644
46c39e
--- a/block.c
46c39e
+++ b/block.c
cba9c9
@@ -4504,7 +4504,6 @@ void bdrv_img_create(const char *filename, const char *fmt,
cba9c9
 {
cba9c9
     QEMUOptionParameter *param = NULL, *create_options = NULL;
cba9c9
     QEMUOptionParameter *backing_fmt, *backing_file, *size;
cba9c9
-    BlockDriverState *bs = NULL;
cba9c9
     BlockDriver *drv, *proto_drv;
cba9c9
     BlockDriver *backing_drv = NULL;
cba9c9
     Error *local_err = NULL;
cba9c9
@@ -4583,6 +4582,7 @@ void bdrv_img_create(const char *filename, const char *fmt,
cba9c9
     size = get_option_parameter(param, BLOCK_OPT_SIZE);
cba9c9
     if (size && size->value.n == -1) {
cba9c9
         if (backing_file && backing_file->value.s) {
cba9c9
+            BlockDriverState *bs;
cba9c9
             uint64_t size;
cba9c9
             char buf[32];
cba9c9
             int back_flags;
cba9c9
@@ -4601,6 +4601,7 @@ void bdrv_img_create(const char *filename, const char *fmt,
cba9c9
                                  error_get_pretty(local_err));
cba9c9
                 error_free(local_err);
cba9c9
                 local_err = NULL;
cba9c9
+                bdrv_unref(bs);
cba9c9
                 goto out;
cba9c9
             }
cba9c9
             bdrv_get_geometry(bs, &size);
cba9c9
@@ -4608,6 +4609,8 @@ void bdrv_img_create(const char *filename, const char *fmt,
46c39e
 
46c39e
             snprintf(buf, sizeof(buf), "%" PRId64, size);
46c39e
             set_option_parameter(param, BLOCK_OPT_SIZE, buf);
46c39e
+
46c39e
+            bdrv_unref(bs);
46c39e
         } else {
46c39e
             error_setg(errp, "Image creation needs a size parameter");
46c39e
             goto out;
cba9c9
@@ -4638,9 +4641,6 @@ out:
cba9c9
     free_option_parameters(create_options);
cba9c9
     free_option_parameters(param);
cba9c9
 
cba9c9
-    if (bs) {
cba9c9
-        bdrv_unref(bs);
cba9c9
-    }
cba9c9
     if (error_is_set(&local_err)) {
cba9c9
         error_propagate(errp, local_err);
cba9c9
     }