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