]> Git Repo - qemu.git/blobdiff - block/vdi.c
iscsi: partly avoid iovec linearization in iscsi_aio_writev
[qemu.git] / block / vdi.c
index 790b61ef59e3e5fd44eb737374cfa04286f3243e..021abaa22731622c6ba756d04bd20137a2ed24f4 100644 (file)
  */
 
 #include "qemu-common.h"
-#include "block_int.h"
-#include "module.h"
-#include "migration.h"
+#include "block/block_int.h"
+#include "qemu/module.h"
+#include "migration/migration.h"
 
 #if defined(CONFIG_UUID)
 #include <uuid/uuid.h>
 #else
 /* TODO: move uuid emulation to some central place in QEMU. */
-#include "sysemu.h"     /* UUID_FMT */
+#include "sysemu/sysemu.h"     /* UUID_FMT */
 typedef unsigned char uuid_t[16];
-void uuid_generate(uuid_t out);
-int uuid_is_null(const uuid_t uu);
-void uuid_unparse(const uuid_t uu, char *out);
 #endif
 
 /* Code configuration options. */
@@ -124,18 +121,18 @@ void uuid_unparse(const uuid_t uu, char *out);
 #define VDI_IS_ALLOCATED(X) ((X) < VDI_DISCARDED)
 
 #if !defined(CONFIG_UUID)
-void uuid_generate(uuid_t out)
+static inline void uuid_generate(uuid_t out)
 {
     memset(out, 0, sizeof(uuid_t));
 }
 
-int uuid_is_null(const uuid_t uu)
+static inline int uuid_is_null(const uuid_t uu)
 {
     uuid_t null_uuid = { 0 };
     return memcmp(uu, null_uuid, sizeof(uuid_t)) == 0;
 }
 
