qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Stefan Hajnoczi <stefanha@redhat.com>
To: qemu-devel@nongnu.org
Cc: Kevin Wolf <kwolf@redhat.com>,
	Anthony Liguori <aliguori@us.ibm.com>,
	Stefan Hajnoczi <stefanha@redhat.com>
Subject: [Qemu-devel] [PATCH 03/11] block: Introduce bdrv_pwritev() for qcow2_save_vmstate
Date: Fri, 26 Apr 2013 13:44:25 +0200	[thread overview]
Message-ID: <1366976682-10251-6-git-send-email-stefanha@redhat.com> (raw)
In-Reply-To: <1366976682-10251-1-git-send-email-stefanha@redhat.com>

From: Kevin Wolf <kwolf@redhat.com>

Directly pass the QEMUIOVector on instead of linearising it.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
---
 block.c               | 80 +++++++++++++++++++++++++++++++++++++--------------
 block/qcow2.c         |  8 +-----
 include/block/block.h |  2 ++
 3 files changed, 61 insertions(+), 29 deletions(-)

diff --git a/block.c b/block.c
index 175497e..4ad663d 100644
--- a/block.c
+++ b/block.c
@@ -2131,27 +2131,21 @@ static void coroutine_fn bdrv_rw_co_entry(void *opaque)
 }
 
 /*
- * Process a synchronous request using coroutines
+ * Process a vectored synchronous request using coroutines
  */
