qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PULL 00/24] Block patches
@ 2011-10-14 16:48 Kevin Wolf
  2011-10-14 16:48 ` [Qemu-devel] [PATCH 01/24] block: allow resizing of images residing on host devices Kevin Wolf
                   ` (24 more replies)
  0 siblings, 25 replies; 27+ messages in thread
From: Kevin Wolf @ 2011-10-14 16:48 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

The following changes since commit ebffe2afceb1a17b5d134b5debf553955fe5ea1a:

  Merge remote-tracking branch 'qmp/queue/qmp' into staging (2011-10-10 08:21:46 -0500)

are available in the git repository at:

  git://repo.or.cz/qemu/kevin.git for-anthony

Christoph Hellwig (1):
      block: allow resizing of images residing on host devices

Kevin Wolf (3):
      linux-aio: Fix laio_submit error handling
      vvfat: Fix potential buffer overflow
      linux-aio: Allow reads beyond the end of growable images

Luiz Capitulino (6):
      block: Keep track of devices' I/O status
      virtio: Support I/O status
      ide: Support I/O status
      scsi: Support I/O status
      QMP: query-status: Add 'io-status' key
      HMP: Print 'io-status' information

Stefan Hajnoczi (12):
      block: directly invoke .bdrv_aio_*() in bdrv_co_io_em()
      block: directly invoke .bdrv_* from emulation functions
      block: split out bdrv_co_do_readv() and bdrv_co_do_writev()
      block: switch bdrv_read()/bdrv_write() to coroutines
      block: switch bdrv_aio_readv() to coroutines
      block: mark blocks dirty on coroutine write completion
      block: switch bdrv_aio_writev() to coroutines
      block: drop emulation functions that use coroutines
      raw-posix: remove bdrv_read()/bdrv_write()
      block: use coroutine interface for raw format
      block: drop .bdrv_read()/.bdrv_write() emulation
      block: drop bdrv_has_async_rw()

Stefan Weil (2):
      block/vvfat: Fix potential memory leaks and other memory errors
      block/vvfat: Remove unused code

 block.c           |  424 ++++++++++++++++++++++-------------------------------
 block.h           |   10 ++
 block/raw-posix.c |  301 +++-----------------------------------
 block/raw.c       |   32 +---
 block/vvfat.c     |  109 ++++----------
 block_int.h       |    1 +
 hw/ide/core.c     |    2 +
 hw/scsi-disk.c    |    2 +
 hw/virtio-blk.c   |    2 +
 linux-aio.c       |   21 ++-
 monitor.c         |    6 +
 qmp-commands.hx   |    6 +
 12 files changed, 283 insertions(+), 633 deletions(-)

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [Qemu-devel] [PATCH 01/24] block: allow resizing of images residing on host devices
  2011-10-14 16:48 [Qemu-devel] [PULL 00/24] Block patches Kevin Wolf
@ 2011-10-14 16:48 ` Kevin Wolf
  2011-10-14 16:48 ` [Qemu-devel] [PATCH 02/24] linux-aio: Fix laio_submit error handling Kevin Wolf
                   ` (23 subsequent siblings)
  24 siblings, 0 replies; 27+ messages in thread
From: Kevin Wolf @ 2011-10-14 16:48 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Christoph Hellwig <hch@lst.de>

Allow to resize images that reside on host devices up to the available
space.  This allows to grow images after resizing the device manually or
vice versa.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/raw-posix.c |   24 +++++++++++++++++++++---
 1 files changed, 21 insertions(+), 3 deletions(-)

diff --git a/block/raw-posix.c b/block/raw-posix.c
index 305998d..0b5e225 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -649,10 +649,24 @@ static void raw_close(BlockDriverState *bs)
 static int raw_truncate(BlockDriverState *bs, int64_t offset)
 {
     BDRVRawState *s = bs->opaque;
-    if (s->type != FTYPE_FILE)
-        return -ENOTSUP;
-    if (ftruncate(s->fd, offset) < 0)
+    struct stat st;
+
+    if (fstat(s->fd, &st)) {
         return -errno;
+    }
+
+    if (S_ISREG(st.st_mode)) {
+        if (ftruncate(s->fd, offset) < 0) {
+            return -errno;
+        }
+    } else if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) {
+       if (offset > raw_getlength(bs)) {
+           return -EINVAL;
+       }
+    } else {
+        return -ENOTSUP;
+    }
+
     return 0;
 }
 
@@ -1178,6 +1192,7 @@ static BlockDriver bdrv_host_device = {
 
     .bdrv_read          = raw_read,
     .bdrv_write         = raw_write,
+    .bdrv_truncate      = raw_truncate,
     .bdrv_getlength	= raw_getlength,
     .bdrv_get_allocated_file_size
                         = raw_get_allocated_file_size,
@@ -1299,6 +1314,7 @@ static BlockDriver bdrv_host_floppy = {
 
     .bdrv_read          = raw_read,
     .bdrv_write         = raw_write,
+    .bdrv_truncate      = raw_truncate,
     .bdrv_getlength	= raw_getlength,
     .bdrv_get_allocated_file_size
                         = raw_get_allocated_file_size,
@@ -1400,6 +1416,7 @@ static BlockDriver bdrv_host_cdrom = {
 
     .bdrv_read          = raw_read,
     .bdrv_write         = raw_write,
+    .bdrv_truncate      = raw_truncate,
     .bdrv_getlength     = raw_getlength,
     .bdrv_get_allocated_file_size
                         = raw_get_allocated_file_size,
@@ -1521,6 +1538,7 @@ static BlockDriver bdrv_host_cdrom = {
 
     .bdrv_read          = raw_read,
     .bdrv_write         = raw_write,
+    .bdrv_truncate      = raw_truncate,
     .bdrv_getlength     = raw_getlength,
     .bdrv_get_allocated_file_size
                         = raw_get_allocated_file_size,
-- 
1.7.6.4

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [Qemu-devel] [PATCH 02/24] linux-aio: Fix laio_submit error handling
  2011-10-14 16:48 [Qemu-devel] [PULL 00/24] Block patches Kevin Wolf
  2011-10-14 16:48 ` [Qemu-devel] [PATCH 01/24] block: allow resizing of images residing on host devices Kevin Wolf
@ 2011-10-14 16:48 ` Kevin Wolf
  2011-10-14 16:48 ` [Qemu-devel] [PATCH 03/24] block: Keep track of devices' I/O status Kevin Wolf
                   ` (22 subsequent siblings)
  24 siblings, 0 replies; 27+ messages in thread
From: Kevin Wolf @ 2011-10-14 16:48 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

The error handling order was in the wrong order, so that either the ACB would
be leaked or the counter would be decremented when it shouldn't.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 linux-aio.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/linux-aio.c b/linux-aio.c
index bffa6cd..50da75d 100644
--- a/linux-aio.c
+++ b/linux-aio.c
@@ -185,10 +185,10 @@ BlockDriverAIOCB *laio_submit(BlockDriverState *bs, void *aio_ctx, int fd,
         goto out_dec_count;
     return &laiocb->common;
 
-out_free_aiocb:
-    qemu_aio_release(laiocb);
 out_dec_count:
     s->count--;
+out_free_aiocb:
+    qemu_aio_release(laiocb);
     return NULL;
 }
 
-- 
1.7.6.4

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [Qemu-devel] [PATCH 03/24] block: Keep track of devices' I/O status
  2011-10-14 16:48 [Qemu-devel] [PULL 00/24] Block patches Kevin Wolf
  2011-10-14 16:48 ` [Qemu-devel] [PATCH 01/24] block: allow resizing of images residing on host devices Kevin Wolf
  2011-10-14 16:48 ` [Qemu-devel] [PATCH 02/24] linux-aio: Fix laio_submit error handling Kevin Wolf
@ 2011-10-14 16:48 ` Kevin Wolf
  2011-10-14 16:48 ` [Qemu-devel] [PATCH 04/24] virtio: Support " Kevin Wolf
                   ` (21 subsequent siblings)
  24 siblings, 0 replies; 27+ messages in thread
From: Kevin Wolf @ 2011-10-14 16:48 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Luiz Capitulino <lcapitulino@redhat.com>

This commit adds support to the BlockDriverState type to keep track
of devices' I/O status.

There are three possible status: BDRV_IOS_OK (no error), BDRV_IOS_ENOSPC
(no space error) and BDRV_IOS_FAILED (any other error). The distinction
between no space and other errors is important because a management
application may want to watch for no space in order to extend the
space assigned to the VM and put it to run again.

Qemu devices supporting the I/O status feature have to enable it
explicitly by calling bdrv_iostatus_enable() _and_ have to be
configured to stop the VM on errors (ie. werror=stop|enospc or
rerror=stop).

In case of multiple errors being triggered in sequence only the first
one is stored. The I/O status is always reset to BDRV_IOS_OK when the
'cont' command is issued.

Next commits will add support to some devices and extend the
query-block/info block commands to return the I/O status information.

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block.c     |   40 ++++++++++++++++++++++++++++++++++++++++
 block.h     |   10 ++++++++++
 block_int.h |    1 +
 monitor.c   |    6 ++++++
 4 files changed, 57 insertions(+), 0 deletions(-)

diff --git a/block.c b/block.c
index e865fab..92ec2c3 100644
--- a/block.c
+++ b/block.c
@@ -221,6 +221,7 @@ BlockDriverState *bdrv_new(const char *device_name)
     if (device_name[0] != '\0') {
         QTAILQ_INSERT_TAIL(&bdrv_states, bs, list);
     }
+    bdrv_iostatus_disable(bs);
     return bs;
 }
 
@@ -772,6 +773,7 @@ int bdrv_attach_dev(BlockDriverState *bs, void *dev)
         return -EBUSY;
     }
     bs->dev = dev;
+    bdrv_iostatus_reset(bs);
     return 0;
 }
 
@@ -3183,6 +3185,44 @@ int bdrv_in_use(BlockDriverState *bs)
     return bs->in_use;
 }
 
+void bdrv_iostatus_enable(BlockDriverState *bs)
+{
+    bs->iostatus = BDRV_IOS_OK;
+}
+
+/* The I/O status is only enabled if the drive explicitly
+ * enables it _and_ the VM is configured to stop on errors */
+bool bdrv_iostatus_is_enabled(const BlockDriverState *bs)
+{
+    return (bs->iostatus != BDRV_IOS_INVAL &&
+           (bs->on_write_error == BLOCK_ERR_STOP_ENOSPC ||
+            bs->on_write_error == BLOCK_ERR_STOP_ANY    ||
+            bs->on_read_error == BLOCK_ERR_STOP_ANY));
+}
+
+void bdrv_iostatus_disable(BlockDriverState *bs)
+{
+    bs->iostatus = BDRV_IOS_INVAL;
+}
+
+void bdrv_iostatus_reset(BlockDriverState *bs)
+{
+    if (bdrv_iostatus_is_enabled(bs)) {
+        bs->iostatus = BDRV_IOS_OK;
+    }
+}
+
+/* XXX: Today this is set by device models because it makes the implementation
+   quite simple. However, the block layer knows about the error, so it's
+   possible to implement this without device models being involved */
+void bdrv_iostatus_set_err(BlockDriverState *bs, int error)
+{
+    if (bdrv_iostatus_is_enabled(bs) && bs->iostatus == BDRV_IOS_OK) {
+        assert(error >= 0);
+        bs->iostatus = error == ENOSPC ? BDRV_IOS_ENOSPC : BDRV_IOS_FAILED;
+    }
+}
+
 void
 bdrv_acct_start(BlockDriverState *bs, BlockAcctCookie *cookie, int64_t bytes,
         enum BlockAcctType type)
diff --git a/block.h b/block.h
index 16bfa0a..e77988e 100644
--- a/block.h
+++ b/block.h
@@ -77,6 +77,16 @@ typedef enum {
     BDRV_ACTION_REPORT, BDRV_ACTION_IGNORE, BDRV_ACTION_STOP
 } BlockMonEventAction;
 
+typedef enum {
+    BDRV_IOS_INVAL, BDRV_IOS_OK, BDRV_IOS_FAILED, BDRV_IOS_ENOSPC,
+    BDRV_IOS_MAX
+} BlockIOStatus;
+
+void bdrv_iostatus_enable(BlockDriverState *bs);
+void bdrv_iostatus_reset(BlockDriverState *bs);
+void bdrv_iostatus_disable(BlockDriverState *bs);
+bool bdrv_iostatus_is_enabled(const BlockDriverState *bs);
+void bdrv_iostatus_set_err(BlockDriverState *bs, int error);
 void bdrv_mon_event(const BlockDriverState *bdrv,
                     BlockMonEventAction action, int is_read);
 void bdrv_info_print(Monitor *mon, const QObject *data);
diff --git a/block_int.h b/block_int.h
index 8c3b863..f2f4f2d 100644
--- a/block_int.h
+++ b/block_int.h
@@ -199,6 +199,7 @@ struct BlockDriverState {
        drivers. They are not used by the block driver */
     int cyls, heads, secs, translation;
     BlockErrorAction on_read_error, on_write_error;
+    BlockIOStatus iostatus;
     char device_name[32];
     unsigned long *dirty_bitmap;
     int64_t dirty_count;
diff --git a/monitor.c b/monitor.c
index 31b212a..1a28956 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1221,6 +1221,11 @@ struct bdrv_iterate_context {
     int err;
 };
 
+static void iostatus_bdrv_it(void *opaque, BlockDriverState *bs)
+{
+    bdrv_iostatus_reset(bs);
+}
+
 /**
  * do_cont(): Resume emulation.
  */
@@ -1237,6 +1242,7 @@ static int do_cont(Monitor *mon, const QDict *qdict, QObject **ret_data)
         return -1;
     }
 
