From patchwork Mon Jul 21 19:52:11 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Cody X-Patchwork-Id: 372189 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 09AA5140088 for ; Tue, 22 Jul 2014 05:54:08 +1000 (EST) Received: from localhost ([::1]:36030 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X9Jew-0003eP-AR for incoming@patchwork.ozlabs.org; Mon, 21 Jul 2014 15:54:06 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39364) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X9JdP-0001Ib-2w for qemu-devel@nongnu.org; Mon, 21 Jul 2014 15:52:37 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1X9JdH-0004lF-6o for qemu-devel@nongnu.org; Mon, 21 Jul 2014 15:52:31 -0400 Received: from mx1.redhat.com ([209.132.183.28]:14344) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X9JdG-0004kx-UA for qemu-devel@nongnu.org; Mon, 21 Jul 2014 15:52:23 -0400 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s6LJqLN9028234 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 21 Jul 2014 15:52:22 -0400 Received: from localhost (ovpn-112-31.phx2.redhat.com [10.3.112.31]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s6LJqK3Z010053 (version=TLSv1/SSLv3 cipher=AES128-GCM-SHA256 bits=128 verify=NO); Mon, 21 Jul 2014 15:52:21 -0400 From: Jeff Cody To: qemu-devel@nongnu.org Date: Mon, 21 Jul 2014 15:52:11 -0400 Message-Id: In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 209.132.183.28 Cc: kwolf@redhat.com, sw@weilnetz.de, stefanha@redhat.com, mreitz@redhat.com Subject: [Qemu-devel] [PATCH v2 2/5] block: vdi - use block layer ops in vdi_create, instead of posix calls X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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. Signed-off-by: Jeff Cody Reviewed-by: Max Reitz --- block/vdi.c | 68 ++++++++++++++++++++++++++----------------------------------- 1 file changed, 29 insertions(+), 39 deletions(-) diff --git a/block/vdi.c b/block/vdi.c index 197bd77..5fd9d5f 100644 --- a/block/vdi.c +++ b/block/vdi.c @@ -681,7 +681,6 @@ static int vdi_co_write(BlockDriverState *bs, static int vdi_create(const char *filename, QemuOpts *opts, Error **errp) { - int fd; int result = 0; uint64_t bytes = 0; uint32_t blocks; @@ -690,7 +689,10 @@ static int vdi_create(const char *filename, QemuOpts *opts, Error **errp) VdiHeader header; size_t i; size_t bmap_size; - bool nocow = false; + int64_t offset = 0; + Error *local_err = NULL; + BlockDriverState *bs = NULL; + uint32_t *bmap = NULL; logout("\n"); @@ -707,7 +709,6 @@ static int vdi_create(const char *filename, QemuOpts *opts, Error **errp) image_type = VDI_TYPE_STATIC; } #endif - nocow = qemu_opt_get_bool_del(opts, BLOCK_OPT_NOCOW, false); if (bytes > VDI_DISK_SIZE_MAX) { result = -ENOTSUP; @@ -717,27 +718,16 @@ static int vdi_create(const char *filename, QemuOpts *opts, Error **errp) 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, opts, &local_err); + if (result < 0) { + error_propagate(errp, local_err); goto exit; } - - if (nocow) { -#ifdef __linux__ - /* Set NOCOW flag to solve performance issue on fs like btrfs. - * This is an optimisation. The FS_IOC_SETFLAGS ioctl return value will - * be ignored since any failure of this operation should not block the - * left work. - */ - int attr; - if (ioctl(fd, FS_IOC_GETFLAGS, &attr) == 0) { - attr |= FS_NOCOW_FL; - ioctl(fd, FS_IOC_SETFLAGS, &attr); - } -#endif + result = bdrv_open(&bs, filename, NULL, NULL, BDRV_O_RDWR | BDRV_O_PROTOCOL, + NULL, &local_err); + if (result < 0) { + error_propagate(errp, local_err); + goto exit; } /* We need enough blocks to store the given disk size, @@ -769,13 +759,15 @@ static int vdi_create(const char *filename, QemuOpts *opts, Error **errp) 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; @@ -783,27 +775,25 @@ static int vdi_create(const char *filename, QemuOpts *opts, Error **errp) 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; }