All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kevin Wolf <kwolf@redhat.com>
To: qemu-devel@nongnu.org
Cc: kwolf@redhat.com
Subject: [Qemu-devel] [PULL 37/62] block: vpc - use block layer ops in vpc_create, instead of posix calls
Date: Fri,  8 Aug 2014 19:39:38 +0200	[thread overview]
Message-ID: <1407519603-6635-38-git-send-email-kwolf@redhat.com> (raw)
In-Reply-To: <1407519603-6635-1-git-send-email-kwolf@redhat.com>

From: Jeff Cody <jcody@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>
---
 block/vpc.c | 106 ++++++++++++++++++++++++------------------------------------
 1 file changed, 43 insertions(+), 63 deletions(-)

diff --git a/block/vpc.c b/block/vpc.c
index 8b376a4..9690344 100644
--- a/block/vpc.c
+++ b/block/vpc.c
@@ -29,13 +29,6 @@
 #if defined(CONFIG_UUID)
 #include <uuid/uuid.h>
 #endif
-#ifdef __linux__
-#include <linux/fs.h>
-#include <sys/ioctl.h>
-#ifndef FS_NOCOW_FL
-#define FS_NOCOW_FL                     0x00800000 /* Do not cow file */
-#endif
-#endif
 
 /**************************************************************/
 
@@ -656,39 +649,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
@@ -709,39 +704,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;
 }
 
@@ -750,7 +741,7 @@ static int vpc_create(const char *filename, QemuOpts *opts, Error **errp)
     uint8_t buf[1024];
     VHDFooter *footer = (VHDFooter *) buf;
     char *disk_type_param;
-    int fd, i;
+    int i;
     uint16_t cyls = 0;
     uint8_t heads = 0;
     uint8_t secs_per_cyl = 0;
@@ -758,7 +749,8 @@ static int vpc_create(const char *filename, QemuOpts *opts, Error **errp)
     int64_t total_size;
     int disk_type;
     int ret = -EIO;
-    bool nocow = false;
+    Error *local_err = NULL;
+    BlockDriverState *bs = NULL;
 
     /* Read out options */
     total_size = qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0);
@@ -775,28 +767,17 @@ static int vpc_create(const char *filename, QemuOpts *opts, Error **errp)
     } else {
         disk_type = VHD_DYNAMIC;
     }
-    nocow = qemu_opt_get_bool_del(opts, BLOCK_OPT_NOCOW, false);
 