+    bdrv_iterate(iostatus_bdrv_it, NULL);
     bdrv_iterate(encrypted_bdrv_it, &context);
     /* only resume the vm if all keys are set and valid */
     if (!context.err) {
-- 
1.7.6.4

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [Qemu-devel] [PATCH 04/24] virtio: Support I/O status
  2011-10-14 16:48 [Qemu-devel] [PULL 00/24] Block patches Kevin Wolf
                   ` (2 preceding siblings ...)
  2011-10-14 16:48 ` [Qemu-devel] [PATCH 03/24] block: Keep track of devices' I/O status Kevin Wolf
@ 2011-10-14 16:48 ` Kevin Wolf
  2011-10-14 16:49 ` [Qemu-devel] [PATCH 05/24] ide: " Kevin Wolf
                   ` (20 subsequent siblings)
  24 siblings, 0 replies; 27+ messages in thread
From: Kevin Wolf @ 2011-10-14 16:48 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Luiz Capitulino <lcapitulino@redhat.com>

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 hw/virtio-blk.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c
index 03878bf..2a5d1a9 100644
--- a/hw/virtio-blk.c
+++ b/hw/virtio-blk.c
@@ -78,6 +78,7 @@ static int virtio_blk_handle_rw_error(VirtIOBlockReq *req, int error,
         s->rq = req;
         bdrv_mon_event(s->bs, BDRV_ACTION_STOP, is_read);
         vm_stop(RUN_STATE_IO_ERROR);
+        bdrv_iostatus_set_err(s->bs, error);
     } else {
         virtio_blk_req_complete(req, VIRTIO_BLK_S_IOERR);
         bdrv_acct_done(s->bs, &req->acct);
@@ -603,6 +604,7 @@ VirtIODevice *virtio_blk_init(DeviceState *dev, BlockConf *conf,
     bdrv_set_dev_ops(s->bs, &virtio_block_ops, s);
     bdrv_set_buffer_alignment(s->bs, conf->logical_block_size);
 
+    bdrv_iostatus_enable(s->bs);
     add_boot_device_path(conf->bootindex, dev, "/disk@0,0");
 
     return &s->vdev;
-- 
1.7.6.4

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [Qemu-devel] [PATCH 05/24] ide: Support I/O status
  2011-10-14 16:48 [Qemu-devel] [PULL 00/24] Block patches Kevin Wolf
                   ` (3 preceding siblings ...)
  2011-10-14 16:48 ` [Qemu-devel] [PATCH 04/24] virtio: Support " Kevin Wolf
@ 2011-10-14 16:49 ` Kevin Wolf
  2011-10-14 16:49 ` [Qemu-devel] [PATCH 06/24] scsi: " Kevin Wolf
                   ` (19 subsequent siblings)
  24 siblings, 0 replies; 27+ messages in thread
From: Kevin Wolf @ 2011-10-14 16:49 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Luiz Capitulino <lcapitulino@redhat.com>

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 hw/ide/core.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/hw/ide/core.c b/hw/ide/core.c
index b71a356..fbc0859 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -528,6 +528,7 @@ static int ide_handle_rw_error(IDEState *s, int error, int op)
         s->bus->error_status = op;
         bdrv_mon_event(s->bs, BDRV_ACTION_STOP, is_read);
         vm_stop(RUN_STATE_IO_ERROR);
+        bdrv_iostatus_set_err(s->bs, error);
     } else {
         if (op & BM_STATUS_DMA_RETRY) {
             dma_buf_commit(s, 0);
@@ -1872,6 +1873,7 @@ int ide_init_drive(IDEState *s, BlockDriverState *bs, IDEDriveKind kind,
     }
 
     ide_reset(s);
+    bdrv_iostatus_enable(bs);
     return 0;
 }
 
-- 
1.7.6.4

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [Qemu-devel] [PATCH 06/24] scsi: Support I/O status
  2011-10-14 16:48 [Qemu-devel] [PULL 00/24] Block patches Kevin Wolf
                   ` (4 preceding siblings ...)
  2011-10-14 16:49 ` [Qemu-devel] [PATCH 05/24] ide: " Kevin Wolf
@ 2011-10-14 16:49 ` Kevin Wolf
  2011-10-14 16:49 ` [Qemu-devel] [PATCH 07/24] QMP: query-status: Add 'io-status' key Kevin Wolf
                   ` (18 subsequent siblings)
  24 siblings, 0 replies; 27+ messages in thread
From: Kevin Wolf @ 2011-10-14 16:49 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Luiz Capitulino <lcapitulino@redhat.com>

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 hw/scsi-disk.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c
index 4f681ef..6909578 100644
--- a/hw/scsi-disk.c
+++ b/hw/scsi-disk.c
@@ -228,6 +228,7 @@ static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int type)
 
         bdrv_mon_event(s->bs, BDRV_ACTION_STOP, is_read);
         vm_stop(RUN_STATE_IO_ERROR);
+        bdrv_iostatus_set_err(s->bs, error);
     } else {
         switch (error) {
         case ENOMEM:
@@ -1260,6 +1261,7 @@ static int scsi_initfn(SCSIDevice *dev, uint8_t scsi_type)
 
     s->qdev.type = scsi_type;
     qemu_add_vm_change_state_handler(scsi_dma_restart_cb, s);
+    bdrv_iostatus_enable(s->bs);
     add_boot_device_path(s->qdev.conf.bootindex, &dev->qdev, ",0");
     return 0;
 }
-- 
1.7.6.4

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [Qemu-devel] [PATCH 07/24] QMP: query-status: Add 'io-status' key
  2011-10-14 16:48 [Qemu-devel] [PULL 00/24] Block patches Kevin Wolf
                   ` (5 preceding siblings ...)
  2011-10-14 16:49 ` [Qemu-devel] [PATCH 06/24] scsi: " Kevin Wolf
@ 2011-10-14 16:49 ` Kevin Wolf
  2011-10-14 16:49 ` [Qemu-devel] [PATCH 08/24] HMP: Print 'io-status' information Kevin Wolf
                   ` (17 subsequent siblings)
  24 siblings, 0 replies; 27+ messages in thread
From: Kevin Wolf @ 2011-10-14 16:49 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Luiz Capitulino <lcapitulino@redhat.com>

Contains the I/O status for the given device. The key is only present
if the device supports it and the VM is configured to stop on errors.

Please, check the documentation being added in this commit for more
information.

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block.c         |   12 ++++++++++++
 qmp-commands.hx |    6 ++++++
 2 files changed, 18 insertions(+), 0 deletions(-)

diff --git a/block.c b/block.c
index 92ec2c3..40621b1 100644
--- a/block.c
+++ b/block.c
@@ -1893,6 +1893,12 @@ void bdrv_info_print(Monitor *mon, const QObject *data)
     qlist_iter(qobject_to_qlist(data), bdrv_print_dict, mon);
 }
 
+static const char *const io_status_name[BDRV_IOS_MAX] = {
+    [BDRV_IOS_OK] = "ok",
+    [BDRV_IOS_FAILED] = "failed",
+    [BDRV_IOS_ENOSPC] = "nospace",
+};
+
 void bdrv_info(Monitor *mon, QObject **ret_data)
 {
     QList *bs_list;
@@ -1915,6 +1921,12 @@ void bdrv_info(Monitor *mon, QObject **ret_data)
             qdict_put(bs_dict, "tray-open",
                       qbool_from_int(bdrv_dev_is_tray_open(bs)));
         }
