qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Kevin Wolf <kwolf@redhat.com>
To: qemu-block@nongnu.org
Cc: kwolf@redhat.com, stefanha@redhat.com, famz@redhat.com,
	mreitz@redhat.com, jcody@redhat.com, qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH 17/17] block: Convert bdrv_co_preadv/pwritev to BdrvChild
Date: Tue, 21 Jun 2016 11:21:34 +0200	[thread overview]
Message-ID: <1466500894-9710-18-git-send-email-kwolf@redhat.com> (raw)
In-Reply-To: <1466500894-9710-1-git-send-email-kwolf@redhat.com>

This is the final patch for converting the common I/O path to take
a BdrvChild parameter instead of BlockDriverState.

The completion of this conversion means that all users that perform I/O
on an image need to actually hold a reference (in the form of BdrvChild,
possible as part of a BlockBackend) to that image. This also protects
against inconsistent use of BlockBackend vs. BlockDriverState functions
because direct use of a BlockDriverState isn't possible any more and
blk->root is private for block-backends.c.

In addition, we can now distinguish different users in the I/O path,
and the future op blockers work is going to add assertions based on
permissions stored in BdrvChild.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/blkreplay.c         |  6 +++---
 block/block-backend.c     |  4 ++--
 block/bochs.c             |  2 +-
 block/io.c                | 25 +++++++++++++------------
 block/qcow2-cluster.c     |  2 +-
 block/qcow2.c             |  6 +++---
 block/raw_bsd.c           |  4 ++--
 block/vdi.c               |  4 ++--
 block/vmdk.c              |  6 +++---
 block/vpc.c               |  8 ++++----
 include/block/block.h     |  4 ++--
 include/block/block_int.h |  4 ++--
 12 files changed, 38 insertions(+), 37 deletions(-)

