From 4df7179eae48f59406dbef4fc0fb0185a09e8289 Mon Sep 17 00:00:00 2001 From: Jeffrey Cody 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: 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 RH-Acked-by: Stefan Hajnoczi RH-Acked-by: Max Reitz 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 Signed-off-by: Jeff Cody Signed-off-by: Kevin Wolf (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 Signed-off-by: Miroslav Rezanina --- 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 --- a/block/vpc.c +++ b/block/vpc.c @@ -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