+
+        if (bdrv_iostatus_is_enabled(bs)) {
+            qdict_put(bs_dict, "io-status",
+                      qstring_from_str(io_status_name[bs->iostatus]));
+        }
+
         if (bs->drv) {
             QObject *obj;
 
diff --git a/qmp-commands.hx b/qmp-commands.hx
index ea96191..9c11e87 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -1154,6 +1154,10 @@ Each json-object contain the following:
                                 "tftp", "vdi", "vmdk", "vpc", "vvfat"
          - "backing_file": backing file name (json-string, optional)
          - "encrypted": true if encrypted, false otherwise (json-bool)
+- "io-status": I/O operation status, only present if the device supports it
+               and the VM is configured to stop on errors. It's always reset
+               to "ok" when the "cont" command is issued (json_string, optional)
+             - Possible values: "ok", "failed", "nospace"
 
 Example:
 
@@ -1161,6 +1165,7 @@ Example:
 <- {
       "return":[
          {
+            "io-status": "ok",
             "device":"ide0-hd0",
             "locked":false,
             "removable":false,
@@ -1173,6 +1178,7 @@ Example:
             "type":"unknown"
          },
          {
+            "io-status": "ok",
             "device":"ide1-cd0",
             "locked":false,
             "removable":true,
-- 
1.7.6.4

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [Qemu-devel] [PATCH 08/24] HMP: Print 'io-status' information
  2011-10-14 16:48 [Qemu-devel] [PULL 00/24] Block patches Kevin Wolf
                   ` (6 preceding siblings ...)
  2011-10-14 16:49 ` [Qemu-devel] [PATCH 07/24] QMP: query-status: Add 'io-status' key Kevin Wolf
@ 2011-10-14 16:49 ` Kevin Wolf
  2011-10-14 16:49 ` [Qemu-devel] [PATCH 09/24] block/vvfat: Fix potential memory leaks and other memory errors Kevin Wolf
                   ` (16 subsequent siblings)
  24 siblings, 0 replies; 27+ messages in thread
From: Kevin Wolf @ 2011-10-14 16:49 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Luiz Capitulino <lcapitulino@redhat.com>

Signed-off-by: Luiz Capitulino <lcapitulino@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/block.c b/block.c
index 40621b1..25b03dd 100644
--- a/block.c
+++ b/block.c
@@ -1868,6 +1868,11 @@ static void bdrv_print_dict(QObject *obj, void *opaque)
         monitor_printf(mon, " tray-open=%d",
                        qdict_get_bool(bs_dict, "tray-open"));
     }
+
+    if (qdict_haskey(bs_dict, "io-status")) {
+        monitor_printf(mon, " io-status=%s", qdict_get_str(bs_dict, "io-status"));
+    }
+
     if (qdict_haskey(bs_dict, "inserted")) {
         QDict *qdict = qobject_to_qdict(qdict_get(bs_dict, "inserted"));
 
-- 
1.7.6.4

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [Qemu-devel] [PATCH 09/24] block/vvfat: Fix potential memory leaks and other memory errors
  2011-10-14 16:48 [Qemu-devel] [PULL 00/24] Block patches Kevin Wolf
                   ` (7 preceding siblings ...)
  2011-10-14 16:49 ` [Qemu-devel] [PATCH 08/24] HMP: Print 'io-status' information Kevin Wolf
@ 2011-10-14 16:49 ` Kevin Wolf
  2011-10-14 16:49 ` [Qemu-devel] [PATCH 10/24] block/vvfat: Remove unused code Kevin Wolf
                   ` (15 subsequent siblings)
  24 siblings, 0 replies; 27+ messages in thread
From: Kevin Wolf @ 2011-10-14 16:49 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Stefan Weil <weil@mail.berlios.de>

cppcheck reported memory leaks and mismatched g_malloc() with free()
instead of g_free().

Fix these errors.

Cc: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Stefan Weil <weil@mail.berlios.de>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/vvfat.c |   51 ++++++++++++++++++++++++++++++---------------------
 1 files changed, 30 insertions(+), 21 deletions(-)

diff --git a/block/vvfat.c b/block/vvfat.c
index f567c9a..f45939d 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -86,8 +86,7 @@ static inline void array_init(array_t* array,unsigned int item_size)
 
 static inline void array_free(array_t* array)
 {
-    if(array->pointer)
-        free(array->pointer);
+    g_free(array->pointer);
     array->size=array->next=0;
 }
 
@@ -169,7 +168,7 @@ static inline int array_roll(array_t* array,int index_to,int index_from,int coun
 
     memcpy(to,buf,is*count);
 
-    free(buf);
+    g_free(buf);
 
     return 0;
 }
@@ -732,7 +731,7 @@ static int read_directory(BDRVVVFATState* s, int mapping_index)
 	snprintf(buffer,length,"%s/%s",dirname,entry->d_name);
 
 	if(stat(buffer,&st)<0) {
-	    free(buffer);
+            g_free(buffer);
             continue;
 	}
 
@@ -755,7 +754,7 @@ static int read_directory(BDRVVVFATState* s, int mapping_index)
 	    direntry->begin=0; /* do that later */
         if (st.st_size > 0x7fffffff) {
 	    fprintf(stderr, "File %s is larger than 2GB\n", buffer);
-	    free(buffer);
+            g_free(buffer);
             closedir(dir);
 	    return -2;
         }
@@ -1375,7 +1374,7 @@ DLOG(fprintf(stderr, "clear_commits (%d commits)\n", s->commits.next));
 	assert(commit->path || commit->action == ACTION_WRITEOUT);
 	if (commit->action != ACTION_WRITEOUT) {
 	    assert(commit->path);
-	    free(commit->path);
+            g_free(commit->path);
 	} else
 	    assert(commit->path == NULL);
     }
@@ -1782,7 +1781,7 @@ DLOG(fprintf(stderr, "read cluster %d (sector %d)\n", (int)cluster_num, (int)clu
 	if (subret) {
 	    fprintf(stderr, "Error fetching direntries\n");
 	fail:
-	    free(cluster);
+            g_free(cluster);
 	    return 0;
 	}
 
@@ -1850,7 +1849,7 @@ DLOG(fprintf(stderr, "check direntry %d:\n", i); print_direntry(direntries + i))
 	cluster_num = modified_fat_get(s, cluster_num);
     } while(!fat_eof(s, cluster_num));
 
-    free(cluster);
+    g_free(cluster);
     return ret;
 }
 
@@ -1995,8 +1994,9 @@ static int remove_mapping(BDRVVVFATState* s, int mapping_index)
     mapping_t* first_mapping = array_get(&(s->mapping), 0);
 
     /* free mapping */
-    if (mapping->first_mapping_index < 0)
-	free(mapping->path);
+    if (mapping->first_mapping_index < 0) {
+        g_free(mapping->path);
+    }
 
     /* remove from s->mapping */
     array_remove(&(s->mapping), mapping_index);
@@ -2232,11 +2232,15 @@ static int commit_one_file(BDRVVVFATState* s,
     if (fd < 0) {
 	fprintf(stderr, "Could not open %s... (%s, %d)\n", mapping->path,
 		strerror(errno), errno);
+        g_free(cluster);
 	return fd;
     }
-    if (offset > 0)
-	if (lseek(fd, offset, SEEK_SET) != offset)
-	    return -3;
+    if (offset > 0) {
+        if (lseek(fd, offset, SEEK_SET) != offset) {
+            g_free(cluster);
+            return -3;
+        }
+    }
 
     while (offset < size) {
 	uint32_t c1;
@@ -2252,11 +2256,15 @@ static int commit_one_file(BDRVVVFATState* s,
 	ret = vvfat_read(s->bs, cluster2sector(s, c),
 	    (uint8_t*)cluster, (rest_size + 0x1ff) / 0x200);
 
-	if (ret < 0)
-	    return ret;
+        if (ret < 0) {
+            g_free(cluster);
+            return ret;
+        }
 
-	if (write(fd, cluster, rest_size) < 0)
-	    return -2;
+        if (write(fd, cluster, rest_size) < 0) {
+            g_free(cluster);
+            return -2;
+        }
 
 	offset += rest_size;
 	c = c1;
@@ -2265,9 +2273,11 @@ static int commit_one_file(BDRVVVFATState* s,
     if (ftruncate(fd, size)) {
         perror("ftruncate()");
         close(fd);
+        g_free(cluster);
         return -4;
     }
     close(fd);
+    g_free(cluster);
 
     return commit_mappings(s, first_cluster, dir_index);
 }
@@ -2399,7 +2409,7 @@ static int handle_renames_and_mkdirs(BDRVVVFATState* s)
 		}
 	    }
 
-	    free(old_path);
+            g_free(old_path);
 	    array_remove(&(s->commits), i);
 	    continue;
 	} else if (commit->action == ACTION_MKDIR) {
@@ -2775,7 +2785,7 @@ static int write_target_commit(BlockDriverState *bs, int64_t sector_num,
 static void write_target_close(BlockDriverState *bs) {
     BDRVVVFATState* s = *((BDRVVVFATState**) bs->opaque);
     bdrv_delete(s->qcow);
-    free(s->qcow_filename);
+    g_free(s->qcow_filename);
 }
 
 static BlockDriver vvfat_write_target = {
@@ -2836,8 +2846,7 @@ static void vvfat_close(BlockDriverState *bs)
     array_free(&(s->fat));
     array_free(&(s->directory));
     array_free(&(s->mapping));
-    if(s->cluster_buffer)
-        free(s->cluster_buffer);
+    g_free(s->cluster_buffer);
 }
 
 static BlockDriver bdrv_vvfat = {
-- 
1.7.6.4

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [Qemu-devel] [PATCH 10/24] block/vvfat: Remove unused code
  2011-10-14 16:48 [Qemu-devel] [PULL 00/24] Block patches Kevin Wolf
                   ` (8 preceding siblings ...)
  2011-10-14 16:49 ` [Qemu-devel] [PATCH 09/24] block/vvfat: Fix potential memory leaks and other memory errors Kevin Wolf
@ 2011-10-14 16:49 ` Kevin Wolf
  2011-10-14 16:49 ` [Qemu-devel] [PATCH 11/24] vvfat: Fix potential buffer overflow Kevin Wolf
                   ` (14 subsequent siblings)
  24 siblings, 0 replies; 27+ messages in thread
From: Kevin Wolf @ 2011-10-14 16:49 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Stefan Weil <weil@mail.berlios.de>

The unused code was detected using cppcheck.

Cc: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Stefan Weil <weil@mail.berlios.de>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/vvfat.c |   56 --------------------------------------------------------
 1 files changed, 0 insertions(+), 56 deletions(-)

diff --git a/block/vvfat.c b/block/vvfat.c
index f45939d..ba207e2 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -824,20 +824,6 @@ static inline off_t cluster2sector(BDRVVVFATState* s, uint32_t cluster_num)
     return s->faked_sectors + s->sectors_per_cluster * cluster_num;
 }
 
-static inline uint32_t sector_offset_in_cluster(BDRVVVFATState* s,off_t sector_num)
-{
-    return (sector_num-s->first_sectors_number-2*s->sectors_per_fat)%s->sectors_per_cluster;
-}
-
-#ifdef DBG
-static direntry_t* get_direntry_for_mapping(BDRVVVFATState* s,mapping_t* mapping)
-{
-    if(mapping->mode==MODE_UNDEFINED)
-	return 0;
-    return (direntry_t*)(s->directory.pointer+sizeof(direntry_t)*mapping->dir_index);
-}
-#endif
-
 static int init_directories(BDRVVVFATState* s,
 	const char* dirname)
 {
@@ -1137,25 +1123,6 @@ static inline mapping_t* find_mapping_for_cluster(BDRVVVFATState* s,int cluster_
     return mapping;
 }
 
-/*
- * This function simply compares path == mapping->path. Since the mappings
- * are sorted by cluster, this is expensive: O(n).
- */
-static inline mapping_t* find_mapping_for_path(BDRVVVFATState* s,
-	const char* path)
-{
-    int i;
-
-    for (i = 0; i < s->mapping.next; i++) {
-	mapping_t* mapping = array_get(&(s->mapping), i);
-	if (mapping->first_mapping_index < 0 &&
-		!strcmp(path, mapping->path))
-	    return mapping;
-    }
-
-    return NULL;
-}
-
 static int open_file(BDRVVVFATState* s,mapping_t* mapping)
 {
     if(!mapping)
@@ -1222,23 +1189,6 @@ read_cluster_directory:
 }
 
 #ifdef DEBUG
-static void hexdump(const void* address, uint32_t len)
-{
-    const unsigned char* p = address;
-    int i, j;
-
-    for (i = 0; i < len; i += 16) {
-	for (j = 0; j < 16 && i + j < len; j++)
-	    fprintf(stderr, "%02x ", p[i + j]);
-	for (; j < 16; j++)
-	    fprintf(stderr, "   ");
-	fprintf(stderr, " ");
-	for (j = 0; j < 16 && i + j < len; j++)
-	    fprintf(stderr, "%c", (p[i + j] < ' ' || p[i + j] > 0x7f) ? '.' : p[i + j]);
-	fprintf(stderr, "\n");
-    }
-}
-
 static void print_direntry(const direntry_t* direntry)
 {
     int j = 0;
@@ -2887,11 +2837,5 @@ static void checkpoint(void) {
     direntry = array_get(&(vvv->directory), mapping->dir_index);
     assert(!memcmp(direntry->name, "USB     H  ", 11) || direntry->name[0]==0);
 #endif
-    return;
-    /* avoid compiler warnings: */
-    hexdump(NULL, 100);
-    remove_mapping(vvv, 0);
-    print_mapping(NULL);
-    print_direntry(NULL);
 }
 #endif
-- 
1.7.6.4

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [Qemu-devel] [PATCH 11/24] vvfat: Fix potential buffer overflow
  2011-10-14 16:48 [Qemu-devel] [PULL 00/24] Block patches Kevin Wolf
                   ` (9 preceding siblings ...)
  2011-10-14 16:49 ` [Qemu-devel] [PATCH 10/24] block/vvfat: Remove unused code Kevin Wolf
@ 2011-10-14 16:49 ` Kevin Wolf
  2011-10-14 16:49 ` [Qemu-devel] [PATCH 12/24] block: directly invoke .bdrv_aio_*() in bdrv_co_io_em() Kevin Wolf
                   ` (13 subsequent siblings)
  24 siblings, 0 replies; 27+ messages in thread
From: Kevin Wolf @ 2011-10-14 16:49 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

path2[PATH_MAX] can be used for the null termination, so make the array big
enough to allow this.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/vvfat.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/block/vvfat.c b/block/vvfat.c
index ba207e2..7e9e35a 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -1690,7 +1690,7 @@ static int check_directory_consistency(BDRVVVFATState *s,
 
     long_file_name lfn;
     int path_len = strlen(path);
-    char path2[PATH_MAX];
+    char path2[PATH_MAX + 1];
 
     assert(path_len < PATH_MAX); /* len was tested before! */
     pstrcpy(path2, sizeof(path2), path);
-- 
1.7.6.4

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [Qemu-devel] [PATCH 12/24] block: directly invoke .bdrv_aio_*() in bdrv_co_io_em()
  2011-10-14 16:48 [Qemu-devel] [PULL 00/24] Block patches Kevin Wolf
                   ` (10 preceding siblings ...)
  2011-10-14 16:49 ` [Qemu-devel] [PATCH 11/24] vvfat: Fix potential buffer overflow Kevin Wolf
@ 2011-10-14 16:49 ` Kevin Wolf
  2011-10-14 16:49 ` [Qemu-devel] [PATCH 13/24] block: directly invoke .bdrv_* from emulation functions Kevin Wolf
                   ` (12 subsequent siblings)
  24 siblings, 0 replies; 27+ messages in thread
From: Kevin Wolf @ 2011-10-14 16:49 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>

We will unify block layer request processing across sync, aio, and
coroutines and this means a .bdrv_co_*() emulation function should not
call back into the public interface.  There's no need here, just call
.bdrv_aio_*() directly.

The gory details: bdrv_co_io_em() cannot call back into the public
bdrv_aio_*() interface since that will be handled using coroutines,
which causes us to call into bdrv_co_io_em() again in an infinite loop
:).

Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/block.c b/block.c
index 25b03dd..09f8aad 100644
--- a/block.c
+++ b/block.c
@@ -3011,11 +3011,11 @@ static int coroutine_fn bdrv_co_io_em(BlockDriverState *bs, int64_t sector_num,
     BlockDriverAIOCB *acb;
 
     if (is_write) {
-        acb = bdrv_aio_writev(bs, sector_num, iov, nb_sectors,
-                              bdrv_co_io_em_complete, &co);
+        acb = bs->drv->bdrv_aio_writev(bs, sector_num, iov, nb_sectors,
+                                       bdrv_co_io_em_complete, &co);
     } else {
-        acb = bdrv_aio_readv(bs, sector_num, iov, nb_sectors,
-                             bdrv_co_io_em_complete, &co);
+        acb = bs->drv->bdrv_aio_readv(bs, sector_num, iov, nb_sectors,
+                                      bdrv_co_io_em_complete, &co);
     }
 
     trace_bdrv_co_io_em(bs, sector_num, nb_sectors, is_write, acb);
-- 
1.7.6.4

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [Qemu-devel] [PATCH 13/24] block: directly invoke .bdrv_* from emulation functions
  2011-10-14 16:48 [Qemu-devel] [PULL 00/24] Block patches Kevin Wolf
                   ` (11 preceding siblings ...)
  2011-10-14 16:49 ` [Qemu-devel] [PATCH 12/24] block: directly invoke .bdrv_aio_*() in bdrv_co_io_em() Kevin Wolf
@ 2011-10-14 16:49 ` Kevin Wolf
  2011-10-14 16:49 ` [Qemu-devel] [PATCH 14/24] block: split out bdrv_co_do_readv() and bdrv_co_do_writev() Kevin Wolf
                   ` (11 subsequent siblings)
  24 siblings, 0 replies; 27+ messages in thread
From: Kevin Wolf @ 2011-10-14 16:49 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>

The emulation functions which supply default BlockDriver .bdrv_*()
functions given another implemented .bdrv_*() function should not use
public bdrv_*() interfaces.  This patch ensures they invoke .bdrv_*()
directly to avoid adding an extra layer of coroutine request processing
and possibly entering an infinite loop.

Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block.c |   14 ++++++++------
 1 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/block.c b/block.c
index 09f8aad..7c01f72 100644
--- a/block.c
+++ b/block.c
@@ -2739,9 +2739,9 @@ static BlockDriverAIOCB *bdrv_aio_rw_vector(BlockDriverState *bs,
 
     if (is_write) {
         qemu_iovec_to_buffer(acb->qiov, acb->bounce);
-        acb->ret = bdrv_write(bs, sector_num, acb->bounce, nb_sectors);
+        acb->ret = bs->drv->bdrv_write(bs, sector_num, acb->bounce, nb_sectors);
     } else {
-        acb->ret = bdrv_read(bs, sector_num, acb->bounce, nb_sectors);
+        acb->ret = bs->drv->bdrv_read(bs, sector_num, acb->bounce, nb_sectors);
     }
 
     qemu_bh_schedule(acb->bh);
@@ -2906,8 +2906,9 @@ static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num,
     iov.iov_base = (void *)buf;
     iov.iov_len = nb_sectors * BDRV_SECTOR_SIZE;
     qemu_iovec_init_external(&qiov, &iov, 1);
-    acb = bdrv_aio_readv(bs, sector_num, &qiov, nb_sectors,
-        bdrv_rw_em_cb, &async_ret);
+
+    acb = bs->drv->bdrv_aio_readv(bs, sector_num, &qiov, nb_sectors,
+                                  bdrv_rw_em_cb, &async_ret);
     if (acb == NULL) {
         async_ret = -1;
         goto fail;
@@ -2934,8 +2935,9 @@ static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num,
     iov.iov_base = (void *)buf;
     iov.iov_len = nb_sectors * BDRV_SECTOR_SIZE;
     qemu_iovec_init_external(&qiov, &iov, 1);
-    acb = bdrv_aio_writev(bs, sector_num, &qiov, nb_sectors,
-        bdrv_rw_em_cb, &async_ret);
+
+    acb = bs->drv->bdrv_aio_writev(bs, sector_num, &qiov, nb_sectors,
+                                   bdrv_rw_em_cb, &async_ret);
     if (acb == NULL) {
         async_ret = -1;
         goto fail;
-- 
1.7.6.4

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [Qemu-devel] [PATCH 14/24] block: split out bdrv_co_do_readv() and bdrv_co_do_writev()
  2011-10-14 16:48 [Qemu-devel] [PULL 00/24] Block patches Kevin Wolf
                   ` (12 preceding siblings ...)
  2011-10-14 16:49 ` [Qemu-devel] [PATCH 13/24] block: directly invoke .bdrv_* from emulation functions Kevin Wolf
@ 2011-10-14 16:49 ` Kevin Wolf
  2011-10-14 16:49 ` [Qemu-devel] [PATCH 15/24] block: switch bdrv_read()/bdrv_write() to coroutines Kevin Wolf
                   ` (10 subsequent siblings)
  24 siblings, 0 replies; 27+ messages in thread
From: Kevin Wolf @ 2011-10-14 16:49 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>

The public interface for I/O in coroutine context is bdrv_co_readv() and
bdrv_co_writev().  Split out the request processing code into
bdrv_co_do_readv() and bdrv_co_writev() so that it can be called
internally when we refactor all request processing to use coroutines.

Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block.c |   34 +++++++++++++++++++++++++++-------
 1 files changed, 27 insertions(+), 7 deletions(-)

diff --git a/block.c b/block.c
index 7c01f72..f4731ec 100644
--- a/block.c
+++ b/block.c
@@ -72,6 +72,8 @@ static int coroutine_fn bdrv_co_writev_em(BlockDriverState *bs,
                                          int64_t sector_num, int nb_sectors,
                                          QEMUIOVector *iov);
 static int coroutine_fn bdrv_co_flush_em(BlockDriverState *bs);
+static int coroutine_fn bdrv_co_do_readv(BlockDriverState *bs,
+    int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
 
 static QTAILQ_HEAD(, BlockDriverState) bdrv_states =
     QTAILQ_HEAD_INITIALIZER(bdrv_states);
@@ -1253,13 +1255,14 @@ int bdrv_pwrite_sync(BlockDriverState *bs, int64_t offset,
     return 0;
 }
 
-int coroutine_fn bdrv_co_readv(BlockDriverState *bs, int64_t sector_num,
-    int nb_sectors, QEMUIOVector *qiov)
+/*
+ * Handle a read request in coroutine context
+ */
+static int coroutine_fn bdrv_co_do_readv(BlockDriverState *bs,
+    int64_t sector_num, int nb_sectors, QEMUIOVector *qiov)
 {
     BlockDriver *drv = bs->drv;
 
-    trace_bdrv_co_readv(bs, sector_num, nb_sectors);
-
     if (!drv) {
         return -ENOMEDIUM;
     }
@@ -1270,12 +1273,21 @@ int coroutine_fn bdrv_co_readv(BlockDriverState *bs, int64_t sector_num,
     return drv->bdrv_co_readv(bs, sector_num, nb_sectors, qiov);
 }
 
-int coroutine_fn bdrv_co_writev(BlockDriverState *bs, int64_t sector_num,
+int coroutine_fn bdrv_co_readv(BlockDriverState *bs, int64_t sector_num,
     int nb_sectors, QEMUIOVector *qiov)
 {
-    BlockDriver *drv = bs->drv;
+    trace_bdrv_co_readv(bs, sector_num, nb_sectors);
 
-    trace_bdrv_co_writev(bs, sector_num, nb_sectors);
+    return bdrv_co_do_readv(bs, sector_num, nb_sectors, qiov);
+}
+
+/*
+ * Handle a write request in coroutine context
+ */
+static int coroutine_fn bdrv_co_do_writev(BlockDriverState *bs,
+    int64_t sector_num, int nb_sectors, QEMUIOVector *qiov)
+{
+    BlockDriver *drv = bs->drv;
 
     if (!bs->drv) {
         return -ENOMEDIUM;
@@ -1298,6 +1310,14 @@ int coroutine_fn bdrv_co_writev(BlockDriverState *bs, int64_t sector_num,
     return drv->bdrv_co_writev(bs, sector_num, nb_sectors, qiov);
 }
 
+int coroutine_fn bdrv_co_writev(BlockDriverState *bs, int64_t sector_num,
+    int nb_sectors, QEMUIOVector *qiov)
+{
+    trace_bdrv_co_writev(bs, sector_num, nb_sectors);
+
+    return bdrv_co_do_writev(bs, sector_num, nb_sectors, qiov);
+}
+
 /**
  * Truncate file to 'offset' bytes (needed only for file protocols)
  */
-- 
1.7.6.4

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [Qemu-devel] [PATCH 15/24] block: switch bdrv_read()/bdrv_write() to coroutines
  2011-10-14 16:48 [Qemu-devel] [PULL 00/24] Block patches Kevin Wolf
                   ` (13 preceding siblings ...)
  2011-10-14 16:49 ` [Qemu-devel] [PATCH 14/24] block: split out bdrv_co_do_readv() and bdrv_co_do_writev() Kevin Wolf
@ 2011-10-14 16:49 ` Kevin Wolf
  2011-10-24 15:12   ` Pierre Riteau
  2011-10-14 16:49 ` [Qemu-devel] [PATCH 16/24] block: switch bdrv_aio_readv() " Kevin Wolf
                   ` (9 subsequent siblings)
  24 siblings, 1 reply; 27+ messages in thread
From: Kevin Wolf @ 2011-10-14 16:49 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>

The bdrv_read()/bdrv_write() functions call .bdrv_read()/.bdrv_write().
They should go through bdrv_co_do_readv() and bdrv_co_do_writev()
instead in order to unify request processing code across sync, aio, and
coroutine interfaces.  This is also an important step towards removing
BlockDriverState .bdrv_read()/.bdrv_write() in the future.

Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block.c |  112 +++++++++++++++++++++++++++++++++++----------------------------
 1 files changed, 62 insertions(+), 50 deletions(-)

diff --git a/block.c b/block.c
index f4731ec..ae8fc80 100644
--- a/block.c
+++ b/block.c
@@ -44,6 +44,8 @@
 #include <windows.h>
 #endif
 
+#define NOT_DONE 0x7fffffff /* used while emulated sync operation in progress */
+
 static void bdrv_dev_change_media_cb(BlockDriverState *bs, bool load);
 static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs,
         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
@@ -74,6 +76,8 @@ static int coroutine_fn bdrv_co_writev_em(BlockDriverState *bs,
 static int coroutine_fn bdrv_co_flush_em(BlockDriverState *bs);
 static int coroutine_fn bdrv_co_do_readv(BlockDriverState *bs,
     int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
+static int coroutine_fn bdrv_co_do_writev(BlockDriverState *bs,
+    int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
 
 static QTAILQ_HEAD(, BlockDriverState) bdrv_states =
     QTAILQ_HEAD_INITIALIZER(bdrv_states);
@@ -1042,30 +1046,69 @@ static inline bool bdrv_has_async_flush(BlockDriver *drv)
     return drv->bdrv_aio_flush != bdrv_aio_flush_em;
 }
 
-/* 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)
+typedef struct RwCo {
+    BlockDriverState *bs;
+    int64_t sector_num;
+    int nb_sectors;
+    QEMUIOVector *qiov;
+    bool is_write;
+    int ret;
+} RwCo;
+
+static void coroutine_fn bdrv_rw_co_entry(void *opaque)
 {
-    BlockDriver *drv = bs->drv;
+    RwCo *rwco = opaque;
 
-    if (!drv)
-        return -ENOMEDIUM;
+    if (!rwco->is_write) {
+        rwco->ret = bdrv_co_do_readv(rwco->bs, rwco->sector_num,
+                                     rwco->nb_sectors, rwco->qiov);
+    } else {
+        rwco->ret = bdrv_co_do_writev(rwco->bs, rwco->sector_num,
+                                      rwco->nb_sectors, rwco->qiov);
+    }
+}
 
-    if (bdrv_has_async_rw(drv) && qemu_in_coroutine()) {
-        QEMUIOVector qiov;
-        struct iovec iov = {
-            .iov_base = (void *)buf,
-            .iov_len = nb_sectors * BDRV_SECTOR_SIZE,
-        };
+/*
+ * 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,
+    };
+    Coroutine *co;
+    RwCo rwco = {
+        .bs = bs,
+        .sector_num = sector_num,
+        .nb_sectors = nb_sectors,
+        .qiov = &qiov,
+        .is_write = is_write,
+        .ret = NOT_DONE,
+    };
 
-        qemu_iovec_init_external(&qiov, &iov, 1);
-        return bdrv_co_readv(bs, sector_num, nb_sectors, &qiov);
-    }
+    qemu_iovec_init_external(&qiov, &iov, 1);
 
-    if (bdrv_check_request(bs, sector_num, nb_sectors))
-        return -EIO;
+    if (qemu_in_coroutine()) {
+        /* Fast-path if already in coroutine context */
+        bdrv_rw_co_entry(&rwco);
+    } else {
+        co = qemu_coroutine_create(bdrv_rw_co_entry);
+        qemu_coroutine_enter(co, &rwco);
+        while (rwco.ret == NOT_DONE) {
+            qemu_aio_wait();
+        }
+    }
+    return rwco.ret;
+}
 
-    return drv->bdrv_read(bs, sector_num, buf, nb_sectors);
+/* 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)
+{
+    return bdrv_rw_co(bs, sector_num, buf, nb_sectors, false);
 }
 
 static void set_dirty_bitmap(BlockDriverState *bs, int64_t sector_num,
@@ -1105,36 +1148,7 @@ static void set_dirty_bitmap(BlockDriverState *bs, int64_t sector_num,
 int bdrv_write(BlockDriverState *bs, int64_t sector_num,
                const uint8_t *buf, int nb_sectors)
 {
-    BlockDriver *drv = bs->drv;
-
-    if (!bs->drv)
-        return -ENOMEDIUM;
-
-    if (bdrv_has_async_rw(drv) && qemu_in_coroutine()) {
-        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_co_writev(bs, sector_num, nb_sectors, &qiov);
-    }
-
-    if (bs->read_only)
-        return -EACCES;
-    if (bdrv_check_request(bs, sector_num, nb_sectors))
-        return -EIO;
-
-    if (bs->dirty_bitmap) {
-        set_dirty_bitmap(bs, sector_num, nb_sectors, 1);
-    }
-
-    if (bs->wr_highest_sector < sector_num + nb_sectors - 1) {
-        bs->wr_highest_sector = sector_num + nb_sectors - 1;
-    }
-
-    return drv->bdrv_write(bs, sector_num, buf, nb_sectors);
+    return bdrv_rw_co(bs, sector_num, (uint8_t *)buf, nb_sectors, true);
 }
 
 int bdrv_pread(BlockDriverState *bs, int64_t offset,
@@ -2912,8 +2926,6 @@ static void bdrv_rw_em_cb(void *opaque, int ret)
     *(int *)opaque = ret;
 }
 
-#define NOT_DONE 0x7fffffff
-
 static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num,
                         uint8_t *buf, int nb_sectors)
 {
-- 
1.7.6.4

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [Qemu-devel] [PATCH 16/24] block: switch bdrv_aio_readv() to coroutines
  2011-10-14 16:48 [Qemu-devel] [PULL 00/24] Block patches Kevin Wolf
                   ` (14 preceding siblings ...)
  2011-10-14 16:49 ` [Qemu-devel] [PATCH 15/24] block: switch bdrv_read()/bdrv_write() to coroutines Kevin Wolf
@ 2011-10-14 16:49 ` Kevin Wolf
  2011-10-14 16:49 ` [Qemu-devel] [PATCH 17/24] block: mark blocks dirty on coroutine write completion Kevin Wolf
                   ` (8 subsequent siblings)
  24 siblings, 0 replies; 27+ messages in thread
From: Kevin Wolf @ 2011-10-14 16:49 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>

More sync, aio, and coroutine unification.  Make bdrv_aio_readv() go
through coroutine request processing.

Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block.c |   48 +++++++++++++++++++++++++++++++++++-------------
 1 files changed, 35 insertions(+), 13 deletions(-)

diff --git a/block.c b/block.c
index ae8fc80..e94fa61 100644
--- a/block.c
+++ b/block.c
@@ -78,6 +78,15 @@ static int coroutine_fn bdrv_co_do_readv(BlockDriverState *bs,
     int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
 static int coroutine_fn bdrv_co_do_writev(BlockDriverState *bs,
     int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
+static BlockDriverAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs,
+                                               int64_t sector_num,
+                                               QEMUIOVector *qiov,
+                                               int nb_sectors,
+                                               BlockDriverCompletionFunc *cb,
+                                               void *opaque,
+                                               bool is_write,
+                                               CoroutineEntry *entry);
+static void coroutine_fn bdrv_co_do_rw(void *opaque);
 
 static QTAILQ_HEAD(, BlockDriverState) bdrv_states =
     QTAILQ_HEAD_INITIALIZER(bdrv_states);
@@ -2367,17 +2376,10 @@ BlockDriverAIOCB *bdrv_aio_readv(BlockDriverState *bs, int64_t sector_num,
                                  QEMUIOVector *qiov, int nb_sectors,
                                  BlockDriverCompletionFunc *cb, void *opaque)
 {
-    BlockDriver *drv = bs->drv;
-
     trace_bdrv_aio_readv(bs, sector_num, nb_sectors, opaque);
 
-    if (!drv)
-        return NULL;
-    if (bdrv_check_request(bs, sector_num, nb_sectors))
-        return NULL;
-
-    return drv->bdrv_aio_readv(bs, sector_num, qiov, nb_sectors,
-                               cb, opaque);
+    return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors,
+                                 cb, opaque, false, bdrv_co_do_rw);
 }
 
 typedef struct BlockCompleteData {
@@ -2824,6 +2826,7 @@ static void bdrv_co_rw_bh(void *opaque)
     qemu_aio_release(acb);
 }
 
+/* Invoke .bdrv_co_readv/.bdrv_co_writev */
 static void coroutine_fn bdrv_co_rw(void *opaque)
 {
     BlockDriverAIOCBCoroutine *acb = opaque;
@@ -2841,13 +2844,32 @@ static void coroutine_fn bdrv_co_rw(void *opaque)
     qemu_bh_schedule(acb->bh);
 }
 
+/* Invoke bdrv_co_do_readv/bdrv_co_do_writev */
+static void coroutine_fn bdrv_co_do_rw(void *opaque)
+{
+    BlockDriverAIOCBCoroutine *acb = opaque;
+    BlockDriverState *bs = acb->common.bs;
+
+    if (!acb->is_write) {
+        acb->req.error = bdrv_co_do_readv(bs, acb->req.sector,
+            acb->req.nb_sectors, acb->req.qiov);
+    } else {
+        acb->req.error = bdrv_co_do_writev(bs, acb->req.sector,
+            acb->req.nb_sectors, acb->req.qiov);
+    }
+
+    acb->bh = qemu_bh_new(bdrv_co_rw_bh, acb);
+    qemu_bh_schedule(acb->bh);
+}
+
 static BlockDriverAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs,
                                                int64_t sector_num,
                                                QEMUIOVector *qiov,
                                                int nb_sectors,
                                                BlockDriverCompletionFunc *cb,
                                                void *opaque,
-                                               bool is_write)
+                                               bool is_write,
+                                               CoroutineEntry *entry)
 {
     Coroutine *co;
     BlockDriverAIOCBCoroutine *acb;
@@ -2858,7 +2880,7 @@ static BlockDriverAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs,
     acb->req.qiov = qiov;
     acb->is_write = is_write;
 
-    co = qemu_coroutine_create(bdrv_co_rw);
+    co = qemu_coroutine_create(entry);
     qemu_coroutine_enter(co, acb);
 
     return &acb->common;
@@ -2869,7 +2891,7 @@ static BlockDriverAIOCB *bdrv_co_aio_readv_em(BlockDriverState *bs,
         BlockDriverCompletionFunc *cb, void *opaque)
 {
     return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque,
-                                 false);
+                                 false, bdrv_co_rw);
 }
 
 static BlockDriverAIOCB *bdrv_co_aio_writev_em(BlockDriverState *bs,
@@ -2877,7 +2899,7 @@ static BlockDriverAIOCB *bdrv_co_aio_writev_em(BlockDriverState *bs,
         BlockDriverCompletionFunc *cb, void *opaque)
 {
     return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque,
-                                 true);
+                                 true, bdrv_co_rw);
 }
 
 static BlockDriverAIOCB *bdrv_aio_flush_em(BlockDriverState *bs,
-- 
1.7.6.4

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [Qemu-devel] [PATCH 17/24] block: mark blocks dirty on coroutine write completion
  2011-10-14 16:48 [Qemu-devel] [PULL 00/24] Block patches Kevin Wolf
                   ` (15 preceding siblings ...)
  2011-10-14 16:49 ` [Qemu-devel] [PATCH 16/24] block: switch bdrv_aio_readv() " Kevin Wolf
@ 2011-10-14 16:49 ` Kevin Wolf
  2011-10-14 16:49 ` [Qemu-devel] [PATCH 18/24] block: switch bdrv_aio_writev() to coroutines Kevin Wolf
                   ` (7 subsequent siblings)
  24 siblings, 0 replies; 27+ messages in thread
From: Kevin Wolf @ 2011-10-14 16:49 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>

The aio write operation marks blocks dirty when the write operation
completes.  The coroutine write operation marks blocks dirty before
issuing the write operation.

It seems safest to mark the block dirty when the operation completes so
that anything tracking dirty blocks will not act before the change has
been made to the image file.

Make the coroutine write operation dirty blocks on write completion.

Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block.c |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/block.c b/block.c
index e94fa61..02e15ca 100644
--- a/block.c
+++ b/block.c
@@ -1311,6 +1311,7 @@ static int coroutine_fn bdrv_co_do_writev(BlockDriverState *bs,
     int64_t sector_num, int nb_sectors, QEMUIOVector *qiov)
 {
     BlockDriver *drv = bs->drv;
+    int ret;
 
     if (!bs->drv) {
         return -ENOMEDIUM;
@@ -1322,6 +1323,8 @@ static int coroutine_fn bdrv_co_do_writev(BlockDriverState *bs,
         return -EIO;
     }
 
+    ret = drv->bdrv_co_writev(bs, sector_num, nb_sectors, qiov);
+
     if (bs->dirty_bitmap) {
         set_dirty_bitmap(bs, sector_num, nb_sectors, 1);
     }
@@ -1330,7 +1333,7 @@ static int coroutine_fn bdrv_co_do_writev(BlockDriverState *bs,
         bs->wr_highest_sector = sector_num + nb_sectors - 1;
     }
 
-    return drv->bdrv_co_writev(bs, sector_num, nb_sectors, qiov);
+    return ret;
 }
 
 int coroutine_fn bdrv_co_writev(BlockDriverState *bs, int64_t sector_num,
-- 
1.7.6.4

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [Qemu-devel] [PATCH 18/24] block: switch bdrv_aio_writev() to coroutines
  2011-10-14 16:48 [Qemu-devel] [PULL 00/24] Block patches Kevin Wolf
                   ` (16 preceding siblings ...)
  2011-10-14 16:49 ` [Qemu-devel] [PATCH 17/24] block: mark blocks dirty on coroutine write completion Kevin Wolf
@ 2011-10-14 16:49 ` Kevin Wolf
  2011-10-14 16:49 ` [Qemu-devel] [PATCH 19/24] linux-aio: Allow reads beyond the end of growable images Kevin Wolf
                   ` (6 subsequent siblings)
  24 siblings, 0 replies; 27+ messages in thread
From: Kevin Wolf @ 2011-10-14 16:49 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>

More sync, aio, and coroutine unification.  Make bdrv_aio_writev() go
through coroutine request processing.

Remove the dirty block callback mechanism which was needed only for aio
processing and can be done more naturally in coroutine context.

Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block.c |   66 +-------------------------------------------------------------
 1 files changed, 2 insertions(+), 64 deletions(-)

diff --git a/block.c b/block.c
index 02e15ca..8c7d05e 100644
--- a/block.c
+++ b/block.c
@@ -2385,76 +2385,14 @@ BlockDriverAIOCB *bdrv_aio_readv(BlockDriverState *bs, int64_t sector_num,
                                  cb, opaque, false, bdrv_co_do_rw);
 }
 
-typedef struct BlockCompleteData {
-    BlockDriverCompletionFunc *cb;
-    void *opaque;
-    BlockDriverState *bs;
-    int64_t sector_num;
-    int nb_sectors;
-} BlockCompleteData;
-
-static void block_complete_cb(void *opaque, int ret)
-{
-    BlockCompleteData *b = opaque;
-
-    if (b->bs->dirty_bitmap) {
-        set_dirty_bitmap(b->bs, b->sector_num, b->nb_sectors, 1);
-    }
-    b->cb(b->opaque, ret);
-    g_free(b);
-}
-
-static BlockCompleteData *blk_dirty_cb_alloc(BlockDriverState *bs,
-                                             int64_t sector_num,
-                                             int nb_sectors,
-                                             BlockDriverCompletionFunc *cb,
-                                             void *opaque)
-{
-    BlockCompleteData *blkdata = g_malloc0(sizeof(BlockCompleteData));
-
-    blkdata->bs = bs;
-    blkdata->cb = cb;
-    blkdata->opaque = opaque;
-    blkdata->sector_num = sector_num;
-    blkdata->nb_sectors = nb_sectors;
-
-    return blkdata;
-}
-
 BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num,
                                   QEMUIOVector *qiov, int nb_sectors,
                                   BlockDriverCompletionFunc *cb, void *opaque)
 {
-    BlockDriver *drv = bs->drv;
-    BlockDriverAIOCB *ret;
-    BlockCompleteData *blk_cb_data;
-
     trace_bdrv_aio_writev(bs, sector_num, nb_sectors, opaque);
 
-    if (!drv)
-        return NULL;
-    if (bs->read_only)
-        return NULL;
-    if (bdrv_check_request(bs, sector_num, nb_sectors))
-        return NULL;
-
-    if (bs->dirty_bitmap) {
-        blk_cb_data = blk_dirty_cb_alloc(bs, sector_num, nb_sectors, cb,
-                                         opaque);
-        cb = &block_complete_cb;
-        opaque = blk_cb_data;
-    }
-
-    ret = drv->bdrv_aio_writev(bs, sector_num, qiov, nb_sectors,
-                               cb, opaque);
-
-    if (ret) {
-        if (bs->wr_highest_sector < sector_num + nb_sectors - 1) {
-            bs->wr_highest_sector = sector_num + nb_sectors - 1;
-        }
-    }
-
-    return ret;
+    return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors,
+                                 cb, opaque, true, bdrv_co_do_rw);
 }
 
 
-- 
1.7.6.4

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [Qemu-devel] [PATCH 19/24] linux-aio: Allow reads beyond the end of growable images
  2011-10-14 16:48 [Qemu-devel] [PULL 00/24] Block patches Kevin Wolf
                   ` (17 preceding siblings ...)
  2011-10-14 16:49 ` [Qemu-devel] [PATCH 18/24] block: switch bdrv_aio_writev() to coroutines Kevin Wolf
@ 2011-10-14 16:49 ` Kevin Wolf
  2011-10-14 16:49 ` [Qemu-devel] [PATCH 20/24] block: drop emulation functions that use coroutines Kevin Wolf
                   ` (5 subsequent siblings)
  24 siblings, 0 replies; 27+ messages in thread
From: Kevin Wolf @ 2011-10-14 16:49 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

This is the linux-aio version of commits 22afa7b5 (raw-posix, synchronous) and
ba1d1afd (posix-aio-compat). Reads now produce zeros after the end of file
instead of failing or resulting in short reads, making linux-aio compatible
with the behaviour of synchronous raw-posix requests and posix-aio-compat.

The problem can be reproduced like this:

dd if=/dev/zero of=/tmp/test.raw bs=1 count=1234
./qemu-io -k -n -g -c 'read -p 1024 512' /tmp/test.raw

Previously, the result of this was 'read failed: Invalid argument', now the
read completes successfully.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
---
 linux-aio.c |   17 ++++++++++++++---
 1 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/linux-aio.c b/linux-aio.c
index 50da75d..1c635ef 100644
--- a/linux-aio.c
+++ b/linux-aio.c
@@ -31,6 +31,8 @@ struct qemu_laiocb {
     struct iocb iocb;
     ssize_t ret;
     size_t nbytes;
+    QEMUIOVector *qiov;
+    bool is_read;
     QLIST_ENTRY(qemu_laiocb) node;
 };
 
@@ -57,10 +59,17 @@ static void qemu_laio_process_completion(struct qemu_laio_state *s,
 
     ret = laiocb->ret;
     if (ret != -ECANCELED) {
-        if (ret == laiocb->nbytes)
+        if (ret == laiocb->nbytes) {
             ret = 0;
-        else if (ret >= 0)
-            ret = -EINVAL;
+        } else if (ret >= 0) {
+            /* Short reads mean EOF, pad with zeros. */
+            if (laiocb->is_read) {
+                qemu_iovec_memset_skip(laiocb->qiov, 0,
+                    laiocb->qiov->size - ret, ret);
+            } else {
+                ret = -EINVAL;
+            }
+        }
 
         laiocb->common.cb(laiocb->common.opaque, ret);
     }
@@ -162,6 +171,8 @@ BlockDriverAIOCB *laio_submit(BlockDriverState *bs, void *aio_ctx, int fd,
     laiocb->nbytes = nb_sectors * 512;
     laiocb->ctx = s;
     laiocb->ret = -EINPROGRESS;
+    laiocb->is_read = (type == QEMU_AIO_READ);
+    laiocb->qiov = qiov;
 
     iocbs = &laiocb->iocb;
 
-- 
1.7.6.4

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [Qemu-devel] [PATCH 20/24] block: drop emulation functions that use coroutines
  2011-10-14 16:48 [Qemu-devel] [PULL 00/24] Block patches Kevin Wolf
                   ` (18 preceding siblings ...)
  2011-10-14 16:49 ` [Qemu-devel] [PATCH 19/24] linux-aio: Allow reads beyond the end of growable images Kevin Wolf
@ 2011-10-14 16:49 ` Kevin Wolf
  2011-10-14 16:49 ` [Qemu-devel] [PATCH 21/24] raw-posix: remove bdrv_read()/bdrv_write() Kevin Wolf
                   ` (4 subsequent siblings)
  24 siblings, 0 replies; 27+ messages in thread
From: Kevin Wolf @ 2011-10-14 16:49 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>

Block drivers that implement coroutine functions used to get sync and
aio wrappers.  This is no longer necessary since all request processing
now happens in a coroutine.  If a block driver implements the coroutine
interface then none of the other interfaces will be invoked.

Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block.c |   61 +++++++------------------------------------------------------
 1 files changed, 7 insertions(+), 54 deletions(-)

diff --git a/block.c b/block.c
index 8c7d05e..3d27bab 100644
--- a/block.c
+++ b/block.c
@@ -61,12 +61,6 @@ static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num,
                         uint8_t *buf, int nb_sectors);
 static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num,
                          const uint8_t *buf, int nb_sectors);
-static BlockDriverAIOCB *bdrv_co_aio_readv_em(BlockDriverState *bs,
-        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
-        BlockDriverCompletionFunc *cb, void *opaque);
-static BlockDriverAIOCB *bdrv_co_aio_writev_em(BlockDriverState *bs,
-        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
-        BlockDriverCompletionFunc *cb, void *opaque);
 static int coroutine_fn bdrv_co_readv_em(BlockDriverState *bs,
                                          int64_t sector_num, int nb_sectors,
                                          QEMUIOVector *iov);
@@ -84,8 +78,7 @@ static BlockDriverAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs,
                                                int nb_sectors,
                                                BlockDriverCompletionFunc *cb,
                                                void *opaque,
-                                               bool is_write,
-                                               CoroutineEntry *entry);
+                                               bool is_write);
 static void coroutine_fn bdrv_co_do_rw(void *opaque);
 
 static QTAILQ_HEAD(, BlockDriverState) bdrv_states =
