958e1b
From 4df7179eae48f59406dbef4fc0fb0185a09e8289 Mon Sep 17 00:00:00 2001
958e1b
From: Jeffrey Cody <jcody@redhat.com>
958e1b
Date: Tue, 16 Sep 2014 20:11:53 +0200
958e1b
Subject: [PATCH 15/20] block: vpc - use block layer ops in vpc_create, instead of posix calls
958e1b
958e1b
Message-id: <d51013668a6aae15dad882bab6d0034e4bbfb4a2.1410897407.git.jcody@redhat.com>
958e1b
Patchwork-id: 61219
958e1b
O-Subject: [PATCH qemu-kvm-rhel RHEL7.1 14/15] block: vpc - use block layer ops in vpc_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 VPC
958e1b
.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
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 fef6070eff233400015cede968b0afe46c80bb0f)
958e1b
958e1b
Conflicts:
958e1b
	block/vpc.c
958e1b
958e1b
RHEL7 Notes: Conflict due to not having the 'nocow' commit
958e1b
             backported, as well as still using QEMUOptionParameter.
958e1b
             BDRV_O_PROTOCOL is also not downstream, and bdrv_open()
958e1b
             arguments are different.
958e1b
958e1b
Signed-off-by: Jeff Cody <jcody@redhat.com>
958e1b
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
958e1b
---
958e1b
 block/vpc.c |   85 +++++++++++++++++++++++++++++++---------------------------
958e1b
 1 files changed, 45 insertions(+), 40 deletions(-)
958e1b
958e1b
diff --git a/block/vpc.c b/block/vpc.c
958e1b
index ab74eb9..849501a 100644
958e1b
--- a/block/vpc.c
958e1b
+++ b/block/vpc.c
958e1b
@@ -633,39 +633,41 @@ static int calculate_geometry(int64_t total_sectors, uint16_t* cyls,
958e1b
     return 0;
958e1b
 }
958e1b
 
