All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kevin Wolf <kwolf@redhat.com>
To: qemu-block@nongnu.org
Cc: kwolf@redhat.com, mreitz@redhat.com, stefanha@redhat.com,
	famz@redhat.com, sw@weilnetz.de, qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH 14/17] vpc: Implement .bdrv_co_preadv() interface
Date: Wed, 27 Apr 2016 11:52:44 +0200	[thread overview]
Message-ID: <1461750767-23273-15-git-send-email-kwolf@redhat.com> (raw)
In-Reply-To: <1461750767-23273-1-git-send-email-kwolf@redhat.com>

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/vpc.c | 79 ++++++++++++++++++++++++++++++++-----------------------------
 1 file changed, 42 insertions(+), 37 deletions(-)

diff --git a/block/vpc.c b/block/vpc.c
index 3e2ea69..0099a80 100644
--- a/block/vpc.c
+++ b/block/vpc.c
@@ -454,22 +454,21 @@ static int vpc_reopen_prepare(BDRVReopenState *state,
  * The parameter write must be 1 if the offset will be used for a write
  * operation (the block bitmaps is updated then), 0 otherwise.
  */
-static inline int64_t get_sector_offset(BlockDriverState *bs,
-    int64_t sector_num, int write)
+static inline int64_t get_image_offset(BlockDriverState *bs, uint64_t offset,
+                                        bool write)
 {
     BDRVVPCState *s = bs->opaque;
-    uint64_t offset = sector_num * 512;
     uint64_t bitmap_offset, block_offset;
-    uint32_t pagetable_index, pageentry_index;
+    uint32_t pagetable_index, offset_in_block;
 
     pagetable_index = offset / s->block_size;
-    pageentry_index = (offset % s->block_size) / 512;
+    offset_in_block = offset % s->block_size;
 
     if (pagetable_index >= s->max_table_entries || s->pagetable[pagetable_index] == 0xffffffff)
         return -1; /* not allocated */
 
     bitmap_offset = 512 * (uint64_t) s->pagetable[pagetable_index];
-    block_offset = bitmap_offset + s->bitmap_size + (512 * pageentry_index);
+    block_offset = bitmap_offset + s->bitmap_size + offset_in_block;
 
     /* We must ensure that we don't write to any sectors which are marked as
        unused in the bitmap. We get away with setting all bits in the block
@@ -487,6 +486,12 @@ static inline int64_t get_sector_offset(BlockDriverState *bs,
     return block_offset;
 }
 
+static inline int64_t get_sector_offset(BlockDriverState *bs,
+                                        int64_t sector_num, bool write)
+{
+    return get_image_offset(bs, sector_num * BDRV_SECTOR_SIZE, write);
+}
+
 /*
  * Writes the footer to the end of the image file. This is needed when the
  * file grows as it overwrites the old footer
@@ -573,52 +578,52 @@ static int vpc_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
     return 0;
 }
 
-static int vpc_read(BlockDriverState *bs, int64_t sector_num,
-                    uint8_t *buf, int nb_sectors)
+static int coroutine_fn
+vpc_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
+              QEMUIOVector *qiov, int flags)
 {
     BDRVVPCState *s = bs->opaque;
     int ret;
-    int64_t offset;
-    int64_t sectors, sectors_per_block;
+    int64_t image_offset;
+    int64_t n_bytes;
+    int64_t bytes_done = 0;
     VHDFooter *footer = (VHDFooter *) s->footer_buf;
+    QEMUIOVector local_qiov;
 
     if (be32_to_cpu(footer->type) == VHD_FIXED) {
-        return bdrv_read(bs->file->bs, sector_num, buf, nb_sectors);
+        return bdrv_co_preadv(bs->file->bs, offset, bytes, qiov, 0);
     }
-    while (nb_sectors > 0) {
-        offset = get_sector_offset(bs, sector_num, 0);
 
-        sectors_per_block = s->block_size >> BDRV_SECTOR_BITS;
-        sectors = sectors_per_block - (sector_num % sectors_per_block);
-        if (sectors > nb_sectors) {
-            sectors = nb_sectors;
-        }
+    qemu_co_mutex_lock(&s->lock);
+    qemu_iovec_init(&local_qiov, qiov->niov);
 
-        if (offset == -1) {
-            memset(buf, 0, sectors * BDRV_SECTOR_SIZE);
+    while (bytes > 0) {
+        image_offset = get_image_offset(bs, offset, false);
+        n_bytes = MIN(bytes, s->block_size - (offset % s->block_size));
+
+        if (image_offset == -1) {
+            qemu_iovec_memset(qiov, bytes_done, 0, n_bytes);
         } else {
-            ret = bdrv_pread(bs->file->bs, offset, buf,
-                sectors * BDRV_SECTOR_SIZE);
-            if (ret != sectors * BDRV_SECTOR_SIZE) {
-                return -1;
+            qemu_iovec_reset(&local_qiov);
+            qemu_iovec_concat(&local_qiov, qiov, bytes_done, n_bytes);
+
+            ret = bdrv_co_preadv(bs->file->bs, image_offset, n_bytes,
+                                 &local_qiov, 0);
+            if (ret < 0) {
+                goto fail;
             }
         }
 
-        nb_sectors -= sectors;
-        sector_num += sectors;
-        buf += sectors * BDRV_SECTOR_SIZE;
+        bytes -= n_bytes;
+        offset += n_bytes;
+        bytes_done += n_bytes;
     }
-    return 0;
-}
 
-static coroutine_fn int vpc_co_read(BlockDriverState *bs, int64_t sector_num,
-                                    uint8_t *buf, int nb_sectors)
-{
-    int ret;
-    BDRVVPCState *s = bs->opaque;
-    qemu_co_mutex_lock(&s->lock);
-    ret = vpc_read(bs, sector_num, buf, nb_sectors);
+    ret = 0;
+fail:
+    qemu_iovec_destroy(&local_qiov);
     qemu_co_mutex_unlock(&s->lock);
+
     return ret;
 }
 
@@ -1056,7 +1061,7 @@ static BlockDriver bdrv_vpc = {
     .bdrv_reopen_prepare    = vpc_reopen_prepare,
     .bdrv_create            = vpc_create,
 
-    .bdrv_read                  = vpc_co_read,
+    .bdrv_co_preadv             = vpc_co_preadv,
     .bdrv_write                 = vpc_co_write,
     .bdrv_co_get_block_status   = vpc_co_get_block_status,
 
-- 
1.8.3.1

  parent reply	other threads:[~2016-04-27  9:53 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-04-27  9:52 [Qemu-devel] [PATCH 00/17] block: Convert .bdrv_read/write to .bdrv_preadv/pwritev Kevin Wolf
2016-04-27  9:52 ` [Qemu-devel] [PATCH 01/17] block: Introduce bdrv_driver_preadv() Kevin Wolf
2016-04-27 13:52   ` Eric Blake
2016-04-27  9:52 ` [Qemu-devel] [PATCH 02/17] block: Introduce bdrv_driver_pwritev() Kevin Wolf
2016-04-27 14:03   ` Eric Blake
2016-04-27  9:52 ` [Qemu-devel] [PATCH 03/17] block: Support AIO drivers in bdrv_driver_preadv/pwritev() Kevin Wolf
2016-04-27 14:13   ` Eric Blake
2016-04-27  9:52 ` [Qemu-devel] [PATCH 04/17] block: Rename bdrv_co_do_preadv/writev to bdrv_co_preadv/writev Kevin Wolf
2016-04-27 14:34   ` Eric Blake
2016-04-27 14:40     ` Kevin Wolf
2016-04-27  9:52 ` [Qemu-devel] [PATCH 05/17] block: Introduce .bdrv_co_preadv/pwritev BlockDriver function Kevin Wolf
2016-04-27 15:44   ` Eric Blake
2016-04-27  9:52 ` [Qemu-devel] [PATCH 06/17] bochs: Implement .bdrv_co_preadv() interface Kevin Wolf
2016-04-27 14:06   ` Stefan Hajnoczi
2016-04-27 14:33     ` Kevin Wolf
2016-04-27 15:51   ` Eric Blake
2016-04-28  8:21     ` Kevin Wolf
2016-04-28  8:42       ` Markus Armbruster
2016-04-27  9:52 ` [Qemu-devel] [PATCH 07/17] cloop: " Kevin Wolf
2016-04-27 14:12   ` Stefan Hajnoczi
2016-04-27  9:52 ` [Qemu-devel] [PATCH 08/17] dmg: " Kevin Wolf
2016-04-27  9:52 ` [Qemu-devel] [PATCH 09/17] vdi: " Kevin Wolf
2016-04-27  9:52 ` [Qemu-devel] [PATCH 10/17] vdi: Implement .bdrv_co_pwritev() interface Kevin Wolf
2016-04-27 14:17   ` Stefan Hajnoczi
2016-04-27 14:36     ` Kevin Wolf
2016-04-27  9:52 ` [Qemu-devel] [PATCH 11/17] vmdk: Add vmdk_find_offset_in_cluster() Kevin Wolf
2016-04-27  9:52 ` [Qemu-devel] [PATCH 12/17] vmdk: Implement .bdrv_co_preadv() interface Kevin Wolf
2016-04-27  9:52 ` [Qemu-devel] [PATCH 13/17] vmdk: Implement .bdrv_co_pwritev() interface Kevin Wolf
2016-04-27 14:21   ` Stefan Hajnoczi
2016-04-27  9:52 ` Kevin Wolf [this message]
2016-04-27  9:52 ` [Qemu-devel] [PATCH 15/17] vpc: " Kevin Wolf
2016-04-27  9:52 ` [Qemu-devel] [PATCH 16/17] vvfat: Implement .bdrv_co_preadv/pwritev interfaces Kevin Wolf
2016-04-27  9:52 ` [Qemu-devel] [PATCH 17/17] block: Remove BlockDriver.bdrv_read/write Kevin Wolf
2016-04-27 14:26 ` [Qemu-devel] [PATCH 00/17] block: Convert .bdrv_read/write to .bdrv_preadv/pwritev Stefan Hajnoczi

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=1461750767-23273-15-git-send-email-kwolf@redhat.com \
    --to=kwolf@redhat.com \
    --cc=famz@redhat.com \
    --cc=mreitz@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanha@redhat.com \
    --cc=sw@weilnetz.de \
    /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.