@@ -199,13 +192,8 @@ void path_combine(char *dest, int dest_size,
 
 void bdrv_register(BlockDriver *bdrv)
 {
-    if (bdrv->bdrv_co_readv) {
-        /* Emulate AIO by coroutines, and sync by AIO */
-        bdrv->bdrv_aio_readv = bdrv_co_aio_readv_em;
-        bdrv->bdrv_aio_writev = bdrv_co_aio_writev_em;
-        bdrv->bdrv_read = bdrv_read_em;
-        bdrv->bdrv_write = bdrv_write_em;
-     } else {
+    /* Block drivers without coroutine functions need emulation */
+    if (!bdrv->bdrv_co_readv) {
         bdrv->bdrv_co_readv = bdrv_co_readv_em;
         bdrv->bdrv_co_writev = bdrv_co_writev_em;
 
@@ -2382,7 +2370,7 @@ BlockDriverAIOCB *bdrv_aio_readv(BlockDriverState *bs, int64_t sector_num,
     trace_bdrv_aio_readv(bs, sector_num, nb_sectors, opaque);
 
     return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors,
-                                 cb, opaque, false, bdrv_co_do_rw);
+                                 cb, opaque, false);
 }
 
 BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num,
@@ -2392,7 +2380,7 @@ BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num,
     trace_bdrv_aio_writev(bs, sector_num, nb_sectors, opaque);
 
     return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors,
-                                 cb, opaque, true, bdrv_co_do_rw);
+                                 cb, opaque, true);
 }
 
 