-static int bdrv_rw_co(BlockDriverState *bs, int64_t sector_num, uint8_t *buf,
-                      int nb_sectors, bool is_write)
+static int bdrv_rwv_co(BlockDriverState *bs, int64_t sector_num,
+                       QEMUIOVector *qiov, bool is_write)
 {
-    QEMUIOVector qiov;
-    struct iovec iov = {
-        .iov_base = (void *)buf,
-        .iov_len = nb_sectors * BDRV_SECTOR_SIZE,
-    };
     Coroutine *co;
     RwCo rwco = {
         .bs = bs,
         .sector_num = sector_num,
-        .nb_sectors = nb_sectors,
-        .qiov = &qiov,
+        .nb_sectors = qiov->size >> BDRV_SECTOR_BITS,
+        .qiov = qiov,
         .is_write = is_write,
         .ret = NOT_DONE,
     };
-
-    qemu_iovec_init_external(&qiov, &iov, 1);
+    assert((qiov->size & (BDRV_SECTOR_SIZE - 1)) == 0);
 
     /**
      * In sync call context, when the vcpu is blocked, this throttling timer
@@ -2177,6 +2171,22 @@ static int bdrv_rw_co(BlockDriverState *bs, int64_t sector_num, uint8_t *buf,
     return rwco.ret;
 }
 
+/*
+ * Process a synchronous request using coroutines
+ */
+static int bdrv_rw_co(BlockDriverState *bs, int64_t sector_num, uint8_t *buf,
+                      int nb_sectors, bool is_write)
+{
+    QEMUIOVector qiov;
+    struct iovec iov = {
+        .iov_base = (void *)buf,
+        .iov_len = nb_sectors * BDRV_SECTOR_SIZE,
+    };
+
+    qemu_iovec_init_external(&qiov, &iov, 1);
+    return bdrv_rwv_co(bs, sector_num, &qiov, is_write);
+}
+
 /* return < 0 if error. See bdrv_write() for the return codes */
 int bdrv_read(BlockDriverState *bs, int64_t sector_num,
               uint8_t *buf, int nb_sectors)
@@ -2210,6 +2220,11 @@ int bdrv_write(BlockDriverState *bs, int64_t sector_num,
     return bdrv_rw_co(bs, sector_num, (uint8_t *)buf, nb_sectors, true);
 }
 
+int bdrv_writev(BlockDriverState *bs, int64_t sector_num, QEMUIOVector *qiov)
+{
+    return bdrv_rwv_co(bs, sector_num, qiov, true);
+}
+
 int bdrv_pread(BlockDriverState *bs, int64_t offset,
                void *buf, int count1)
 {
@@ -2255,15 +2270,15 @@ int bdrv_pread(BlockDriverState *bs, int64_t offset,
     return count1;
 }
 
-int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
-                const void *buf, int count1)
+int bdrv_pwritev(BlockDriverState *bs, int64_t offset, QEMUIOVector *qiov)
 {
     uint8_t tmp_buf[BDRV_SECTOR_SIZE];
     int len, nb_sectors, count;
     int64_t sector_num;
     int ret;
 
-    count = count1;
+    count = qiov->size;
+
     /* first write to align to sector start */
     len = (BDRV_SECTOR_SIZE - offset) & (BDRV_SECTOR_SIZE - 1);
     if (len > count)
@@ -2272,24 +2287,32 @@ int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
     if (len > 0) {
         if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
             return ret;
-        memcpy(tmp_buf + (offset & (BDRV_SECTOR_SIZE - 1)), buf, len);
+        qemu_iovec_to_buf(qiov, 0, tmp_buf + (offset & (BDRV_SECTOR_SIZE - 1)),
+                          len);
         if ((ret = bdrv_write(bs, sector_num, tmp_buf, 1)) < 0)
             return ret;
         count -= len;
         if (count == 0)
-            return count1;
+            return qiov->size;
         sector_num++;
-        buf += len;
     }
 
     /* write the sectors "in place" */
     nb_sectors = count >> BDRV_SECTOR_BITS;
     if (nb_sectors > 0) {
-        if ((ret = bdrv_write(bs, sector_num, buf, nb_sectors)) < 0)
+        QEMUIOVector qiov_inplace;
+
+        qemu_iovec_init(&qiov_inplace, qiov->niov);
+        qemu_iovec_concat(&qiov_inplace, qiov, len,
+                          nb_sectors << BDRV_SECTOR_BITS);
+        ret = bdrv_writev(bs, sector_num, &qiov_inplace);
+        qemu_iovec_destroy(&qiov_inplace);
+        if (ret < 0) {
             return ret;
+        }
+
         sector_num += nb_sectors;
         len = nb_sectors << BDRV_SECTOR_BITS;
-        buf += len;
         count -= len;
     }
 
@@ -2297,11 +2320,24 @@ int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
     if (count > 0) {
         if ((ret = bdrv_read(bs, sector_num, tmp_buf, 1)) < 0)
             return ret;
-        memcpy(tmp_buf, buf, count);
+        qemu_iovec_to_buf(qiov, qiov->size - count, tmp_buf, count);
         if ((ret = bdrv_write(bs, sector_num, tmp_buf, 1)) < 0)
             return ret;
     }
-    return count1;
+    return qiov->size;
+}
+
+int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
+                const void *buf, int count1)
+{
+    QEMUIOVector qiov;
+    struct iovec iov = {
+        .iov_base   = (void *) buf,
+        .iov_len    = count1,
+    };
+
+    qemu_iovec_init_external(&qiov, &iov, 1);
+    return bdrv_pwritev(bs, offset, &qiov);
 }
 
 /*
diff --git a/block/qcow2.c b/block/qcow2.c
index 1d856af..e8934de 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1658,18 +1658,12 @@ static int qcow2_save_vmstate(BlockDriverState *bs, QEMUIOVector *qiov,
     BDRVQcowState *s = bs->opaque;
     int growable = bs->growable;
     int ret;
-    void *buf;
-
-    buf = qemu_blockalign(bs, qiov->size);
-    qemu_iovec_to_buf(qiov, 0, buf, qiov->size);
 
     BLKDBG_EVENT(bs->file, BLKDBG_VMSTATE_SAVE);
     bs->growable = 1;
-    ret = bdrv_pwrite(bs, qcow2_vm_state_offset(s) + pos, buf, qiov->size);
+    ret = bdrv_pwritev(bs, qcow2_vm_state_offset(s) + pos, qiov);
     bs->growable = growable;
 
-    qemu_vfree(buf);
-
     return ret;
 }
 
diff --git a/include/block/block.h b/include/block/block.h
index e5fc566..ebd9512 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -166,10 +166,12 @@ int bdrv_read_unthrottled(BlockDriverState *bs, int64_t sector_num,
                           uint8_t *buf, int nb_sectors);
 int bdrv_write(BlockDriverState *bs, int64_t sector_num,
                const uint8_t *buf, int nb_sectors);
+int bdrv_writev(BlockDriverState *bs, int64_t sector_num, QEMUIOVector *qiov);
 int bdrv_pread(BlockDriverState *bs, int64_t offset,
                void *buf, int count);
 int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
                 const void *buf, int count);
+int bdrv_pwritev(BlockDriverState *bs, int64_t offset, QEMUIOVector *qiov);
 int bdrv_pwrite_sync(BlockDriverState *bs, int64_t offset,
     const void *buf, int count);
 int coroutine_fn bdrv_co_readv(BlockDriverState *bs, int64_t sector_num,
-- 
1.8.1.4

  parent reply	other threads:[~2013-04-26 11:45 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-04-26 11:44 [Qemu-devel] [PULL 00/11] Block patches Stefan Hajnoczi
2013-04-26 11:44 ` [Qemu-devel] [PATCH 01/11] block: Introduce bdrv_writev_vmstate Stefan Hajnoczi
2013-04-26 11:44 ` [Qemu-devel] [PATCH 01/11] block/ssh: Require libssh2 >= 1.2.8 Stefan Hajnoczi
2013-04-26 11:44 ` [Qemu-devel] [PATCH 02/11] savevm: Implement block_writev_buffer() Stefan Hajnoczi
2013-04-26 11:44 ` [Qemu-devel] [PATCH 02/11] sheepdog: add discard/trim support for sheepdog Stefan Hajnoczi
2013-04-26 11:44 ` Stefan Hajnoczi [this message]
2013-04-26 11:44 ` [Qemu-devel] [PATCH 03/11] sheepdog: use BDRV_SECTOR_SIZE Stefan Hajnoczi
2013-04-26 11:44 ` [Qemu-devel] [PATCH 04/11] qemu-iotests: A few more bdrv_pread/pwrite tests Stefan Hajnoczi
2013-04-26 11:44 ` [Qemu-devel] [PATCH 04/11] sheepdog: implement .bdrv_co_is_allocated() Stefan Hajnoczi
2013-04-26 11:44 ` [Qemu-devel] [PATCH 05/11] block: Disable driver-specific options for 1.5 Stefan Hajnoczi
2013-04-26 11:44 ` [Qemu-devel] [PATCH 05/11] qemu-iotests: Add test for -drive options Stefan Hajnoczi
2013-04-26 11:44 ` [Qemu-devel] [PATCH 06/11] qemu-iotests: filter QEMU_PROG in 051.out Stefan Hajnoczi
2013-04-26 11:44 ` [Qemu-devel] [PATCH 06/11] rbd: Fix use after free in rbd_open() Stefan Hajnoczi
2013-04-26 11:44 ` [Qemu-devel] [PATCH 07/11] ide: refuse WIN_READ_NATIVE_MAX on empty device Stefan Hajnoczi
2013-04-26 11:44 ` [Qemu-devel] [PATCH 07/11] sheepdog: cleanup find_vdi_name Stefan Hajnoczi
2013-04-26 11:44 ` [Qemu-devel] [PATCH 08/11] block: Add support for Secure Shell (ssh) block device Stefan Hajnoczi
2013-04-26 11:44 ` [Qemu-devel] [PATCH 08/11] sheepdog: add SD_RES_READONLY result code Stefan Hajnoczi
2013-04-26 11:44 ` [Qemu-devel] [PATCH 09/11] block: ssh: Use libssh2_sftp_fsync (if supported by libssh2) to flush to disk Stefan Hajnoczi
2013-04-26 11:44 ` [Qemu-devel] [PATCH 09/11] sheepdog: add helper function to reload inode Stefan Hajnoczi
2013-04-26 11:44 ` [Qemu-devel] [PATCH 10/11] iotests: Add 'check -ssh' option to test Secure Shell block device Stefan Hajnoczi
2013-04-26 11:44 ` [Qemu-devel] [PATCH 10/11] sheepdog: resend write requests when SD_RES_READONLY is received Stefan Hajnoczi
2013-04-26 11:44 ` [Qemu-devel] [PATCH 11/11] rbd: add an asynchronous flush Stefan Hajnoczi
2013-04-26 11:44 ` [Qemu-devel] [PATCH 11/11] sheepdog: fix loadvm operation Stefan Hajnoczi
  -- strict thread matches above, loose matches on Subject: below --
2013-04-15  8:22 [Qemu-devel] [PULL 00/11] Block patches Stefan Hajnoczi
2013-04-15  8:22 ` [Qemu-devel] [PATCH 03/11] block: Introduce bdrv_pwritev() for qcow2_save_vmstate 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=1366976682-10251-6-git-send-email-stefanha@redhat.com \
    --to=stefanha@redhat.com \
    --cc=aliguori@us.ibm.com \
    --cc=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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).