958e1b
From 9628ef39a4866417b7c2dc5af81ba12bfeb33630 Mon Sep 17 00:00:00 2001
958e1b
From: Jeffrey Cody <jcody@redhat.com>
958e1b
Date: Tue, 16 Sep 2014 20:11:51 +0200
958e1b
Subject: [PATCH 13/20] block: vdi - use block layer ops in vdi_create, instead of posix calls
958e1b
958e1b
Message-id: <f49d9ed2f027b0bee1a3fa4383cfa553d71e54bf.1410897407.git.jcody@redhat.com>
958e1b
Patchwork-id: 61217
958e1b
O-Subject: [PATCH qemu-kvm-rhel RHEL7.1 12/15] block: vdi - use block layer ops in vdi_create, instead of posix calls
958e1b
Bugzilla: 1098086
958e1b
RH-Acked-by: Fam Zheng <famz@redhat.com>
958e1b
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
958e1b
RH-Acked-by: Max Reitz <mreitz@redhat.com>
958e1b
958e1b
Use the block layer to create, and write to, the image file in the
958e1b
VDI .bdrv_create() operation.
958e1b
958e1b
This has a couple of benefits: Images can now be created over protocols,
958e1b
and hacks such as NOCOW are not needed in the image format driver, and
958e1b
the underlying file protocol appropriate for the host OS can be relied
958e1b
upon.
958e1b
958e1b
Also some minor cleanup for error handling.
958e1b
958e1b
Reviewed-by: Max Reitz <mreitz@redhat.com>
958e1b
Signed-off-by: Jeff Cody <jcody@redhat.com>
958e1b
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
958e1b
(cherry picked from commit 70747862f129ea0af5e3910f204cc93174c549e4)
958e1b
958e1b
Conflicts:
958e1b
	block/vdi.c
958e1b
958e1b
RHEL7 notes: conflicts due to not having the 'nocow' commit, as
958e1b
             well as not using QemuOpts yet. Arguments for bdrv_open()
958e1b
             are different, and downstream does not have
958e1b
             BDRV_O_PROTOCOL.  In addition, bdrv_file_open() must be
958e1b
             used instead of just bdrv_open().
958e1b
958e1b
Signed-off-by: Jeff Cody <jcody@redhat.com>
958e1b
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
958e1b
---
958e1b
 block/vdi.c |   52 +++++++++++++++++++++++++++++-----------------------
958e1b
 1 files changed, 29 insertions(+), 23 deletions(-)
958e1b
958e1b
diff --git a/block/vdi.c b/block/vdi.c
958e1b
index fb25424..1f4491f 100644
958e1b
--- a/block/vdi.c
958e1b
+++ b/block/vdi.c
958e1b
@@ -673,7 +673,6 @@ static int vdi_co_write(BlockDriverState *bs,
958e1b
 static int vdi_create(const char *filename, QEMUOptionParameter *options,
958e1b
                       Error **errp)
958e1b
 {
958e1b
-    int fd;
958e1b
     int result = 0;
958e1b
     uint64_t bytes = 0;
958e1b
     uint32_t blocks;
958e1b
@@ -682,6 +681,10 @@ static int vdi_create(const char *filename, QEMUOptionParameter *options,
958e1b
     VdiHeader header;
958e1b
     size_t i;
958e1b
     size_t bmap_size;
958e1b
+    int64_t offset = 0;
958e1b
+    Error *local_err = NULL;
958e1b
+    BlockDriverState *bs = NULL;
958e1b
+    uint32_t *bmap = NULL;
958e1b
 
958e1b
     logout("\n");
958e1b
 
958e1b
@@ -714,11 +717,14 @@ static int vdi_create(const char *filename, QEMUOptionParameter *options,
958e1b
         goto exit;
958e1b
     }
958e1b
 
958e1b
-    fd = qemu_open(filename,
958e1b
-                   O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE,
958e1b
-                   0644);
958e1b
-    if (fd < 0) {
958e1b
-        result = -errno;
958e1b
+    result = bdrv_create_file(filename, options, &local_err);
958e1b
+    if (result < 0) {
958e1b
+        error_propagate(errp, local_err);
958e1b
+        goto exit;
958e1b
+    }
958e1b
+    result = bdrv_file_open(&bs, filename, NULL, BDRV_O_RDWR, &local_err);
958e1b
+    if (result < 0) {
958e1b
+        error_propagate(errp, local_err);
958e1b
         goto exit;
958e1b
     }
958e1b
 
958e1b
@@ -751,13 +757,15 @@ static int vdi_create(const char *filename, QEMUOptionParameter *options,
958e1b
     vdi_header_print(&header);
958e1b
 #endif
958e1b
     vdi_header_to_le(&header);
958e1b
-    if (write(fd, &header, sizeof(header)) < 0) {
958e1b
-        result = -errno;
958e1b
-        goto close_and_exit;
958e1b
+    result = bdrv_pwrite_sync(bs, offset, &header, sizeof(header));
958e1b
+    if (result < 0) {
958e1b
+        error_setg(errp, "Error writing header to %s", filename);
958e1b
+        goto exit;
958e1b
     }
958e1b
+    offset += sizeof(header);
958e1b
 
958e1b
     if (bmap_size > 0) {
958e1b
-        uint32_t *bmap = g_malloc0(bmap_size);
958e1b
+        bmap = g_malloc0(bmap_size);
958e1b
         for (i = 0; i < blocks; i++) {
958e1b
             if (image_type == VDI_TYPE_STATIC) {
958e1b
                 bmap[i] = i;
958e1b
@@ -765,27 +773,25 @@ static int vdi_create(const char *filename, QEMUOptionParameter *options,
958e1b
                 bmap[i] = VDI_UNALLOCATED;
958e1b
             }
958e1b
         }
958e1b
-        if (write(fd, bmap, bmap_size) < 0) {
958e1b
-            result = -errno;
958e1b
-            g_free(bmap);
958e1b
-            goto close_and_exit;
958e1b
+        result = bdrv_pwrite_sync(bs, offset, bmap, bmap_size);
958e1b
+        if (result < 0) {
958e1b
+            error_setg(errp, "Error writing bmap to %s", filename);
958e1b
+            goto exit;
958e1b
         }
958e1b
-        g_free(bmap);
958e1b
+        offset += bmap_size;
958e1b
     }
958e1b
 
958e1b
     if (image_type == VDI_TYPE_STATIC) {
958e1b
-        if (ftruncate(fd, sizeof(header) + bmap_size + blocks * block_size)) {
958e1b
-            result = -errno;
958e1b
-            goto close_and_exit;
958e1b
+        result = bdrv_truncate(bs, offset + blocks * block_size);
958e1b
+        if (result < 0) {
958e1b
+            error_setg(errp, "Failed to statically allocate %s", filename);
958e1b
+            goto exit;
958e1b
         }
958e1b
     }
958e1b
 
958e1b
-close_and_exit:
958e1b
-    if ((close(fd) < 0) && !result) {
958e1b
-        result = -errno;
958e1b
-    }
958e1b
-
958e1b
 exit:
958e1b
+    bdrv_unref(bs);
958e1b
+    g_free(bmap);
958e1b
     return result;
958e1b
 }
958e1b
 
958e1b
-- 
958e1b
1.7.1
958e1b