@@ -2767,24 +2755,6 @@ static void bdrv_co_rw_bh(void *opaque)
     qemu_aio_release(acb);
 }
 
-/* Invoke .bdrv_co_readv/.bdrv_co_writev */
-static void coroutine_fn bdrv_co_rw(void *opaque)
-{
-    BlockDriverAIOCBCoroutine *acb = opaque;
-    BlockDriverState *bs = acb->common.bs;
-
-    if (!acb->is_write) {
-        acb->req.error = bs->drv->bdrv_co_readv(bs, acb->req.sector,
-            acb->req.nb_sectors, acb->req.qiov);
-    } else {
-        acb->req.error = bs->drv->bdrv_co_writev(bs, acb->req.sector,
-            acb->req.nb_sectors, acb->req.qiov);
-    }
-
-    acb->bh = qemu_bh_new(bdrv_co_rw_bh, acb);
-    qemu_bh_schedule(acb->bh);
-}
-
 /* Invoke bdrv_co_do_readv/bdrv_co_do_writev */
 static void coroutine_fn bdrv_co_do_rw(void *opaque)
 {
@@ -2809,8 +2779,7 @@ static BlockDriverAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs,
                                                int nb_sectors,
                                                BlockDriverCompletionFunc *cb,
                                                void *opaque,
-                                               bool is_write,
-                                               CoroutineEntry *entry)
+                                               bool is_write)
 {
     Coroutine *co;
     BlockDriverAIOCBCoroutine *acb;
@@ -2821,28 +2790,12 @@ static BlockDriverAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs,
     acb->req.qiov = qiov;
     acb->is_write = is_write;
 
-    co = qemu_coroutine_create(entry);
+    co = qemu_coroutine_create(bdrv_co_do_rw);
     qemu_coroutine_enter(co, acb);
 
     return &acb->common;
 }
 
