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