958e1b
-static int create_dynamic_disk(int fd, uint8_t *buf, int64_t total_sectors)
958e1b
+static int create_dynamic_disk(BlockDriverState *bs, uint8_t *buf,
958e1b
+                               int64_t total_sectors)
958e1b
 {
958e1b
     VHDDynDiskHeader *dyndisk_header =
958e1b
         (VHDDynDiskHeader *) buf;
958e1b
     size_t block_size, num_bat_entries;
958e1b
     int i;
958e1b
-    int ret = -EIO;
958e1b
+    int ret;
958e1b
+    int64_t offset = 0;
958e1b
 
958e1b
     // Write the footer (twice: at the beginning and at the end)
958e1b
     block_size = 0x200000;
958e1b
     num_bat_entries = (total_sectors + block_size / 512) / (block_size / 512);
958e1b
 
958e1b
-    if (write(fd, buf, HEADER_SIZE) != HEADER_SIZE) {
958e1b
+    ret = bdrv_pwrite_sync(bs, offset, buf, HEADER_SIZE);
958e1b
+    if (ret) {
958e1b
         goto fail;
958e1b
     }
958e1b
 
958e1b
-    if (lseek(fd, 1536 + ((num_bat_entries * 4 + 511) & ~511), SEEK_SET) < 0) {
958e1b
-        goto fail;
958e1b
-    }
958e1b
-    if (write(fd, buf, HEADER_SIZE) != HEADER_SIZE) {
958e1b
+    offset = 1536 + ((num_bat_entries * 4 + 511) & ~511);
958e1b
+    ret = bdrv_pwrite_sync(bs, offset, buf, HEADER_SIZE);
958e1b
+    if (ret < 0) {
958e1b
         goto fail;
958e1b
     }
958e1b
 
958e1b
     // Write the initial BAT
958e1b
-    if (lseek(fd, 3 * 512, SEEK_SET) < 0) {
958e1b
-        goto fail;
958e1b
-    }
958e1b
+    offset = 3 * 512;
958e1b
 
958e1b
     memset(buf, 0xFF, 512);
958e1b
     for (i = 0; i < (num_bat_entries * 4 + 511) / 512; i++) {
958e1b
-        if (write(fd, buf, 512) != 512) {
958e1b
+        ret = bdrv_pwrite_sync(bs, offset, buf, 512);
958e1b
+        if (ret < 0) {
958e1b
             goto fail;
958e1b
         }
958e1b
+        offset += 512;
958e1b
     }
958e1b
 
958e1b
     // Prepare the Dynamic Disk Header
958e1b
@@ -686,39 +688,35 @@ static int create_dynamic_disk(int fd, uint8_t *buf, int64_t total_sectors)
958e1b
     dyndisk_header->checksum = be32_to_cpu(vpc_checksum(buf, 1024));
958e1b
 
958e1b
     // Write the header
958e1b
-    if (lseek(fd, 512, SEEK_SET) < 0) {
958e1b
-        goto fail;
958e1b
-    }
958e1b
+    offset = 512;
958e1b
 
958e1b
-    if (write(fd, buf, 1024) != 1024) {
958e1b
+    ret = bdrv_pwrite_sync(bs, offset, buf, 1024);
958e1b
+    if (ret < 0) {
958e1b
         goto fail;
958e1b
     }
958e1b
-    ret = 0;
958e1b
 
958e1b
  fail:
958e1b
     return ret;
958e1b
 }
958e1b
 
958e1b
-static int create_fixed_disk(int fd, uint8_t *buf, int64_t total_size)
958e1b
+static int create_fixed_disk(BlockDriverState *bs, uint8_t *buf,
958e1b
+                             int64_t total_size)
958e1b
 {
958e1b
-    int ret = -EIO;
958e1b
+    int ret;
958e1b
 
958e1b
     /* Add footer to total size */
958e1b
-    total_size += 512;
958e1b
-    if (ftruncate(fd, total_size) != 0) {
958e1b
-        ret = -errno;
958e1b
-        goto fail;
958e1b
-    }
958e1b
-    if (lseek(fd, -512, SEEK_END) < 0) {
958e1b
-        goto fail;
958e1b
-    }
958e1b
-    if (write(fd, buf, HEADER_SIZE) != HEADER_SIZE) {
958e1b
-        goto fail;
958e1b
+    total_size += HEADER_SIZE;
958e1b
+
958e1b
+    ret = bdrv_truncate(bs, total_size);
958e1b
+    if (ret < 0) {
958e1b
+        return ret;
958e1b
     }
958e1b
 
958e1b
-    ret = 0;
958e1b
+    ret = bdrv_pwrite_sync(bs, total_size - HEADER_SIZE, buf, HEADER_SIZE);
958e1b
+    if (ret < 0) {
958e1b
+        return ret;
958e1b
+    }
958e1b
 
958e1b
- fail:
958e1b
     return ret;
958e1b
 }
958e1b
 
958e1b
@@ -728,7 +726,7 @@ static int vpc_create(const char *filename, QEMUOptionParameter *options,
958e1b
     uint8_t buf[1024];
958e1b
     VHDFooter *footer = (VHDFooter *) buf;
958e1b
     QEMUOptionParameter *disk_type_param;
958e1b
-    int fd, i;
958e1b
+    int i;
958e1b
     uint16_t cyls = 0;
958e1b
     uint8_t heads = 0;
958e1b
     uint8_t secs_per_cyl = 0;
958e1b
@@ -736,6 +734,8 @@ static int vpc_create(const char *filename, QEMUOptionParameter *options,
958e1b
     int64_t total_size;
958e1b
     int disk_type;
958e1b
     int ret = -EIO;
958e1b
+    Error *local_err = NULL;
958e1b
+    BlockDriverState *bs = NULL;
958e1b
 
958e1b
     /* Read out options */
958e1b
     total_size = get_option_parameter(options, BLOCK_OPT_SIZE)->value.n;
958e1b
@@ -753,10 +753,15 @@ static int vpc_create(const char *filename, QEMUOptionParameter *options,
958e1b
         disk_type = VHD_DYNAMIC;
958e1b
     }
958e1b
 
958e1b
-    /* Create the file */
958e1b
-    fd = qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
958e1b
-    if (fd < 0) {
958e1b
-        return -EIO;
958e1b
+    ret = bdrv_create_file(filename, options, &local_err);
958e1b
+    if (ret < 0) {
958e1b
+        error_propagate(errp, local_err);
958e1b
+        goto out;
958e1b
+    }
958e1b
+    ret = bdrv_file_open(&bs, filename, NULL, BDRV_O_RDWR, &local_err);
958e1b
+    if (ret < 0) {
958e1b
+        error_propagate(errp, local_err);
958e1b
+        goto out;
958e1b
     }
958e1b
 
958e1b
     /*
958e1b
@@ -770,7 +775,7 @@ static int vpc_create(const char *filename, QEMUOptionParameter *options,
958e1b
                                &secs_per_cyl))
958e1b
         {
958e1b
             ret = -EFBIG;
958e1b
-            goto fail;
958e1b
+            goto out;
958e1b
         }
958e1b
     }
958e1b
 
958e1b
@@ -816,13 +821,13 @@ static int vpc_create(const char *filename, QEMUOptionParameter *options,
958e1b
     footer->checksum = be32_to_cpu(vpc_checksum(buf, HEADER_SIZE));
958e1b
 
958e1b
     if (disk_type == VHD_DYNAMIC) {
958e1b
-        ret = create_dynamic_disk(fd, buf, total_sectors);
958e1b
+        ret = create_dynamic_disk(bs, buf, total_sectors);
958e1b
     } else {
958e1b
-        ret = create_fixed_disk(fd, buf, total_size);
958e1b
+        ret = create_fixed_disk(bs, buf, total_size);
958e1b
     }
958e1b
 
958e1b
- fail:
958e1b
-    qemu_close(fd);
958e1b
+out:
958e1b
+    bdrv_unref(bs);
958e1b
     return ret;
958e1b
 }
958e1b
 
958e1b
-- 
958e1b
1.7.1
958e1b