-static BlockDriverAIOCB *bdrv_co_aio_readv_em(BlockDriverState *bs,
-        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
-        BlockDriverCompletionFunc *cb, void *opaque)
-{
-    return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque,
-                                 false, bdrv_co_rw);
-}
-
-static BlockDriverAIOCB *bdrv_co_aio_writev_em(BlockDriverState *bs,
-        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
-        BlockDriverCompletionFunc *cb, void *opaque)
-{
-    return bdrv_co_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque,
-                                 true, bdrv_co_rw);
-}
-
 static BlockDriverAIOCB *bdrv_aio_flush_em(BlockDriverState *bs,
         BlockDriverCompletionFunc *cb, void *opaque)
 {
-- 
1.7.6.4

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [Qemu-devel] [PATCH 21/24] raw-posix: remove bdrv_read()/bdrv_write()
  2011-10-14 16:48 [Qemu-devel] [PULL 00/24] Block patches Kevin Wolf
                   ` (19 preceding siblings ...)
  2011-10-14 16:49 ` [Qemu-devel] [PATCH 20/24] block: drop emulation functions that use coroutines Kevin Wolf
@ 2011-10-14 16:49 ` Kevin Wolf
  2011-10-14 16:49 ` [Qemu-devel] [PATCH 22/24] block: use coroutine interface for raw format Kevin Wolf
                   ` (3 subsequent siblings)
  24 siblings, 0 replies; 27+ messages in thread
From: Kevin Wolf @ 2011-10-14 16:49 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>

Block drivers only need to provide one of sync, aio, or coroutine
interfaces.  Since raw-posix.c provides aio interfaces, simply drop the
synchronous interfaces since they can be emulated using aio and
coroutines.

Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/raw-posix.c |  277 -----------------------------------------------------
 1 files changed, 0 insertions(+), 277 deletions(-)

diff --git a/block/raw-posix.c b/block/raw-posix.c
index 0b5e225..c7f5544 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -297,273 +297,6 @@ static int raw_open(BlockDriverState *bs, const char *filename, int flags)
 */
 
 /*
- * offset and count are in bytes, but must be multiples of 512 for files
- * opened with O_DIRECT. buf must be aligned to 512 bytes then.
- *
- * This function may be called without alignment if the caller ensures
- * that O_DIRECT is not in effect.
- */
-static int raw_pread_aligned(BlockDriverState *bs, int64_t offset,
-                     uint8_t *buf, int count)
-{
-    BDRVRawState *s = bs->opaque;
-    int ret;
-
-    ret = fd_open(bs);
-    if (ret < 0)
-        return ret;
-
-    ret = pread(s->fd, buf, count, offset);
-    if (ret == count)
-        return ret;
-
-    /* Allow reads beyond the end (needed for pwrite) */
-    if ((ret == 0) && bs->growable) {
-        int64_t size = raw_getlength(bs);
-        if (offset >= size) {
-            memset(buf, 0, count);
-            return count;
-        }
-    }
-
-    DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
-                      "] read failed %d : %d = %s\n",
-                      s->fd, bs->filename, offset, buf, count,
-                      bs->total_sectors, ret, errno, strerror(errno));
-
-    /* Try harder for CDrom. */
-    if (s->type != FTYPE_FILE) {
-        ret = pread(s->fd, buf, count, offset);
-        if (ret == count)
-            return ret;
-        ret = pread(s->fd, buf, count, offset);
-        if (ret == count)
-            return ret;
-
-        DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
-                          "] retry read failed %d : %d = %s\n",
-                          s->fd, bs->filename, offset, buf, count,
-                          bs->total_sectors, ret, errno, strerror(errno));
-    }
-
-    return  (ret < 0) ? -errno : ret;
-}
-
-/*
- * offset and count are in bytes, but must be multiples of the sector size
- * for files opened with O_DIRECT. buf must be aligned to sector size bytes
- * then.
- *
- * This function may be called without alignment if the caller ensures
- * that O_DIRECT is not in effect.
- */
-static int raw_pwrite_aligned(BlockDriverState *bs, int64_t offset,
-                      const uint8_t *buf, int count)
-{
-    BDRVRawState *s = bs->opaque;
-    int ret;
-
-    ret = fd_open(bs);
-    if (ret < 0)
-        return -errno;
-
-    ret = pwrite(s->fd, buf, count, offset);
-    if (ret == count)
-        return ret;
-
-    DEBUG_BLOCK_PRINT("raw_pwrite(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
-                      "] write failed %d : %d = %s\n",
-                      s->fd, bs->filename, offset, buf, count,
-                      bs->total_sectors, ret, errno, strerror(errno));
-
-    return  (ret < 0) ? -errno : ret;
-}
-
-
-/*
- * offset and count are in bytes and possibly not aligned. For files opened
- * with O_DIRECT, necessary alignments are ensured before calling
- * raw_pread_aligned to do the actual read.
- */
-static int raw_pread(BlockDriverState *bs, int64_t offset,
-                     uint8_t *buf, int count)
-{
-    BDRVRawState *s = bs->opaque;
-    unsigned sector_mask = bs->buffer_alignment - 1;
-    int size, ret, shift, sum;
-
-    sum = 0;
-
-    if (s->aligned_buf != NULL)  {
-
-        if (offset & sector_mask) {
-            /* align offset on a sector size bytes boundary */
-
-            shift = offset & sector_mask;
-            size = (shift + count + sector_mask) & ~sector_mask;
-            if (size > s->aligned_buf_size)
-                size = s->aligned_buf_size;
-            ret = raw_pread_aligned(bs, offset - shift, s->aligned_buf, size);
-            if (ret < 0)
-                return ret;
-
-            size = bs->buffer_alignment - shift;
-            if (size > count)
-                size = count;
-            memcpy(buf, s->aligned_buf + shift, size);
-
-            buf += size;
-            offset += size;
-            count -= size;
-            sum += size;
-
-            if (count == 0)
-                return sum;
-        }
-        if (count & sector_mask || (uintptr_t) buf & sector_mask) {
-
-            /* read on aligned buffer */
-
-            while (count) {
-
-                size = (count + sector_mask) & ~sector_mask;
-                if (size > s->aligned_buf_size)
-                    size = s->aligned_buf_size;
-
-                ret = raw_pread_aligned(bs, offset, s->aligned_buf, size);
-                if (ret < 0) {
-                    return ret;
-                } else if (ret == 0) {
-                    fprintf(stderr, "raw_pread: read beyond end of file\n");
-                    abort();
-                }
-
-                size = ret;
-                if (size > count)
-                    size = count;
-
-                memcpy(buf, s->aligned_buf, size);
-
-                buf += size;
-                offset += size;
-                count -= size;
-                sum += size;
-            }
-
-            return sum;
-        }
-    }
-
-    return raw_pread_aligned(bs, offset, buf, count) + sum;
-}
-
-static int raw_read(BlockDriverState *bs, int64_t sector_num,
-                    uint8_t *buf, int nb_sectors)
-{
-    int ret;
-
-    ret = raw_pread(bs, sector_num * BDRV_SECTOR_SIZE, buf,
-                    nb_sectors * BDRV_SECTOR_SIZE);
-    if (ret == (nb_sectors * BDRV_SECTOR_SIZE))
-        ret = 0;
-    return ret;
-}
-
-/*
- * offset and count are in bytes and possibly not aligned. For files opened
- * with O_DIRECT, necessary alignments are ensured before calling
- * raw_pwrite_aligned to do the actual write.
- */
-static int raw_pwrite(BlockDriverState *bs, int64_t offset,
-                      const uint8_t *buf, int count)
-{
-    BDRVRawState *s = bs->opaque;
-    unsigned sector_mask = bs->buffer_alignment - 1;
-    int size, ret, shift, sum;
-
-    sum = 0;
-
-    if (s->aligned_buf != NULL) {
-
-        if (offset & sector_mask) {
-            /* align offset on a sector size bytes boundary */
-            shift = offset & sector_mask;
-            ret = raw_pread_aligned(bs, offset - shift, s->aligned_buf,
-                                    bs->buffer_alignment);
-            if (ret < 0)
-                return ret;
-
-            size = bs->buffer_alignment - shift;
-            if (size > count)
-                size = count;
-            memcpy(s->aligned_buf + shift, buf, size);
-
-            ret = raw_pwrite_aligned(bs, offset - shift, s->aligned_buf,
-                                     bs->buffer_alignment);
-            if (ret < 0)
-                return ret;
-
-            buf += size;
-            offset += size;
-            count -= size;
-            sum += size;
-
-            if (count == 0)
-                return sum;
-        }
-        if (count & sector_mask || (uintptr_t) buf & sector_mask) {
-
-            while ((size = (count & ~sector_mask)) != 0) {
-
-                if (size > s->aligned_buf_size)
-                    size = s->aligned_buf_size;
-
-                memcpy(s->aligned_buf, buf, size);
-
-                ret = raw_pwrite_aligned(bs, offset, s->aligned_buf, size);
-                if (ret < 0)
-                    return ret;
-
-                buf += ret;
-                offset += ret;
-                count -= ret;
-                sum += ret;
-            }
-            /* here, count < sector_size because (count & ~sector_mask) == 0 */
-            if (count) {
-                ret = raw_pread_aligned(bs, offset, s->aligned_buf,
-                                     bs->buffer_alignment);
-                if (ret < 0)
-                    return ret;
-                 memcpy(s->aligned_buf, buf, count);
-
-                 ret = raw_pwrite_aligned(bs, offset, s->aligned_buf,
-                                     bs->buffer_alignment);
-                 if (ret < 0)
-                     return ret;
-                 if (count < ret)
-                     ret = count;
-
-                 sum += ret;
-            }
-            return sum;
-        }
-    }
-    return raw_pwrite_aligned(bs, offset, buf, count) + sum;
-}
-
-static int raw_write(BlockDriverState *bs, int64_t sector_num,
-                     const uint8_t *buf, int nb_sectors)
-{
-    int ret;
-    ret = raw_pwrite(bs, sector_num * BDRV_SECTOR_SIZE, buf,
-                     nb_sectors * BDRV_SECTOR_SIZE);
-    if (ret == (nb_sectors * BDRV_SECTOR_SIZE))
-        ret = 0;
-    return ret;
-}
-
-/*
  * Check if all memory in this vector is sector aligned.
  */
 static int qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov)
@@ -910,8 +643,6 @@ static BlockDriver bdrv_file = {
     .instance_size = sizeof(BDRVRawState),
     .bdrv_probe = NULL, /* no probe for protocols */
     .bdrv_file_open = raw_open,
-    .bdrv_read = raw_read,
-    .bdrv_write = raw_write,
     .bdrv_close = raw_close,
     .bdrv_create = raw_create,
     .bdrv_flush = raw_flush,
@@ -1190,8 +921,6 @@ static BlockDriver bdrv_host_device = {
     .bdrv_aio_writev	= raw_aio_writev,
     .bdrv_aio_flush	= raw_aio_flush,
 
-    .bdrv_read          = raw_read,
-    .bdrv_write         = raw_write,
     .bdrv_truncate      = raw_truncate,
     .bdrv_getlength	= raw_getlength,
     .bdrv_get_allocated_file_size
@@ -1312,8 +1041,6 @@ static BlockDriver bdrv_host_floppy = {
     .bdrv_aio_writev    = raw_aio_writev,
     .bdrv_aio_flush	= raw_aio_flush,
 
-    .bdrv_read          = raw_read,
-    .bdrv_write         = raw_write,
     .bdrv_truncate      = raw_truncate,
     .bdrv_getlength	= raw_getlength,
     .bdrv_get_allocated_file_size
@@ -1414,8 +1141,6 @@ static BlockDriver bdrv_host_cdrom = {
     .bdrv_aio_writev    = raw_aio_writev,
     .bdrv_aio_flush	= raw_aio_flush,
 
-    .bdrv_read          = raw_read,
-    .bdrv_write         = raw_write,
     .bdrv_truncate      = raw_truncate,
     .bdrv_getlength     = raw_getlength,
     .bdrv_get_allocated_file_size
@@ -1536,8 +1261,6 @@ static BlockDriver bdrv_host_cdrom = {
     .bdrv_aio_writev    = raw_aio_writev,
     .bdrv_aio_flush	= raw_aio_flush,
 
-    .bdrv_read          = raw_read,
-    .bdrv_write         = raw_write,
     .bdrv_truncate      = raw_truncate,
     .bdrv_getlength     = raw_getlength,
     .bdrv_get_allocated_file_size
-- 
1.7.6.4

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [Qemu-devel] [PATCH 22/24] block: use coroutine interface for raw format
  2011-10-14 16:48 [Qemu-devel] [PULL 00/24] Block patches Kevin Wolf
                   ` (20 preceding siblings ...)
  2011-10-14 16:49 ` [Qemu-devel] [PATCH 21/24] raw-posix: remove bdrv_read()/bdrv_write() Kevin Wolf
@ 2011-10-14 16:49 ` Kevin Wolf
  2011-10-14 16:49 ` [Qemu-devel] [PATCH 23/24] block: drop .bdrv_read()/.bdrv_write() emulation Kevin Wolf
                   ` (2 subsequent siblings)
  24 siblings, 0 replies; 27+ messages in thread
From: Kevin Wolf @ 2011-10-14 16:49 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>

The raw format delegates all operations to bs->file (the protocol).
Previously this block driver exposed both sync and aio interfaces.
Since the block layer now works in terms of coroutines, expose the
coroutine interfaces and drop the others.  This avoids unnecessary
emulation of sync and aio interfaces.

Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/raw.c |   32 ++++++++------------------------
 1 files changed, 8 insertions(+), 24 deletions(-)

diff --git a/block/raw.c b/block/raw.c
index 63cf2d3..5ca606b 100644
--- a/block/raw.c
+++ b/block/raw.c
@@ -9,30 +9,16 @@ static int raw_open(BlockDriverState *bs, int flags)
     return 0;
 }
 
