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