-void uuid_unparse(const uuid_t uu, char *out)
+static inline void uuid_unparse(const uuid_t uu, char *out)
 {
     snprintf(out, 37, UUID_FMT,
             uu[0], uu[1], uu[2], uu[3], uu[4], uu[5], uu[6], uu[7],
@@ -277,7 +274,8 @@ static void vdi_header_print(VdiHeader *header)
 }
 #endif
 
-static int vdi_check(BlockDriverState *bs, BdrvCheckResult *res)
+static int vdi_check(BlockDriverState *bs, BdrvCheckResult *res,
+                     BdrvCheckMode fix)
 {
     /* TODO: additional checks possible. */
     BDRVVdiState *s = (BDRVVdiState *)bs->opaque;
@@ -286,6 +284,10 @@ static int vdi_check(BlockDriverState *bs, BdrvCheckResult *res)
     uint32_t *bmap;
     logout("\n");
 
+    if (fix) {
+        return -ENOTSUP;
+    }
+
     bmap = g_malloc(s->header.blocks_in_image * sizeof(uint32_t));
     memset(bmap, 0xff, s->header.blocks_in_image * sizeof(uint32_t));
 
@@ -449,6 +451,12 @@ static int vdi_open(BlockDriverState *bs, int flags)
     return -1;
 }
 
+static int vdi_reopen_prepare(BDRVReopenState *state,
+                              BlockReopenQueue *queue, Error **errp)
+{
+    return 0;
+}
+
 static int coroutine_fn vdi_co_is_allocated(BlockDriverState *bs,
         int64_t sector_num, int nb_sectors, int *pnum)
 {
@@ -474,46 +482,38 @@ static int vdi_co_read(BlockDriverState *bs,
     uint32_t block_index;
     uint32_t sector_in_block;
     uint32_t n_sectors;
-    struct iovec hd_iov;
-    QEMUIOVector hd_qiov;
-    int ret;
+    int ret = 0;
 
     logout("\n");
 
-restart:
-    block_index = sector_num / s->block_sectors;
-    sector_in_block = sector_num % s->block_sectors;
-    n_sectors = s->block_sectors - sector_in_block;
-    if (n_sectors > nb_sectors) {
-        n_sectors = nb_sectors;
-    }
-
-    logout("will read %u sectors starting at sector %" PRIu64 "\n",
-           n_sectors, sector_num);
+    while (ret >= 0 && nb_sectors > 0) {
+        block_index = sector_num / s->block_sectors;
+        sector_in_block = sector_num % s->block_sectors;
+        n_sectors = s->block_sectors - sector_in_block;
+        if (n_sectors > nb_sectors) {
+            n_sectors = nb_sectors;
+        }
 
-    /* prepare next AIO request */
-    bmap_entry = le32_to_cpu(s->bmap[block_index]);
-    if (!VDI_IS_ALLOCATED(bmap_entry)) {
-        /* Block not allocated, return zeros, no need to wait. */
-        memset(buf, 0, n_sectors * SECTOR_SIZE);
-        ret = 0;
-    } else {
-        uint64_t offset = s->header.offset_data / SECTOR_SIZE +
-                          (uint64_t)bmap_entry * s->block_sectors +
-                          sector_in_block;
-        hd_iov.iov_base = (void *)buf;
-        hd_iov.iov_len = n_sectors * SECTOR_SIZE;
-        qemu_iovec_init_external(&hd_qiov, &hd_iov, 1);
-        ret = bdrv_co_readv(bs->file, offset, n_sectors, &hd_qiov);
-    }
-    logout("%u sectors read\n", n_sectors);
+        logout("will read %u sectors starting at sector %" PRIu64 "\n",
+               n_sectors, sector_num);
 
-    nb_sectors -= n_sectors;
-    sector_num += n_sectors;
-    buf += n_sectors * SECTOR_SIZE;
+        /* prepare next AIO request */
+        bmap_entry = le32_to_cpu(s->bmap[block_index]);
+        if (!VDI_IS_ALLOCATED(bmap_entry)) {
+            /* Block not allocated, return zeros, no need to wait. */
+            memset(buf, 0, n_sectors * SECTOR_SIZE);
+            ret = 0;
+        } else {
+            uint64_t offset = s->header.offset_data / SECTOR_SIZE +
+                              (uint64_t)bmap_entry * s->block_sectors +
+                              sector_in_block;
+            ret = bdrv_read(bs->file, offset, buf, n_sectors);
+        }
+        logout("%u sectors read\n", n_sectors);
 
-    if (ret >= 0 && nb_sectors > 0) {
-        goto restart;
+        nb_sectors -= n_sectors;
+        sector_num += n_sectors;
+        buf += n_sectors * SECTOR_SIZE;
     }
 
     return ret;
@@ -529,102 +529,92 @@ static int vdi_co_write(BlockDriverState *bs,
     uint32_t n_sectors;
     uint32_t bmap_first = VDI_UNALLOCATED;
     uint32_t bmap_last = VDI_UNALLOCATED;
-    struct iovec hd_iov;
-    QEMUIOVector hd_qiov;
     uint8_t *block = NULL;
-    int ret;
+    int ret = 0;
 
     logout("\n");
 
-restart:
-    block_index = sector_num / s->block_sectors;
-    sector_in_block = sector_num % s->block_sectors;
-    n_sectors = s->block_sectors - sector_in_block;
-    if (n_sectors > nb_sectors) {
-        n_sectors = nb_sectors;
-    }
+    while (ret >= 0 && nb_sectors > 0) {
+        block_index = sector_num / s->block_sectors;
+        sector_in_block = sector_num % s->block_sectors;
+        n_sectors = s->block_sectors - sector_in_block;
+        if (n_sectors > nb_sectors) {
+            n_sectors = nb_sectors;
+        }
 
-    logout("will write %u sectors starting at sector %" PRIu64 "\n",
-           n_sectors, sector_num);
+        logout("will write %u sectors starting at sector %" PRIu64 "\n",
+               n_sectors, sector_num);
 
-    /* prepare next AIO request */
-    bmap_entry = le32_to_cpu(s->bmap[block_index]);
-    if (!VDI_IS_ALLOCATED(bmap_entry)) {
-        /* Allocate new block and write to it. */
-        uint64_t offset;
-        bmap_entry = s->header.blocks_allocated;
-        s->bmap[block_index] = cpu_to_le32(bmap_entry);
-        s->header.blocks_allocated++;
-        offset = s->header.offset_data / SECTOR_SIZE +
-                 (uint64_t)bmap_entry * s->block_sectors;
-        if (block == NULL) {
-            block = g_malloc(s->block_size);
-            bmap_first = block_index;
+        /* prepare next AIO request */
+        bmap_entry = le32_to_cpu(s->bmap[block_index]);
+        if (!VDI_IS_ALLOCATED(bmap_entry)) {
+            /* Allocate new block and write to it. */
+            uint64_t offset;
+            bmap_entry = s->header.blocks_allocated;
+            s->bmap[block_index] = cpu_to_le32(bmap_entry);
+            s->header.blocks_allocated++;
+            offset = s->header.offset_data / SECTOR_SIZE +
+                     (uint64_t)bmap_entry * s->block_sectors;
+            if (block == NULL) {
+                block = g_malloc(s->block_size);
+                bmap_first = block_index;
+            }
+            bmap_last = block_index;
+            /* Copy data to be written to new block and zero unused parts. */
+            memset(block, 0, sector_in_block * SECTOR_SIZE);
+            memcpy(block + sector_in_block * SECTOR_SIZE,
+                   buf, n_sectors * SECTOR_SIZE);
+            memset(block + (sector_in_block + n_sectors) * SECTOR_SIZE, 0,
+                   (s->block_sectors - n_sectors - sector_in_block) * SECTOR_SIZE);
+            ret = bdrv_write(bs->file, offset, block, s->block_sectors);
+        } else {
+            uint64_t offset = s->header.offset_data / SECTOR_SIZE +
+                              (uint64_t)bmap_entry * s->block_sectors +
+                              sector_in_block;
+            ret = bdrv_write(bs->file, offset, buf, n_sectors);
         }
-        bmap_last = block_index;
-        /* Copy data to be written to new block and zero unused parts. */
-        memset(block, 0, sector_in_block * SECTOR_SIZE);
-        memcpy(block + sector_in_block * SECTOR_SIZE,
-               buf, n_sectors * SECTOR_SIZE);
-        memset(block + (sector_in_block + n_sectors) * SECTOR_SIZE, 0,
-               (s->block_sectors - n_sectors - sector_in_block) * SECTOR_SIZE);
-        hd_iov.iov_base = (void *)block;
-        hd_iov.iov_len = s->block_size;
-        qemu_iovec_init_external(&hd_qiov, &hd_iov, 1);
-        ret = bdrv_co_writev(bs->file, offset, s->block_sectors, &hd_qiov);
-    } else {
-        uint64_t offset = s->header.offset_data / SECTOR_SIZE +
-                          (uint64_t)bmap_entry * s->block_sectors +
-                          sector_in_block;
-        hd_iov.iov_base = (void *)buf;
-        hd_iov.iov_len = n_sectors * SECTOR_SIZE;
-        qemu_iovec_init_external(&hd_qiov, &hd_iov, 1);
-        ret = bdrv_co_writev(bs->file, offset, n_sectors, &hd_qiov);
-    }
 
-    nb_sectors -= n_sectors;
-    sector_num += n_sectors;
-    buf += n_sectors * SECTOR_SIZE;
+        nb_sectors -= n_sectors;
+        sector_num += n_sectors;
+        buf += n_sectors * SECTOR_SIZE;
 
-    logout("%u sectors written\n", n_sectors);
-    if (ret >= 0 && nb_sectors > 0) {
-        goto restart;
+        logout("%u sectors written\n", n_sectors);
     }
 
     logout("finished data write\n");
-    if (ret >= 0) {
-        ret = 0;
-        if (block) {
-            VdiHeader *header = (VdiHeader *) block;
-            logout("now writing modified header\n");
-            assert(VDI_IS_ALLOCATED(bmap_first));
-            *header = s->header;
-            vdi_header_to_le(header);
-            hd_iov.iov_base = block;
-            hd_iov.iov_len = SECTOR_SIZE;
-            qemu_iovec_init_external(&hd_qiov, &hd_iov, 1);
-            ret = bdrv_co_writev(bs->file, 0, 1, &hd_qiov);
-        }
+    if (ret < 0) {
+        return ret;
+    }
+
+    if (block) {
+        /* One or more new blocks were allocated. */
+        VdiHeader *header = (VdiHeader *) block;
+        uint8_t *base;
+        uint64_t offset;
+
+        logout("now writing modified header\n");
+        assert(VDI_IS_ALLOCATED(bmap_first));
+        *header = s->header;
+        vdi_header_to_le(header);
+        ret = bdrv_write(bs->file, 0, block, 1);
         g_free(block);
         block = NULL;
-        if (ret >= 0 && VDI_IS_ALLOCATED(bmap_first)) {
-            /* One or more new blocks were allocated. */
-            uint64_t offset;
-            logout("now writing modified block map entry %u...%u\n",
-                   bmap_first, bmap_last);
-            /* Write modified sectors from block map. */
-            bmap_first /= (SECTOR_SIZE / sizeof(uint32_t));
-            bmap_last /= (SECTOR_SIZE / sizeof(uint32_t));
-            n_sectors = bmap_last - bmap_first + 1;
-            offset = s->bmap_sector + bmap_first;
-            hd_iov.iov_base = (void *)((uint8_t *)&s->bmap[0] +
-                                            bmap_first * SECTOR_SIZE);
-            hd_iov.iov_len = n_sectors * SECTOR_SIZE;
-            qemu_iovec_init_external(&hd_qiov, &hd_iov, 1);
-            logout("will write %u block map sectors starting from entry %u\n",
-                   n_sectors, bmap_first);
-            ret = bdrv_co_writev(bs->file, offset, n_sectors, &hd_qiov);
+
+        if (ret < 0) {
+            return ret;
         }
+
+        logout("now writing modified block map entry %u...%u\n",
+               bmap_first, bmap_last);
+        /* Write modified sectors from block map. */
+        bmap_first /= (SECTOR_SIZE / sizeof(uint32_t));
+        bmap_last /= (SECTOR_SIZE / sizeof(uint32_t));
+        n_sectors = bmap_last - bmap_first + 1;
+        offset = s->bmap_sector + bmap_first;
+        base = ((uint8_t *)&s->bmap[0]) + bmap_first * SECTOR_SIZE;
+        logout("will write %u block map sectors starting from entry %u\n",
+               n_sectors, bmap_first);
+        ret = bdrv_write(bs->file, offset, base, n_sectors);
     }
 
     return ret;
@@ -641,7 +631,6 @@ static int vdi_create(const char *filename, QEMUOptionParameter *options)
     VdiHeader header;
     size_t i;
     size_t bmap_size;
-    uint32_t *bmap;
 
     logout("\n");
 
@@ -666,8 +655,9 @@ static int vdi_create(const char *filename, QEMUOptionParameter *options)
         options++;
     }
 
-    fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE,
-              0644);
+    fd = qemu_open(filename,
+                   O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE,
+                   0644);
     if (fd < 0) {
         return -errno;
     }
@@ -705,21 +695,21 @@ static int vdi_create(const char *filename, QEMUOptionParameter *options)
         result = -errno;
     }
 
-    bmap = NULL;
     if (bmap_size > 0) {
-        bmap = (uint32_t *)g_malloc0(bmap_size);
-    }
-    for (i = 0; i < blocks; i++) {
-        if (image_type == VDI_TYPE_STATIC) {
-            bmap[i] = i;
-        } else {
-            bmap[i] = VDI_UNALLOCATED;
+        uint32_t *bmap = g_malloc0(bmap_size);
+        for (i = 0; i < blocks; i++) {
+            if (image_type == VDI_TYPE_STATIC) {
+                bmap[i] = i;
+            } else {
+                bmap[i] = VDI_UNALLOCATED;
+            }
         }
+        if (write(fd, bmap, bmap_size) < 0) {
+            result = -errno;
+        }
+        g_free(bmap);
     }
-    if (write(fd, bmap, bmap_size) < 0) {
-        result = -errno;
-    }
-    g_free(bmap);
+
     if (image_type == VDI_TYPE_STATIC) {
         if (ftruncate(fd, sizeof(header) + bmap_size + blocks * block_size)) {
             result = -errno;
@@ -774,6 +764,7 @@ static BlockDriver bdrv_vdi = {
     .bdrv_probe = vdi_probe,
     .bdrv_open = vdi_open,
     .bdrv_close = vdi_close,
+    .bdrv_reopen_prepare = vdi_reopen_prepare,
     .bdrv_create = vdi_create,
     .bdrv_co_is_allocated = vdi_co_is_allocated,
     .bdrv_make_empty = vdi_make_empty,
This page took 0.032196 seconds and 4 git commands to generate.