-static int raw_read(BlockDriverState *bs, int64_t sector_num,
-                    uint8_t *buf, int nb_sectors)
+static int coroutine_fn raw_co_readv(BlockDriverState *bs, int64_t sector_num,
+                                     int nb_sectors, QEMUIOVector *qiov)
 {
-    return bdrv_read(bs->file, sector_num, buf, nb_sectors);
+    return bdrv_co_readv(bs->file, sector_num, nb_sectors, qiov);
 }
 
-static int raw_write(BlockDriverState *bs, int64_t sector_num,
-                     const uint8_t *buf, int nb_sectors)
+static int coroutine_fn raw_co_writev(BlockDriverState *bs, int64_t sector_num,
+                                      int nb_sectors, QEMUIOVector *qiov)
 {
-    return bdrv_write(bs->file, sector_num, buf, nb_sectors);
-}
-
-static BlockDriverAIOCB *raw_aio_readv(BlockDriverState *bs,
-    int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
-    BlockDriverCompletionFunc *cb, void *opaque)
-{
-    return bdrv_aio_readv(bs->file, sector_num, qiov, nb_sectors, cb, opaque);
-}
-
-static BlockDriverAIOCB *raw_aio_writev(BlockDriverState *bs,
-    int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
-    BlockDriverCompletionFunc *cb, void *opaque)
-{
-    return bdrv_aio_writev(bs->file, sector_num, qiov, nb_sectors, cb, opaque);
+    return bdrv_co_writev(bs->file, sector_num, nb_sectors, qiov);
 }
 
 static void raw_close(BlockDriverState *bs)
