diff mbox

[08/12] block: extract make_snapshot() from bdrv_open()

Message ID 1371750371-18491-9-git-send-email-marcandre.lureau@redhat.com
State New
Headers show

Commit Message

Marc-André Lureau June 20, 2013, 5:46 p.m. UTC
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 block.c | 107 +++++++++++++++++++++++++++++++++++++---------------------------
 1 file changed, 62 insertions(+), 45 deletions(-)
diff mbox

Patch

diff --git a/block.c b/block.c
index f502eed..5db8fa1 100644
--- a/block.c
+++ b/block.c
@@ -959,6 +959,65 @@  static void extract_subqdict(QDict *src, QDict **dst, const char *start)
     }
 }
 
+static int make_snapshot(BlockDriverState *bs, int64_t total_size,
+                         const char **pfilename, BlockDriver **pdrv)
+{
+    const char *filename = *pfilename;
+    BlockDriver *drv = *pdrv;
+    int ret;
+    BlockDriver *bdrv_qcow2;
+    QEMUOptionParameter *create_options;
+    char backing_filename[PATH_MAX];
+    /* TODO: extra byte is a hack to ensure MAX_PATH space on Windows. */
+    char tmp_filename[PATH_MAX + 1];
+
+    assert(filename != NULL);
+    total_size &= BDRV_SECTOR_MASK;
+
+    /* if snapshot, we create a temporary backing file and open it
+       instead of opening 'filename' directly */
+
+    ret = get_tmp_filename(tmp_filename, sizeof(tmp_filename));
+    if (ret < 0) {
+        goto fail;
+    }
+
+    /* Real path is meaningless for protocols */
+    if (path_has_protocol(filename)) {
+        snprintf(backing_filename, sizeof(backing_filename),
+                 "%s", filename);
+    } else if (!realpath(filename, backing_filename)) {
+        ret = -errno;
+        goto fail;
+    }
+
+    bdrv_qcow2 = bdrv_find_format("qcow2");
+    create_options = parse_option_parameters("", bdrv_qcow2->create_options,
+                                             NULL);
+
+    set_option_parameter_int(create_options, BLOCK_OPT_SIZE, total_size);
+    set_option_parameter(create_options, BLOCK_OPT_BACKING_FILE,
+                         backing_filename);
+    if (drv) {
+        set_option_parameter(create_options, BLOCK_OPT_BACKING_FMT,
+                             drv->format_name);
+    }
+
+    ret = bdrv_create(bdrv_qcow2, tmp_filename, create_options);
+    free_option_parameters(create_options);
+    if (ret < 0) {
+        goto fail;
+    }
+
+    *pfilename = tmp_filename;
+    *pdrv = bdrv_qcow2;
+    bs->is_temporary = 1;
+    return 0;
+
+fail:
+    return ret;
+}
+
 /*
  * Opens a disk image (raw, qcow2, vmdk, ...)
  *
@@ -971,8 +1030,6 @@  int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options,
               int flags, BlockDriver *drv)
 {
     int ret;
-    /* TODO: extra byte is a hack to ensure MAX_PATH space on Windows. */
-    char tmp_filename[PATH_MAX + 1];
     BlockDriverState *file = NULL;
     QDict *file_options = NULL;
 
@@ -988,66 +1045,26 @@  int bdrv_open(BlockDriverState *bs, const char *filename, QDict *options,
     if (flags & BDRV_O_SNAPSHOT) {
         BlockDriverState *bs1;
         int64_t total_size;
-        BlockDriver *bdrv_qcow2;
-        QEMUOptionParameter *create_options;
-        char backing_filename[PATH_MAX];
 
         if (qdict_size(options) != 0) {
             error_report("Can't use snapshot=on with driver-specific options");
             ret = -EINVAL;
             goto fail;
         }
-        assert(filename != NULL);
 
-        /* if snapshot, we create a temporary backing file and open it
-           instead of opening 'filename' directly */
-
-        /* if there is a backing file, use it */
-        bs1 = bdrv_new_int("", bs);
+        bs1 = bdrv_new_int("", NULL);
         ret = bdrv_open(bs1, filename, NULL, 0, drv);
         if (ret < 0) {
             bdrv_delete(bs1);
             goto fail;
         }
-        total_size = bdrv_getlength(bs1) & BDRV_SECTOR_MASK;
-
+        total_size = bdrv_getlength(bs1);
         bdrv_delete(bs1);
 
-        ret = get_tmp_filename(tmp_filename, sizeof(tmp_filename));
+        ret = make_snapshot(bs, total_size, &filename, &drv);
         if (ret < 0) {
             goto fail;
         }
-
-        /* Real path is meaningless for protocols */
-        if (path_has_protocol(filename)) {
-            snprintf(backing_filename, sizeof(backing_filename),
-                     "%s", filename);
-        } else if (!realpath(filename, backing_filename)) {
-            ret = -errno;
-            goto fail;
-        }
-
-        bdrv_qcow2 = bdrv_find_format("qcow2");
-        create_options = parse_option_parameters("", bdrv_qcow2->create_options,
-                                                 NULL);
-
-        set_option_parameter_int(create_options, BLOCK_OPT_SIZE, total_size);
-        set_option_parameter(create_options, BLOCK_OPT_BACKING_FILE,
-                             backing_filename);
-        if (drv) {
-            set_option_parameter(create_options, BLOCK_OPT_BACKING_FMT,
-                drv->format_name);
-        }
-
-        ret = bdrv_create(bdrv_qcow2, tmp_filename, create_options);
-        free_option_parameters(create_options);
-        if (ret < 0) {
-            goto fail;
-        }
-
-        filename = tmp_filename;
-        drv = bdrv_qcow2;
-        bs->is_temporary = 1;
     }
 
     /* Open image file without format layer */