diff --git a/block/blkreplay.c b/block/blkreplay.c
index 196b8d0..70650e4 100755
--- a/block/blkreplay.c
+++ b/block/blkreplay.c
@@ -85,7 +85,7 @@ static int coroutine_fn blkreplay_co_preadv(BlockDriverState *bs,
     uint64_t offset, uint64_t bytes, QEMUIOVector *qiov, int flags)
 {
     uint64_t reqid = request_id++;
-    int ret = bdrv_co_preadv(bs->file->bs, offset, bytes, qiov, flags);
+    int ret = bdrv_co_preadv(bs->file, offset, bytes, qiov, flags);
     block_request_create(reqid, bs, qemu_coroutine_self());
     qemu_coroutine_yield();
 
@@ -96,7 +96,7 @@ static int coroutine_fn blkreplay_co_pwritev(BlockDriverState *bs,
     uint64_t offset, uint64_t bytes, QEMUIOVector *qiov, int flags)
 {
     uint64_t reqid = request_id++;
-    int ret = bdrv_co_pwritev(bs->file->bs, offset, bytes, qiov, flags);
+    int ret = bdrv_co_pwritev(bs->file, offset, bytes, qiov, flags);
     block_request_create(reqid, bs, qemu_coroutine_self());
     qemu_coroutine_yield();
 
@@ -107,7 +107,7 @@ static int coroutine_fn blkreplay_co_pwrite_zeroes(BlockDriverState *bs,
     int64_t offset, int count, BdrvRequestFlags flags)
 {
     uint64_t reqid = request_id++;
-    int ret = bdrv_co_pwrite_zeroes(bs->file->bs, offset, count, flags);
+    int ret = bdrv_co_pwrite_zeroes(bs->file, offset, count, flags);
     block_request_create(reqid, bs, qemu_coroutine_self());
     qemu_coroutine_yield();
 
diff --git a/block/block-backend.c b/block/block-backend.c
index 389b36b..8b74780 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -760,7 +760,7 @@ int coroutine_fn blk_co_preadv(BlockBackend *blk, int64_t offset,
         throttle_group_co_io_limits_intercept(blk, bytes, false);
     }
 
-    return bdrv_co_preadv(blk_bs(blk), offset, bytes, qiov, flags);
+    return bdrv_co_preadv(blk->root, offset, bytes, qiov, flags);
 }
 
 int coroutine_fn blk_co_pwritev(BlockBackend *blk, int64_t offset,
@@ -785,7 +785,7 @@ int coroutine_fn blk_co_pwritev(BlockBackend *blk, int64_t offset,
         flags |= BDRV_REQ_FUA;
     }
 
-    return bdrv_co_pwritev(blk_bs(blk), offset, bytes, qiov, flags);
+    return bdrv_co_pwritev(blk->root, offset, bytes, qiov, flags);
 }
 
 typedef struct BlkRwCo {
diff --git a/block/bochs.c b/block/bochs.c
index e9323ec7..8125461 100644
--- a/block/bochs.c
+++ b/block/bochs.c
@@ -251,7 +251,7 @@ bochs_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
         qemu_iovec_concat(&local_qiov, qiov, bytes_done, 512);
 
         if (block_offset > 0) {
-            ret = bdrv_co_preadv(bs->file->bs, block_offset, 512,
+            ret = bdrv_co_preadv(bs->file, block_offset, 512,
                                  &local_qiov, 0);
             if (ret < 0) {
                 goto fail;
diff --git a/block/io.c b/block/io.c
index 78529fc..96d2b15 100644
--- a/block/io.c
+++ b/block/io.c
@@ -570,11 +570,11 @@ static void coroutine_fn bdrv_rw_co_entry(void *opaque)
     RwCo *rwco = opaque;
 
     if (!rwco->is_write) {
-        rwco->ret = bdrv_co_preadv(rwco->child->bs, rwco->offset,
+        rwco->ret = bdrv_co_preadv(rwco->child, rwco->offset,
                                    rwco->qiov->size, rwco->qiov,
                                    rwco->flags);
     } else {
-        rwco->ret = bdrv_co_pwritev(rwco->child->bs, rwco->offset,
+        rwco->ret = bdrv_co_pwritev(rwco->child, rwco->offset,
                                     rwco->qiov->size, rwco->qiov,
                                     rwco->flags);
     }
@@ -1057,10 +1057,11 @@ out:
 /*
  * Handle a read request in coroutine context
  */
-int coroutine_fn bdrv_co_preadv(BlockDriverState *bs,
+int coroutine_fn bdrv_co_preadv(BdrvChild *child,
     int64_t offset, unsigned int bytes, QEMUIOVector *qiov,
     BdrvRequestFlags flags)
 {
+    BlockDriverState *bs = child->bs;
     BlockDriver *drv = bs->drv;
     BdrvTrackedRequest req;
 
@@ -1133,7 +1134,7 @@ static int coroutine_fn bdrv_co_do_readv(BdrvChild *child,
         return -EINVAL;
     }
 
-    return bdrv_co_preadv(child->bs, sector_num << BDRV_SECTOR_BITS,
+    return bdrv_co_preadv(child, sector_num << BDRV_SECTOR_BITS,
                           nb_sectors << BDRV_SECTOR_BITS, qiov, flags);
 }
 
@@ -1398,10 +1399,11 @@ fail:
 /*
  * Handle a write request in coroutine context
  */
-int coroutine_fn bdrv_co_pwritev(BlockDriverState *bs,
+int coroutine_fn bdrv_co_pwritev(BdrvChild *child,
     int64_t offset, unsigned int bytes, QEMUIOVector *qiov,
     BdrvRequestFlags flags)
 {
+    BlockDriverState *bs = child->bs;
     BdrvTrackedRequest req;
     uint64_t align = bs->request_alignment;
     uint8_t *head_buf = NULL;
@@ -1535,7 +1537,7 @@ static int coroutine_fn bdrv_co_do_writev(BdrvChild *child,
         return -EINVAL;
     }
 
-    return bdrv_co_pwritev(child->bs, sector_num << BDRV_SECTOR_BITS,
+    return bdrv_co_pwritev(child, sector_num << BDRV_SECTOR_BITS,
                            nb_sectors << BDRV_SECTOR_BITS, qiov, flags);
 }
 
@@ -1547,17 +1549,16 @@ int coroutine_fn bdrv_co_writev(BdrvChild *child, int64_t sector_num,
     return bdrv_co_do_writev(child, sector_num, nb_sectors, qiov, 0);
 }
 
-int coroutine_fn bdrv_co_pwrite_zeroes(BlockDriverState *bs,
-                                       int64_t offset, int count,
-                                       BdrvRequestFlags flags)
+int coroutine_fn bdrv_co_pwrite_zeroes(BdrvChild *child, int64_t offset,
+                                       int count, BdrvRequestFlags flags)
 {
-    trace_bdrv_co_pwrite_zeroes(bs, offset, count, flags);
+    trace_bdrv_co_pwrite_zeroes(child->bs, offset, count, flags);
 
-    if (!(bs->open_flags & BDRV_O_UNMAP)) {
+    if (!(child->bs->open_flags & BDRV_O_UNMAP)) {
         flags &= ~BDRV_REQ_MAY_UNMAP;
     }
 
-    return bdrv_co_pwritev(bs, offset, count, NULL,
+    return bdrv_co_pwritev(child, offset, count, NULL,
                            BDRV_REQ_ZERO_WRITE | flags);
 }
 
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index 20ac99e..361f166 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -448,7 +448,7 @@ static int coroutine_fn do_perform_cow(BlockDriverState *bs,
     }
 
     BLKDBG_EVENT(bs->file, BLKDBG_COW_WRITE);
-    ret = bdrv_co_pwritev(bs->file->bs, cluster_offset + offset_in_cluster,
+    ret = bdrv_co_pwritev(bs->file, cluster_offset + offset_in_cluster,
                           bytes, &qiov, 0);
     if (ret < 0) {
         goto out;
diff --git a/block/qcow2.c b/block/qcow2.c
index 4aab822..1dbdbb6 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1442,7 +1442,7 @@ static coroutine_fn int qcow2_co_preadv(BlockDriverState *bs, uint64_t offset,
 
                     BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING_AIO);
                     qemu_co_mutex_unlock(&s->lock);
-                    ret = bdrv_co_preadv(bs->backing->bs, offset, n1,
+                    ret = bdrv_co_preadv(bs->backing, offset, n1,
                                          &local_qiov, 0);
                     qemu_co_mutex_lock(&s->lock);
 
@@ -1505,7 +1505,7 @@ static coroutine_fn int qcow2_co_preadv(BlockDriverState *bs, uint64_t offset,
 
             BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO);
             qemu_co_mutex_unlock(&s->lock);
-            ret = bdrv_co_preadv(bs->file->bs,
+            ret = bdrv_co_preadv(bs->file,
                                  cluster_offset + offset_in_cluster,
                                  cur_bytes, &hd_qiov, 0);
             qemu_co_mutex_lock(&s->lock);
@@ -1636,7 +1636,7 @@ static coroutine_fn int qcow2_co_pwritev(BlockDriverState *bs, uint64_t offset,
         BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
         trace_qcow2_writev_data(qemu_coroutine_self(),
                                 cluster_offset + offset_in_cluster);
-        ret = bdrv_co_pwritev(bs->file->bs,
+        ret = bdrv_co_pwritev(bs->file,
                               cluster_offset + offset_in_cluster,
                               cur_bytes, &hd_qiov, 0);
         qemu_co_mutex_lock(&s->lock);
diff --git a/block/raw_bsd.c b/block/raw_bsd.c
index 8a943a4..450bbb0 100644
--- a/block/raw_bsd.c
+++ b/block/raw_bsd.c
@@ -105,7 +105,7 @@ raw_co_writev_flags(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
     }
 
     BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
-    ret = bdrv_co_pwritev(bs->file->bs, sector_num * BDRV_SECTOR_SIZE,
+    ret = bdrv_co_pwritev(bs->file, sector_num * BDRV_SECTOR_SIZE,
                           nb_sectors * BDRV_SECTOR_SIZE, qiov, flags);
 
 fail:
@@ -131,7 +131,7 @@ static int coroutine_fn raw_co_pwrite_zeroes(BlockDriverState *bs,
                                              int64_t offset, int count,
                                              BdrvRequestFlags flags)
 {
-    return bdrv_co_pwrite_zeroes(bs->file->bs, offset, count, flags);
+    return bdrv_co_pwrite_zeroes(bs->file, offset, count, flags);
 }
 
 static int coroutine_fn raw_co_discard(BlockDriverState *bs,
diff --git a/block/vdi.c b/block/vdi.c
index a1a12d9..8a1cf97 100644
--- a/block/vdi.c
+++ b/block/vdi.c
@@ -597,7 +597,7 @@ vdi_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
             qemu_iovec_reset(&local_qiov);
             qemu_iovec_concat(&local_qiov, qiov, bytes_done, n_bytes);
 
-            ret = bdrv_co_preadv(bs->file->bs, data_offset, n_bytes,
+            ret = bdrv_co_preadv(bs->file, data_offset, n_bytes,
                                  &local_qiov, 0);
         }
         logout("%u bytes read\n", n_bytes);
@@ -690,7 +690,7 @@ vdi_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
             qemu_iovec_reset(&local_qiov);
             qemu_iovec_concat(&local_qiov, qiov, bytes_done, n_bytes);
 
-            ret = bdrv_co_pwritev(bs->file->bs, data_offset, n_bytes,
+            ret = bdrv_co_pwritev(bs->file, data_offset, n_bytes,
                                   &local_qiov, 0);
         }
 
diff --git a/block/vmdk.c b/block/vmdk.c
index 094013f..a37c85c 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -1371,7 +1371,7 @@ static int vmdk_write_extent(VmdkExtent *extent, int64_t cluster_offset,
     }
 
     write_offset = cluster_offset + offset_in_cluster,
-    ret = bdrv_co_pwritev(extent->file->bs, write_offset, n_bytes,
+    ret = bdrv_co_pwritev(extent->file, write_offset, n_bytes,
                           &local_qiov, 0);
 
     write_end_sector = DIV_ROUND_UP(write_offset + n_bytes, BDRV_SECTOR_SIZE);
@@ -1409,7 +1409,7 @@ static int vmdk_read_extent(VmdkExtent *extent, int64_t cluster_offset,
 
 
     if (!extent->compressed) {
-        ret = bdrv_co_preadv(extent->file->bs,
+        ret = bdrv_co_preadv(extent->file,
                              cluster_offset + offset_in_cluster, bytes,
                              qiov, 0);
         if (ret < 0) {
@@ -1499,7 +1499,7 @@ vmdk_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
                 qemu_iovec_reset(&local_qiov);
                 qemu_iovec_concat(&local_qiov, qiov, bytes_done, n_bytes);
 
-                ret = bdrv_co_preadv(bs->backing->bs, offset, n_bytes,
+                ret = bdrv_co_preadv(bs->backing, offset, n_bytes,
                                      &local_qiov, 0);
                 if (ret < 0) {
                     goto fail;
diff --git a/block/vpc.c b/block/vpc.c
index dcb5312..43707ed 100644
--- a/block/vpc.c
+++ b/block/vpc.c
@@ -591,7 +591,7 @@ vpc_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
     QEMUIOVector local_qiov;
 
     if (be32_to_cpu(footer->type) == VHD_FIXED) {
-        return bdrv_co_preadv(bs->file->bs, offset, bytes, qiov, 0);
+        return bdrv_co_preadv(bs->file, offset, bytes, qiov, 0);
     }
 
     qemu_co_mutex_lock(&s->lock);
@@ -607,7 +607,7 @@ vpc_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
             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,
+            ret = bdrv_co_preadv(bs->file, image_offset, n_bytes,
                                  &local_qiov, 0);
             if (ret < 0) {
                 goto fail;
@@ -640,7 +640,7 @@ vpc_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
     QEMUIOVector local_qiov;
 
     if (be32_to_cpu(footer->type) == VHD_FIXED) {
-        return bdrv_co_pwritev(bs->file->bs, offset, bytes, qiov, 0);
+        return bdrv_co_pwritev(bs->file, offset, bytes, qiov, 0);
     }
 
     qemu_co_mutex_lock(&s->lock);
@@ -661,7 +661,7 @@ vpc_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
         qemu_iovec_reset(&local_qiov);
         qemu_iovec_concat(&local_qiov, qiov, bytes_done, n_bytes);
 
-        ret = bdrv_co_pwritev(bs->file->bs, image_offset, n_bytes,
+        ret = bdrv_co_pwritev(bs->file, image_offset, n_bytes,
                               &local_qiov, 0);
         if (ret < 0) {
             goto fail;
diff --git a/include/block/block.h b/include/block/block.h
index abc5f26..12de4ea 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -249,8 +249,8 @@ int coroutine_fn bdrv_co_writev(BdrvChild *child, int64_t sector_num,
  * function is not suitable for zeroing the entire image in a single request
  * because it may allocate memory for the entire region.
  */
-int coroutine_fn bdrv_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset,
-    int count, BdrvRequestFlags flags);
+int coroutine_fn bdrv_co_pwrite_zeroes(BdrvChild *child, int64_t offset,
+                                       int count, BdrvRequestFlags flags);
 BlockDriverState *bdrv_find_backing_image(BlockDriverState *bs,
     const char *backing_file);
 int bdrv_get_backing_file_depth(BlockDriverState *bs);
diff --git a/include/block/block_int.h b/include/block/block_int.h
index 688c6be..fc11732 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -544,10 +544,10 @@ extern BlockDriver bdrv_qcow2;
  */
 void bdrv_setup_io_funcs(BlockDriver *bdrv);
 
-int coroutine_fn bdrv_co_preadv(BlockDriverState *bs,
+int coroutine_fn bdrv_co_preadv(BdrvChild *child,
     int64_t offset, unsigned int bytes, QEMUIOVector *qiov,
     BdrvRequestFlags flags);
-int coroutine_fn bdrv_co_pwritev(BlockDriverState *bs,
+int coroutine_fn bdrv_co_pwritev(BdrvChild *child,
     int64_t offset, unsigned int bytes, QEMUIOVector *qiov,
     BdrvRequestFlags flags);
 
-- 
1.8.3.1

  parent reply	other threads:[~2016-06-21  9:22 UTC|newest]

Thread overview: 48+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-06-21  9:21 [Qemu-devel] [PATCH 00/17] block: Convert common I/O path to BdrvChild Kevin Wolf
2016-06-21  9:21 ` [Qemu-devel] [PATCH 01/17] vvfat: Use BdrvChild for s->qcow Kevin Wolf
2016-06-22 16:54   ` Max Reitz
2016-06-21  9:21 ` [Qemu-devel] [PATCH 02/17] blkreplay: Convert to byte-based I/O Kevin Wolf
2016-06-22 17:03   ` Max Reitz
2016-06-22 17:15   ` Eric Blake
2016-06-21  9:21 ` [Qemu-devel] [PATCH 03/17] vhdx: Some more BlockBackend use in vhdx_create() Kevin Wolf
2016-06-22 17:08   ` Max Reitz
2016-06-21  9:21 ` [Qemu-devel] [PATCH 04/17] block: Convert bdrv_co_readv() to BdrvChild Kevin Wolf
2016-06-25 15:07   ` Max Reitz
2016-06-21  9:21 ` [Qemu-devel] [PATCH 05/17] block: Convert bdrv_co_writev() " Kevin Wolf
2016-06-25 15:14   ` Max Reitz
2016-06-27  8:56     ` Kevin Wolf
2016-06-21  9:21 ` [Qemu-devel] [PATCH 06/17] block: Convert bdrv_aio_readv() " Kevin Wolf
2016-06-25 15:16   ` Max Reitz
2016-06-21  9:21 ` [Qemu-devel] [PATCH 07/17] block: Convert bdrv_aio_writev() " Kevin Wolf
2016-06-25 15:20   ` Max Reitz
2016-06-21  9:21 ` [Qemu-devel] [PATCH 08/17] block: Convert bdrv_co_do_readv/writev " Kevin Wolf
2016-06-25 15:26   ` Max Reitz
2016-06-21  9:21 ` [Qemu-devel] [PATCH 09/17] block: Move bdrv_commit() to block/commit.c Kevin Wolf
2016-06-24 15:37   ` Eric Blake
2016-06-21  9:21 ` [Qemu-devel] [PATCH 10/17] block: Use BlockBackend for I/O in bdrv_commit() Kevin Wolf
2016-06-25 15:34   ` Max Reitz
2016-06-21  9:21 ` [Qemu-devel] [PATCH 11/17] block: Convert bdrv_read() to BdrvChild Kevin Wolf
2016-06-27 13:24   ` Max Reitz
2016-06-21  9:21 ` [Qemu-devel] [PATCH 12/17] block: Convert bdrv_write() " Kevin Wolf
2016-06-27 13:44   ` Max Reitz
2016-06-27 13:47     ` Max Reitz
2016-06-29 12:11       ` [Qemu-devel] [PATCH v2 " Kevin Wolf
2016-06-29 15:22         ` Max Reitz
2016-06-29 15:33           ` Kevin Wolf
2016-06-29 15:37             ` Max Reitz
2016-06-21  9:21 ` [Qemu-devel] [PATCH 13/17] block: Convert bdrv_pread(v) " Kevin Wolf
2016-06-27 14:55   ` Max Reitz
2016-06-21  9:21 ` [Qemu-devel] [PATCH 14/17] block: Convert bdrv_pwrite(v/_sync) " Kevin Wolf
2016-06-27 15:07   ` Max Reitz
2016-06-21  9:21 ` [Qemu-devel] [PATCH 15/17] block: Convert bdrv_pwrite_zeroes() " Kevin Wolf
2016-06-27 15:12   ` Max Reitz
2016-06-21  9:21 ` [Qemu-devel] [PATCH 16/17] block: Convert bdrv_prwv_co() " Kevin Wolf
2016-06-27 15:19   ` Max Reitz
2016-06-21  9:21 ` Kevin Wolf [this message]
2016-06-21  9:47 ` [Qemu-devel] [PATCH 00/17] block: Convert common I/O path " Paolo Bonzini
2016-06-21 10:56   ` Kevin Wolf
2016-06-21 11:01     ` Paolo Bonzini
2016-06-21 11:31       ` Kevin Wolf
2016-06-22  8:37         ` Fam Zheng
2016-06-28 13:28 ` Stefan Hajnoczi
2016-06-29 11:58   ` Kevin Wolf

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=1466500894-9710-18-git-send-email-kwolf@redhat.com \
    --to=kwolf@redhat.com \
    --cc=famz@redhat.com \
    --cc=jcody@redhat.com \
    --cc=mreitz@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=stefanha@redhat.com \
    /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).