@@ -129,15 +115,13 @@ static BlockDriver bdrv_raw = {
 
     .bdrv_open          = raw_open,
     .bdrv_close         = raw_close,
-    .bdrv_read          = raw_read,
-    .bdrv_write         = raw_write,
+    .bdrv_co_readv      = raw_co_readv,
+    .bdrv_co_writev     = raw_co_writev,
     .bdrv_flush         = raw_flush,
     .bdrv_probe         = raw_probe,
     .bdrv_getlength     = raw_getlength,
     .bdrv_truncate      = raw_truncate,
 
-    .bdrv_aio_readv     = raw_aio_readv,
-    .bdrv_aio_writev    = raw_aio_writev,
     .bdrv_aio_flush     = raw_aio_flush,
     .bdrv_discard       = raw_discard,
 
-- 
1.7.6.4

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [Qemu-devel] [PATCH 23/24] block: drop .bdrv_read()/.bdrv_write() emulation
  2011-10-14 16:48 [Qemu-devel] [PULL 00/24] Block patches Kevin Wolf
                   ` (21 preceding siblings ...)
  2011-10-14 16:49 ` [Qemu-devel] [PATCH 22/24] block: use coroutine interface for raw format Kevin Wolf
@ 2011-10-14 16:49 ` Kevin Wolf
  2011-10-14 16:49 ` [Qemu-devel] [PATCH 24/24] block: drop bdrv_has_async_rw() Kevin Wolf
  2011-10-14 17:48 ` [Qemu-devel] [PULL 00/24] Block patches Anthony Liguori
  24 siblings, 0 replies; 27+ messages in thread
From: Kevin Wolf @ 2011-10-14 16:49 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>

There is no need to emulate .bdrv_read()/.bdrv_write() since these
interfaces are only called if aio and coroutine interfaces are not
present.  All valid BlockDrivers must implement either sync, aio, or
coroutine interfaces.

Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block.c |   75 ++------------------------------------------------------------
 1 files changed, 3 insertions(+), 72 deletions(-)

diff --git a/block.c b/block.c
index 3d27bab..4d4d61a 100644
--- a/block.c
+++ b/block.c
@@ -57,10 +57,6 @@ static BlockDriverAIOCB *bdrv_aio_flush_em(BlockDriverState *bs,
         BlockDriverCompletionFunc *cb, void *opaque);
 static BlockDriverAIOCB *bdrv_aio_noop_em(BlockDriverState *bs,
         BlockDriverCompletionFunc *cb, void *opaque);
-static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num,
-                        uint8_t *buf, int nb_sectors);
-static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num,
-                         const uint8_t *buf, int nb_sectors);
 static int coroutine_fn bdrv_co_readv_em(BlockDriverState *bs,
                                          int64_t sector_num, int nb_sectors,
                                          QEMUIOVector *iov);
@@ -197,14 +193,13 @@ void bdrv_register(BlockDriver *bdrv)
         bdrv->bdrv_co_readv = bdrv_co_readv_em;
         bdrv->bdrv_co_writev = bdrv_co_writev_em;
 
+        /* bdrv_co_readv_em()/brdv_co_writev_em() work in terms of aio, so if
+         * the block driver lacks aio we need to emulate that too.
+         */
         if (!bdrv->bdrv_aio_readv) {
             /* add AIO emulation layer */
             bdrv->bdrv_aio_readv = bdrv_aio_readv_em;
             bdrv->bdrv_aio_writev = bdrv_aio_writev_em;
-        } else if (!bdrv->bdrv_read) {
-            /* add synchronous IO emulation layer */
-            bdrv->bdrv_read = bdrv_read_em;
-            bdrv->bdrv_write = bdrv_write_em;
         }
     }
 
@@ -2834,70 +2829,6 @@ static BlockDriverAIOCB *bdrv_aio_noop_em(BlockDriverState *bs,
     return &acb->common;
 }
 
-/**************************************************************/
-/* sync block device emulation */
-
-static void bdrv_rw_em_cb(void *opaque, int ret)
-{
-    *(int *)opaque = ret;
-}
-
-static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num,
-                        uint8_t *buf, int nb_sectors)
-{
-    int async_ret;
-    BlockDriverAIOCB *acb;
-    struct iovec iov;
-    QEMUIOVector qiov;
-
-    async_ret = NOT_DONE;
-    iov.iov_base = (void *)buf;
-    iov.iov_len = nb_sectors * BDRV_SECTOR_SIZE;
-    qemu_iovec_init_external(&qiov, &iov, 1);
-
-    acb = bs->drv->bdrv_aio_readv(bs, sector_num, &qiov, nb_sectors,
-                                  bdrv_rw_em_cb, &async_ret);
-    if (acb == NULL) {
-        async_ret = -1;
-        goto fail;
-    }
-
-    while (async_ret == NOT_DONE) {
-        qemu_aio_wait();
-    }
-
-
-fail:
-    return async_ret;
-}
-
-static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num,
-                         const uint8_t *buf, int nb_sectors)
-{
-    int async_ret;
-    BlockDriverAIOCB *acb;
-    struct iovec iov;
-    QEMUIOVector qiov;
-
-    async_ret = NOT_DONE;
-    iov.iov_base = (void *)buf;
-    iov.iov_len = nb_sectors * BDRV_SECTOR_SIZE;
-    qemu_iovec_init_external(&qiov, &iov, 1);
-
-    acb = bs->drv->bdrv_aio_writev(bs, sector_num, &qiov, nb_sectors,
-                                   bdrv_rw_em_cb, &async_ret);
-    if (acb == NULL) {
-        async_ret = -1;
-        goto fail;
-    }
-    while (async_ret == NOT_DONE) {
-        qemu_aio_wait();
-    }
-
-fail:
-    return async_ret;
-}
-
 void bdrv_init(void)
 {
     module_call_init(MODULE_INIT_BLOCK);
-- 
1.7.6.4

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* [Qemu-devel] [PATCH 24/24] block: drop bdrv_has_async_rw()
  2011-10-14 16:48 [Qemu-devel] [PULL 00/24] Block patches Kevin Wolf
                   ` (22 preceding siblings ...)
  2011-10-14 16:49 ` [Qemu-devel] [PATCH 23/24] block: drop .bdrv_read()/.bdrv_write() emulation Kevin Wolf
@ 2011-10-14 16:49 ` Kevin Wolf
  2011-10-14 17:48 ` [Qemu-devel] [PULL 00/24] Block patches Anthony Liguori
  24 siblings, 0 replies; 27+ messages in thread
From: Kevin Wolf @ 2011-10-14 16:49 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>

Commit cd74d83345e0e3b708330ab8c4cd9111bb82cda6 ("block: switch
bdrv_read()/bdrv_write() to coroutines") removed the bdrv_has_async_rw()
callers.  This patch removes bdrv_has_async_rw() since it is no longer
used.

Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block.c |    6 ------
 1 files changed, 0 insertions(+), 6 deletions(-)

diff --git a/block.c b/block.c
index 4d4d61a..9873b57 100644
--- a/block.c
+++ b/block.c
@@ -1027,12 +1027,6 @@ static int bdrv_check_request(BlockDriverState *bs, int64_t sector_num,
                                    nb_sectors * BDRV_SECTOR_SIZE);
 }
 
-static inline bool bdrv_has_async_rw(BlockDriver *drv)
-{
-    return drv->bdrv_co_readv != bdrv_co_readv_em
-        || drv->bdrv_aio_readv != bdrv_aio_readv_em;
-}
-
 static inline bool bdrv_has_async_flush(BlockDriver *drv)
 {
     return drv->bdrv_aio_flush != bdrv_aio_flush_em;
-- 
1.7.6.4

^ permalink raw reply related	[flat|nested] 27+ messages in thread

* Re: [Qemu-devel] [PULL 00/24] Block patches
  2011-10-14 16:48 [Qemu-devel] [PULL 00/24] Block patches Kevin Wolf
                   ` (23 preceding siblings ...)
  2011-10-14 16:49 ` [Qemu-devel] [PATCH 24/24] block: drop bdrv_has_async_rw() Kevin Wolf
@ 2011-10-14 17:48 ` Anthony Liguori
  24 siblings, 0 replies; 27+ messages in thread
From: Anthony Liguori @ 2011-10-14 17:48 UTC (permalink / raw)
  To: Kevin Wolf; +Cc: qemu-devel

On 10/14/2011 11:48 AM, Kevin Wolf wrote:
> The following changes since commit ebffe2afceb1a17b5d134b5debf553955fe5ea1a:
>
>    Merge remote-tracking branch 'qmp/queue/qmp' into staging (2011-10-10 08:21:46 -0500)
>
> are available in the git repository at:
>
>    git://repo.or.cz/qemu/kevin.git for-anthony

Pulled.  Thanks.

Regards,

Anthony Liguori

>
> Christoph Hellwig (1):
>        block: allow resizing of images residing on host devices
>
> Kevin Wolf (3):
>        linux-aio: Fix laio_submit error handling
>        vvfat: Fix potential buffer overflow
>        linux-aio: Allow reads beyond the end of growable images
>
> Luiz Capitulino (6):
>        block: Keep track of devices' I/O status
>        virtio: Support I/O status
>        ide: Support I/O status
>        scsi: Support I/O status
>        QMP: query-status: Add 'io-status' key
>        HMP: Print 'io-status' information
>
> Stefan Hajnoczi (12):
>        block: directly invoke .bdrv_aio_*() in bdrv_co_io_em()
>        block: directly invoke .bdrv_* from emulation functions
>        block: split out bdrv_co_do_readv() and bdrv_co_do_writev()
>        block: switch bdrv_read()/bdrv_write() to coroutines
>        block: switch bdrv_aio_readv() to coroutines
>        block: mark blocks dirty on coroutine write completion
>        block: switch bdrv_aio_writev() to coroutines
>        block: drop emulation functions that use coroutines
>        raw-posix: remove bdrv_read()/bdrv_write()
>        block: use coroutine interface for raw format
>        block: drop .bdrv_read()/.bdrv_write() emulation
>        block: drop bdrv_has_async_rw()
>
> Stefan Weil (2):
>        block/vvfat: Fix potential memory leaks and other memory errors
>        block/vvfat: Remove unused code
>
>   block.c           |  424 ++++++++++++++++++++++-------------------------------
>   block.h           |   10 ++
>   block/raw-posix.c |  301 +++-----------------------------------
>   block/raw.c       |   32 +---
>   block/vvfat.c     |  109 ++++----------
>   block_int.h       |    1 +
>   hw/ide/core.c     |    2 +
>   hw/scsi-disk.c    |    2 +
>   hw/virtio-blk.c   |    2 +
>   linux-aio.c       |   21 ++-
>   monitor.c         |    6 +
>   qmp-commands.hx   |    6 +
>   12 files changed, 283 insertions(+), 633 deletions(-)
>
>

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [Qemu-devel] [PATCH 15/24] block: switch bdrv_read()/bdrv_write() to coroutines
  2011-10-14 16:49 ` [Qemu-devel] [PATCH 15/24] block: switch bdrv_read()/bdrv_write() to coroutines Kevin Wolf
@ 2011-10-24 15:12   ` Pierre Riteau
  0 siblings, 0 replies; 27+ messages in thread
From: Pierre Riteau @ 2011-10-24 15:12 UTC (permalink / raw)
  To: Stefan Hajnoczi; +Cc: Kevin Wolf, qemu-devel

This commit (1c9805a398cc1125b4defa6367172c8c2c0bca9f in Git) breaks qemu-nbd for me. I cannot mount any VM image (raw or qcow2 format) with this commit or today's HEAD. Previous commit c5fbe57111ef59c315a71cd80e8b0af59e36ff21 works fine.

The qemu-nbd process hangs while reading disk:

31175 ?        Ss     0:00 qemu-nbd --connect=/dev/nbd0 /tmp/lenny-vm.raw
31176 ?        S      0:00  \_ qemu-nbd --connect=/dev/nbd0 /tmp/lenny-vm.raw
31177 ?        D      0:00  \_ qemu-nbd --connect=/dev/nbd0 /tmp/lenny-vm.raw

In dmesg I see only:

[18304.541058]  nbd0:

Then, if I pkill -9 nbd, dmesg gets more verbose:

[18467.288183] nbd (pid 31175: qemu-nbd) got signal 9
[18467.303175] nbd0: shutting down socket
[18467.314446] nbd0: Receive control failed (result -4)
[18467.329354] end_request: I/O error, dev nbd0, sector 0
[18467.344771] __ratelimit: 38 callbacks suppressed
[18467.358620] Buffer I/O error on device nbd0, logical block 0
[18467.375591] Buffer I/O error on device nbd0, logical block 1
[18467.392560] Buffer I/O error on device nbd0, logical block 2
[18467.409530] Buffer I/O error on device nbd0, logical block 3
[18467.426508] nbd0: queue cleared
[18467.435962] nbd0: Attempted send on closed socket
[18467.450095] end_request: I/O error, dev nbd0, sector 0
[18467.465527] Buffer I/O error on device nbd0, logical block 0
[18467.482496] Buffer I/O error on device nbd0, logical block 1
[18467.499464] Buffer I/O error on device nbd0, logical block 2
[18467.516433] Buffer I/O error on device nbd0, logical block 3
[18467.533418] nbd0: Attempted send on closed socket
[18467.547539] end_request: I/O error, dev nbd0, sector 0
[18467.562945] Buffer I/O error on device nbd0, logical block 0
[18467.579917] Buffer I/O error on device nbd0, logical block 1
[18467.596897] nbd0: Attempted send on closed socket
[18467.611022] end_request: I/O error, dev nbd0, sector 0
[18467.626442] nbd0: Attempted send on closed socket
[18467.640569] end_request: I/O error, dev nbd0, sector 0
[18467.655984] ldm_validate_partition_table(): Disk read failed.
[18467.673242] nbd0: Attempted send on closed socket
[18467.687369] end_request: I/O error, dev nbd0, sector 0
[18467.702788] nbd0: Attempted send on closed socket
[18467.716915] end_request: I/O error, dev nbd0, sector 0
[18467.732359] nbd0: Attempted send on closed socket
[18467.746487] end_request: I/O error, dev nbd0, sector 0
[18467.761931] nbd0: Attempted send on closed socket
[18467.776058] end_request: I/O error, dev nbd0, sector 0
[18467.791473] Dev nbd0: unable to read RDB block 0
[18467.805348] nbd0: Attempted send on closed socket
[18467.819479] end_request: I/O error, dev nbd0, sector 0
[18467.834897] nbd0: Attempted send on closed socket
[18467.849025] end_request: I/O error, dev nbd0, sector 0
[18467.864446] nbd0: Attempted send on closed socket
[18467.878572] end_request: I/O error, dev nbd0, sector 0
[18467.893985]  unable to read partition table

-- 
Pierre Riteau -- PhD student, Myriads team, IRISA, Rennes, France
http://perso.univ-rennes1.fr/pierre.riteau/

On 14 oct. 2011, at 18:49, Kevin Wolf wrote:

> From: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
> 
> The bdrv_read()/bdrv_write() functions call .bdrv_read()/.bdrv_write().
> They should go through bdrv_co_do_readv() and bdrv_co_do_writev()
> instead in order to unify request processing code across sync, aio, and
> coroutine interfaces.  This is also an important step towards removing
> BlockDriverState .bdrv_read()/.bdrv_write() in the future.
> 
> Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
> ---
> block.c |  112 +++++++++++++++++++++++++++++++++++----------------------------
> 1 files changed, 62 insertions(+), 50 deletions(-)
> 
> diff --git a/block.c b/block.c
> index f4731ec..ae8fc80 100644
> --- a/block.c
> +++ b/block.c
> @@ -44,6 +44,8 @@
> #include <windows.h>
> #endif
> 
> +#define NOT_DONE 0x7fffffff /* used while emulated sync operation in progress */
> +
> static void bdrv_dev_change_media_cb(BlockDriverState *bs, bool load);
> static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs,
>         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
> @@ -74,6 +76,8 @@ static int coroutine_fn bdrv_co_writev_em(BlockDriverState *bs,
> static int coroutine_fn bdrv_co_flush_em(BlockDriverState *bs);
> static int coroutine_fn bdrv_co_do_readv(BlockDriverState *bs,
>     int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
> +static int coroutine_fn bdrv_co_do_writev(BlockDriverState *bs,
> +    int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
> 
> static QTAILQ_HEAD(, BlockDriverState) bdrv_states =
>     QTAILQ_HEAD_INITIALIZER(bdrv_states);
> @@ -1042,30 +1046,69 @@ static inline bool bdrv_has_async_flush(BlockDriver *drv)
>     return drv->bdrv_aio_flush != bdrv_aio_flush_em;
> }
> 
> -/* 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)
> +typedef struct RwCo {
> +    BlockDriverState *bs;
> +    int64_t sector_num;
> +    int nb_sectors;
> +    QEMUIOVector *qiov;
> +    bool is_write;
> +    int ret;
> +} RwCo;
> +
> +static void coroutine_fn bdrv_rw_co_entry(void *opaque)
> {
> -    BlockDriver *drv = bs->drv;
> +    RwCo *rwco = opaque;
> 
> -    if (!drv)
> -        return -ENOMEDIUM;
> +    if (!rwco->is_write) {
> +        rwco->ret = bdrv_co_do_readv(rwco->bs, rwco->sector_num,
> +                                     rwco->nb_sectors, rwco->qiov);
> +    } else {
> +        rwco->ret = bdrv_co_do_writev(rwco->bs, rwco->sector_num,
> +                                      rwco->nb_sectors, rwco->qiov);
> +    }
> +}
> 
> -    if (bdrv_has_async_rw(drv) && qemu_in_coroutine()) {
> -        QEMUIOVector qiov;
> -        struct iovec iov = {
> -            .iov_base = (void *)buf,
> -            .iov_len = nb_sectors * BDRV_SECTOR_SIZE,
> -        };
> +/*
> + * 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,
> +    };
> +    Coroutine *co;
> +    RwCo rwco = {
> +        .bs = bs,
> +        .sector_num = sector_num,
> +        .nb_sectors = nb_sectors,
> +        .qiov = &qiov,
> +        .is_write = is_write,
> +        .ret = NOT_DONE,
> +    };
> 
> -        qemu_iovec_init_external(&qiov, &iov, 1);
> -        return bdrv_co_readv(bs, sector_num, nb_sectors, &qiov);
> -    }
> +    qemu_iovec_init_external(&qiov, &iov, 1);
> 
> -    if (bdrv_check_request(bs, sector_num, nb_sectors))
> -        return -EIO;
> +    if (qemu_in_coroutine()) {
> +        /* Fast-path if already in coroutine context */
> +        bdrv_rw_co_entry(&rwco);
> +    } else {
> +        co = qemu_coroutine_create(bdrv_rw_co_entry);
> +        qemu_coroutine_enter(co, &rwco);
> +        while (rwco.ret == NOT_DONE) {
> +            qemu_aio_wait();
> +        }
> +    }
> +    return rwco.ret;
> +}
> 
> -    return drv->bdrv_read(bs, sector_num, buf, nb_sectors);
> +/* 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)
> +{
> +    return bdrv_rw_co(bs, sector_num, buf, nb_sectors, false);
> }
> 
> static void set_dirty_bitmap(BlockDriverState *bs, int64_t sector_num,
> @@ -1105,36 +1148,7 @@ static void set_dirty_bitmap(BlockDriverState *bs, int64_t sector_num,
> int bdrv_write(BlockDriverState *bs, int64_t sector_num,
>                const uint8_t *buf, int nb_sectors)
> {
> -    BlockDriver *drv = bs->drv;
> -
> -    if (!bs->drv)
> -        return -ENOMEDIUM;
> -
> -    if (bdrv_has_async_rw(drv) && qemu_in_coroutine()) {
> -        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_co_writev(bs, sector_num, nb_sectors, &qiov);
> -    }
> -
> -    if (bs->read_only)
> -        return -EACCES;
> -    if (bdrv_check_request(bs, sector_num, nb_sectors))
> -        return -EIO;
> -
> -    if (bs->dirty_bitmap) {
> -        set_dirty_bitmap(bs, sector_num, nb_sectors, 1);
> -    }
> -
> -    if (bs->wr_highest_sector < sector_num + nb_sectors - 1) {
> -        bs->wr_highest_sector = sector_num + nb_sectors - 1;
> -    }
> -
> -    return drv->bdrv_write(bs, sector_num, buf, nb_sectors);
> +    return bdrv_rw_co(bs, sector_num, (uint8_t *)buf, nb_sectors, true);
> }
> 
> int bdrv_pread(BlockDriverState *bs, int64_t offset,
> @@ -2912,8 +2926,6 @@ static void bdrv_rw_em_cb(void *opaque, int ret)
>     *(int *)opaque = ret;
> }
> 
> -#define NOT_DONE 0x7fffffff
> -
> static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num,
>                         uint8_t *buf, int nb_sectors)
> {
> -- 
> 1.7.6.4
> 
> 

^ permalink raw reply	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2011-10-24 15:12 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-10-14 16:48 [Qemu-devel] [PULL 00/24] Block patches Kevin Wolf
2011-10-14 16:48 ` [Qemu-devel] [PATCH 01/24] block: allow resizing of images residing on host devices Kevin Wolf
2011-10-14 16:48 ` [Qemu-devel] [PATCH 02/24] linux-aio: Fix laio_submit error handling Kevin Wolf
2011-10-14 16:48 ` [Qemu-devel] [PATCH 03/24] block: Keep track of devices' I/O status Kevin Wolf
2011-10-14 16:48 ` [Qemu-devel] [PATCH 04/24] virtio: Support " Kevin Wolf
2011-10-14 16:49 ` [Qemu-devel] [PATCH 05/24] ide: " Kevin Wolf
2011-10-14 16:49 ` [Qemu-devel] [PATCH 06/24] scsi: " Kevin Wolf
2011-10-14 16:49 ` [Qemu-devel] [PATCH 07/24] QMP: query-status: Add 'io-status' key Kevin Wolf
2011-10-14 16:49 ` [Qemu-devel] [PATCH 08/24] HMP: Print 'io-status' information Kevin Wolf
2011-10-14 16:49 ` [Qemu-devel] [PATCH 09/24] block/vvfat: Fix potential memory leaks and other memory errors Kevin Wolf
2011-10-14 16:49 ` [Qemu-devel] [PATCH 10/24] block/vvfat: Remove unused code Kevin Wolf
2011-10-14 16:49 ` [Qemu-devel] [PATCH 11/24] vvfat: Fix potential buffer overflow Kevin Wolf
2011-10-14 16:49 ` [Qemu-devel] [PATCH 12/24] block: directly invoke .bdrv_aio_*() in bdrv_co_io_em() Kevin Wolf
2011-10-14 16:49 ` [Qemu-devel] [PATCH 13/24] block: directly invoke .bdrv_* from emulation functions Kevin Wolf
2011-10-14 16:49 ` [Qemu-devel] [PATCH 14/24] block: split out bdrv_co_do_readv() and bdrv_co_do_writev() Kevin Wolf
2011-10-14 16:49 ` [Qemu-devel] [PATCH 15/24] block: switch bdrv_read()/bdrv_write() to coroutines Kevin Wolf
2011-10-24 15:12   ` Pierre Riteau
2011-10-14 16:49 ` [Qemu-devel] [PATCH 16/24] block: switch bdrv_aio_readv() " Kevin Wolf
2011-10-14 16:49 ` [Qemu-devel] [PATCH 17/24] block: mark blocks dirty on coroutine write completion Kevin Wolf
2011-10-14 16:49 ` [Qemu-devel] [PATCH 18/24] block: switch bdrv_aio_writev() to coroutines Kevin Wolf
2011-10-14 16:49 ` [Qemu-devel] [PATCH 19/24] linux-aio: Allow reads beyond the end of growable images Kevin Wolf
2011-10-14 16:49 ` [Qemu-devel] [PATCH 20/24] block: drop emulation functions that use coroutines Kevin Wolf
2011-10-14 16:49 ` [Qemu-devel] [PATCH 21/24] raw-posix: remove bdrv_read()/bdrv_write() Kevin Wolf
2011-10-14 16:49 ` [Qemu-devel] [PATCH 22/24] block: use coroutine interface for raw format Kevin Wolf
2011-10-14 16:49 ` [Qemu-devel] [PATCH 23/24] block: drop .bdrv_read()/.bdrv_write() emulation Kevin Wolf
2011-10-14 16:49 ` [Qemu-devel] [PATCH 24/24] block: drop bdrv_has_async_rw() Kevin Wolf
2011-10-14 17:48 ` [Qemu-devel] [PULL 00/24] Block patches Anthony Liguori

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).