-    /* Create the file */
-    fd = qemu_open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
-    if (fd < 0) {
-        ret = -EIO;
+    ret = bdrv_create_file(filename, opts, &local_err);
+    if (ret < 0) {
+        error_propagate(errp, local_err);
         goto out;
     }
-
-    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
+    ret = bdrv_open(&bs, filename, NULL, NULL, BDRV_O_RDWR | BDRV_O_PROTOCOL,
+                    NULL, &local_err);
+    if (ret < 0) {
+        error_propagate(errp, local_err);
+        goto out;
     }
 
     /*
@@ -810,7 +791,7 @@ static int vpc_create(const char *filename, QemuOpts *opts, Error **errp)
                                &secs_per_cyl))
         {
             ret = -EFBIG;
-            goto fail;
+            goto out;
         }
     }
 
@@ -856,14 +837,13 @@ static int vpc_create(const char *filename, QemuOpts *opts, Error **errp)
     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);
     g_free(disk_type_param);
     return ret;
 }
-- 
1.8.3.1

  parent reply	other threads:[~2014-08-08 17:41 UTC|newest]

Thread overview: 71+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-08-08 17:39 [Qemu-devel] [PULL 00/62] Block patches Kevin Wolf
2014-08-08 17:39 ` [Qemu-devel] [PULL 01/62] nbd: Drop nbd_can_read() Kevin Wolf
2014-08-08 17:39 ` [Qemu-devel] [PULL 02/62] block: Add AIO context notifiers Kevin Wolf
2014-08-08 17:39 ` [Qemu-devel] [PULL 03/62] nbd: Follow the BDS' AIO context Kevin Wolf
2014-08-08 17:39 ` [Qemu-devel] [PULL 04/62] block: New bdrv_nb_sectors() Kevin Wolf
2014-08-08 17:39 ` [Qemu-devel] [PULL 05/62] block: Use bdrv_nb_sectors() in bdrv_make_zero() Kevin Wolf
2014-08-08 17:39 ` [Qemu-devel] [PULL 06/62] block: Use bdrv_nb_sectors() in bdrv_aligned_preadv() Kevin Wolf
2014-08-08 17:39 ` [Qemu-devel] [PULL 07/62] block: Use bdrv_nb_sectors() in bdrv_co_get_block_status() Kevin Wolf
2014-08-08 17:39 ` [Qemu-devel] [PULL 08/62] block: Use bdrv_nb_sectors() in img_convert() Kevin Wolf
2014-08-08 17:39 ` [Qemu-devel] [PULL 09/62] block: Use bdrv_nb_sectors() where sectors, not bytes are wanted Kevin Wolf
2014-08-08 17:39 ` [Qemu-devel] [PULL 10/62] block: Drop superfluous aligning of bdrv_getlength()'s value Kevin Wolf
2014-08-08 17:39 ` [Qemu-devel] [PULL 11/62] qemu-img: Make img_convert() get image size just once per image Kevin Wolf
2014-08-08 17:39 ` [Qemu-devel] [PULL 12/62] block: Avoid bdrv_get_geometry() where errors should be detected Kevin Wolf
2014-08-08 17:39 ` [Qemu-devel] [PULL 13/62] docs: Make the recommendation for the backing file name position a requirement Kevin Wolf
2014-08-08 17:39 ` [Qemu-devel] [PULL 14/62] configure: explicitly state version requirements to devel packages Kevin Wolf
2014-08-08 17:39 ` [Qemu-devel] [PULL 15/62] xen_disk: fix possible null-ptr dereference Kevin Wolf
2014-08-08 17:39 ` [Qemu-devel] [PULL 16/62] docs/multiple-iothreads.txt: add documentation on IOThread programming Kevin Wolf
2014-08-08 17:39 ` [Qemu-devel] [PULL 17/62] qmp: hide "hotplugged" device property from device-list-properties Kevin Wolf
2014-08-08 17:39 ` [Qemu-devel] [PULL 18/62] qdev-monitor: include QOM properties in -device FOO, help output Kevin Wolf
2014-08-08 17:39 ` [Qemu-devel] [PULL 19/62] qemu-iotests: Add data pattern in version3 VMDK sample image in 059 Kevin Wolf
2014-08-08 17:39 ` [Qemu-devel] [PULL 20/62] vmdk: Optimize cluster allocation Kevin Wolf
2014-08-08 17:39 ` [Qemu-devel] [PULL 21/62] qemu-img info: show nocow info Kevin Wolf
2014-08-08 17:39 ` [Qemu-devel] [PULL 22/62] block: Support Archipelago as a QEMU block backend Kevin Wolf
2015-04-09  3:48   ` Andreas Färber
2015-04-09 12:48     ` Chrysostomos Nanakos
2015-04-09 14:05       ` Stefan Hajnoczi
2015-04-09 14:08         ` Chrysostomos Nanakos
2014-08-08 17:39 ` [Qemu-devel] [PULL 23/62] block/archipelago: Implement bdrv_parse_filename() Kevin Wolf
2014-08-08 17:39 ` [Qemu-devel] [PULL 24/62] block/archipelago: Add support for creating images Kevin Wolf
2014-08-08 17:39 ` [Qemu-devel] [PULL 25/62] QMP: Add support for Archipelago Kevin Wolf
2014-08-08 17:39 ` [Qemu-devel] [PULL 26/62] qemu-iotests: add support for Archipelago protocol Kevin Wolf
2014-08-08 17:39 ` [Qemu-devel] [PULL 27/62] coroutine: make pool size dynamic Kevin Wolf
2014-08-08 17:39 ` [Qemu-devel] [PULL 28/62] block: bump coroutine pool size for drives Kevin Wolf
2014-08-08 17:39 ` [Qemu-devel] [PULL 29/62] thread-pool: avoid per-thread-pool EventNotifier Kevin Wolf
2014-08-08 17:39 ` [Qemu-devel] [PULL 30/62] thread-pool: avoid deadlock in nested aio_poll() calls Kevin Wolf
2014-08-08 17:39 ` [Qemu-devel] [PULL 31/62] block: vhdx - add error check Kevin Wolf
2014-08-08 17:39 ` [Qemu-devel] [PULL 32/62] block: VHDX endian fixes Kevin Wolf
2014-08-08 17:39 ` [Qemu-devel] [PULL 33/62] test-coroutine: add baseline test that times the cost of function calls Kevin Wolf
2014-08-08 17:39 ` [Qemu-devel] [PULL 34/62] block: allow bdrv_unref() to be passed NULL pointers Kevin Wolf
2014-08-08 17:39 ` [Qemu-devel] [PULL 35/62] block: vdi - use block layer ops in vdi_create, instead of posix calls Kevin Wolf
2014-08-08 17:39 ` [Qemu-devel] [PULL 36/62] block: use the standard 'ret' instead of 'result' Kevin Wolf
2014-08-08 17:39 ` Kevin Wolf [this message]
2014-08-08 17:39 ` [Qemu-devel] [PULL 38/62] block: iotest - update 084 to test static VDI image creation Kevin Wolf
2014-08-08 17:39 ` [Qemu-devel] [PULL 39/62] block: Introduce qemu_try_blockalign() Kevin Wolf
2014-08-08 17:39 ` [Qemu-devel] [PULL 40/62] block: Handle failure for potentially large allocations Kevin Wolf
2014-08-08 17:39 ` [Qemu-devel] [PULL 41/62] bochs: " Kevin Wolf
2014-08-08 17:39 ` [Qemu-devel] [PULL 42/62] cloop: " Kevin Wolf
2014-08-08 17:39 ` [Qemu-devel] [PULL 43/62] curl: " Kevin Wolf
2014-08-08 17:39 ` [Qemu-devel] [PULL 44/62] dmg: " Kevin Wolf
2014-08-08 17:39 ` [Qemu-devel] [PULL 45/62] iscsi: " Kevin Wolf
2014-08-08 17:39 ` [Qemu-devel] [PULL 46/62] nfs: " Kevin Wolf
2014-08-08 17:39 ` [Qemu-devel] [PULL 47/62] parallels: " Kevin Wolf
2014-08-08 17:39 ` [Qemu-devel] [PULL 48/62] qcow1: " Kevin Wolf
2014-08-08 17:39 ` [Qemu-devel] [PULL 49/62] qcow2: " Kevin Wolf
2014-08-08 17:39 ` [Qemu-devel] [PULL 50/62] qed: " Kevin Wolf
2014-08-08 17:39 ` [Qemu-devel] [PULL 51/62] raw-posix: " Kevin Wolf
2014-08-08 17:39 ` [Qemu-devel] [PULL 52/62] raw-win32: " Kevin Wolf
2014-08-08 17:39 ` [Qemu-devel] [PULL 53/62] rbd: " Kevin Wolf
2014-08-08 17:39 ` [Qemu-devel] [PULL 54/62] vdi: " Kevin Wolf
2014-08-08 17:39 ` [Qemu-devel] [PULL 55/62] vhdx: " Kevin Wolf
2014-08-08 17:39 ` [Qemu-devel] [PULL 56/62] vmdk: " Kevin Wolf
2014-08-08 17:39 ` [Qemu-devel] [PULL 57/62] vpc: " Kevin Wolf
2014-08-08 17:39 ` [Qemu-devel] [PULL 58/62] mirror: " Kevin Wolf
2014-08-08 17:40 ` [Qemu-devel] [PULL 59/62] qcow2: Return useful error code in refcount_init() Kevin Wolf
2014-08-08 17:40 ` [Qemu-devel] [PULL 60/62] qcow2: Catch !*host_offset for data allocation Kevin Wolf
2014-08-08 17:40 ` [Qemu-devel] [PULL 61/62] iotests: Add test for image header overlap Kevin Wolf
2014-08-08 17:40 ` [Qemu-devel] [PULL 62/62] block: Catch !bs->drv in bdrv_check() Kevin Wolf
2014-08-15 12:41 ` [Qemu-devel] [PULL 00/62] Block patches Peter Maydell
2014-08-15 13:10   ` Kevin Wolf
2014-08-15 15:34     ` Peter Maydell
2014-08-15 20:21     ` Paolo Bonzini

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1407519603-6635-38-git-send-email-kwolf@redhat.com \
    --to=kwolf@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.