qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PULL 00/19] Block patches
@ 2011-10-21 17:18 Kevin Wolf
  2011-10-21 17:18 ` [Qemu-devel] [PATCH 01/19] sheepdog: add coroutine_fn markers Kevin Wolf
                   ` (19 more replies)
  0 siblings, 20 replies; 21+ messages in thread
From: Kevin Wolf @ 2011-10-21 17:18 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

The following changes since commit c2e2343e1faae7bbc77574c12a25881b1b696808:

  hw/arm_gic.c: Fix save/load of irq_target array (2011-10-21 17:19:56 +0200)

are available in the git repository at:
  git://repo.or.cz/qemu/kevin.git for-anthony

Alex Jia (1):
      fix memory leak in aio_write_f

Kevin Wolf (5):
      xen_disk: Always set feature-barrier = 1
      fdc: Fix floppy port I/O
      qemu-img: Don't allow preallocation and compression at the same time
      qcow2: Fix bdrv_write_compressed error handling
      pc: Fix floppy drives with if=none

Paolo Bonzini (12):
      sheepdog: add coroutine_fn markers
      add socket_set_block
      block: rename bdrv_co_rw_bh
      block: unify flush implementations
      block: add bdrv_co_discard and bdrv_aio_discard support
      vmdk: fix return values of vmdk_parent_open
      vmdk: clean up open
      block: add a CoMutex to synchronous read drivers
      block: take lock around bdrv_read implementations
      block: take lock around bdrv_write implementations
      block: change flush to co_flush
      block: change discard to co_discard

Stefan Hajnoczi (1):
      block: drop redundant bdrv_flush implementation

 block.c               |  258 ++++++++++++++++++++++++++++++-------------------
 block.h               |    5 +
 block/blkdebug.c      |    6 -
 block/blkverify.c     |    9 --
 block/bochs.c         |   15 +++-
 block/cloop.c         |   15 +++-
 block/cow.c           |   34 ++++++-
 block/dmg.c           |   15 +++-
 block/nbd.c           |   28 +++++-
 block/parallels.c     |   15 +++-
 block/qcow.c          |   17 +---
 block/qcow2-cluster.c |    6 +-
 block/qcow2.c         |   72 ++++++--------
 block/qed.c           |    6 -
 block/raw-posix.c     |   23 +----
 block/raw-win32.c     |    4 +-
 block/raw.c           |   23 ++---
 block/rbd.c           |    4 +-
 block/sheepdog.c      |   14 ++--
 block/vdi.c           |    6 +-
 block/vmdk.c          |   82 ++++++++++------
 block/vpc.c           |   34 ++++++-
 block/vvfat.c         |   28 +++++-
 block_int.h           |    9 +-
 hw/fdc.c              |   14 +++
 hw/fdc.h              |    9 ++-
 hw/pc.c               |   25 +++--
 hw/pc.h               |    3 +-
 hw/pc_piix.c          |    5 +-
 hw/xen_disk.c         |    5 +-
 oslib-posix.c         |    7 ++
 oslib-win32.c         |    6 +
 qemu-img.c            |   11 ++
 qemu-io.c             |    1 +
 qemu_socket.h         |    1 +
 trace-events          |    1 +
 36 files changed, 524 insertions(+), 292 deletions(-)

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

* [Qemu-devel] [PATCH 01/19] sheepdog: add coroutine_fn markers
  2011-10-21 17:18 [Qemu-devel] [PULL 00/19] Block patches Kevin Wolf
@ 2011-10-21 17:18 ` Kevin Wolf
  2011-10-21 17:18 ` [Qemu-devel] [PATCH 02/19] add socket_set_block Kevin Wolf
                   ` (18 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Kevin Wolf @ 2011-10-21 17:18 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Paolo Bonzini <pbonzini@redhat.com>

This makes the following patch easier to review.

Cc: MORITA Kazutaka <morita.kazutaka@lab.ntt.co.jp>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/sheepdog.c |   14 +++++++-------
 1 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/block/sheepdog.c b/block/sheepdog.c
index ae857e2..9f80609 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -396,7 +396,7 @@ static inline int free_aio_req(BDRVSheepdogState *s, AIOReq *aio_req)
     return !QLIST_EMPTY(&acb->aioreq_head);
 }
 
-static void sd_finish_aiocb(SheepdogAIOCB *acb)
+static void coroutine_fn sd_finish_aiocb(SheepdogAIOCB *acb)
 {
     if (!acb->canceled) {
         qemu_coroutine_enter(acb->coroutine, NULL);
@@ -735,7 +735,7 @@ out:
     return ret;
 }
 
-static int add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
+static int coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
                            struct iovec *iov, int niov, int create,
                            enum AIOCBState aiocb_type);
 
@@ -743,7 +743,7 @@ static int add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
  * This function searchs pending requests to the object `oid', and
  * sends them.
  */
-static void send_pending_req(BDRVSheepdogState *s, uint64_t oid, uint32_t id)
+static void coroutine_fn send_pending_req(BDRVSheepdogState *s, uint64_t oid, uint32_t id)
 {
     AIOReq *aio_req, *next;
     SheepdogAIOCB *acb;
@@ -777,7 +777,7 @@ static void send_pending_req(BDRVSheepdogState *s, uint64_t oid, uint32_t id)
  * This function is registered as a fd handler, and called from the
  * main loop when s->fd is ready for reading responses.
  */
-static void aio_read_response(void *opaque)
+static void coroutine_fn aio_read_response(void *opaque)
 {
     SheepdogObjRsp rsp;
     BDRVSheepdogState *s = opaque;
@@ -1064,7 +1064,7 @@ out:
     return ret;
 }
 
-static int add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
+static int coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
                            struct iovec *iov, int niov, int create,
                            enum AIOCBState aiocb_type)
 {
@@ -1517,7 +1517,7 @@ static int sd_truncate(BlockDriverState *bs, int64_t offset)
  * update metadata, this sends a write request to the vdi object.
  * Otherwise, this switches back to sd_co_readv/writev.
  */
-static void sd_write_done(SheepdogAIOCB *acb)
+static void coroutine_fn sd_write_done(SheepdogAIOCB *acb)
 {
     int ret;
     BDRVSheepdogState *s = acb->common.bs->opaque;
@@ -1615,7 +1615,7 @@ out:
  * Returns 1 when we need to wait a response, 0 when there is no sent
  * request and -errno in error cases.
  */
-static int sd_co_rw_vector(void *p)
+static int coroutine_fn sd_co_rw_vector(void *p)
 {
     SheepdogAIOCB *acb = p;
     int ret = 0;
-- 
1.7.6.4

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

* [Qemu-devel] [PATCH 02/19] add socket_set_block
  2011-10-21 17:18 [Qemu-devel] [PULL 00/19] Block patches Kevin Wolf
  2011-10-21 17:18 ` [Qemu-devel] [PATCH 01/19] sheepdog: add coroutine_fn markers Kevin Wolf
@ 2011-10-21 17:18 ` Kevin Wolf
  2011-10-21 17:19 ` [Qemu-devel] [PATCH 03/19] block: rename bdrv_co_rw_bh Kevin Wolf
                   ` (17 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Kevin Wolf @ 2011-10-21 17:18 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Paolo Bonzini <pbonzini@redhat.com>

Cc: MORITA Kazutaka <morita.kazutaka@lab.ntt.co.jp>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 oslib-posix.c |    7 +++++++
 oslib-win32.c |    6 ++++++
 qemu_socket.h |    1 +
 3 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/oslib-posix.c b/oslib-posix.c
index a304fb0..dbc8ee8 100644
--- a/oslib-posix.c
+++ b/oslib-posix.c
@@ -103,6 +103,13 @@ void qemu_vfree(void *ptr)
     free(ptr);
 }
 
+void socket_set_block(int fd)
+{
+    int f;
+    f = fcntl(fd, F_GETFL);
+    fcntl(fd, F_SETFL, f & ~O_NONBLOCK);
+}
+
 void socket_set_nonblock(int fd)
 {
     int f;
diff --git a/oslib-win32.c b/oslib-win32.c
index 5f0759f..5e3de7d 100644
--- a/oslib-win32.c
+++ b/oslib-win32.c
@@ -73,6 +73,12 @@ void qemu_vfree(void *ptr)
     VirtualFree(ptr, 0, MEM_RELEASE);
 }
 
+void socket_set_block(int fd)
+{
+    unsigned long opt = 0;
+    ioctlsocket(fd, FIONBIO, &opt);
+}
+
 void socket_set_nonblock(int fd)
 {
     unsigned long opt = 1;
diff --git a/qemu_socket.h b/qemu_socket.h
index 180e4db..9e32fac 100644
--- a/qemu_socket.h
+++ b/qemu_socket.h
@@ -35,6 +35,7 @@ int inet_aton(const char *cp, struct in_addr *ia);
 /* misc helpers */
 int qemu_socket(int domain, int type, int protocol);
 int qemu_accept(int s, struct sockaddr *addr, socklen_t *addrlen);
+void socket_set_block(int fd);
 void socket_set_nonblock(int fd);
 int send_all(int fd, const void *buf, int len1);
 
-- 
1.7.6.4

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

* [Qemu-devel] [PATCH 03/19] block: rename bdrv_co_rw_bh
  2011-10-21 17:18 [Qemu-devel] [PULL 00/19] Block patches Kevin Wolf
  2011-10-21 17:18 ` [Qemu-devel] [PATCH 01/19] sheepdog: add coroutine_fn markers Kevin Wolf
  2011-10-21 17:18 ` [Qemu-devel] [PATCH 02/19] add socket_set_block Kevin Wolf
@ 2011-10-21 17:19 ` Kevin Wolf
  2011-10-21 17:19 ` [Qemu-devel] [PATCH 04/19] fix memory leak in aio_write_f Kevin Wolf
                   ` (16 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Kevin Wolf @ 2011-10-21 17:19 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Paolo Bonzini <pbonzini@redhat.com>

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

diff --git a/block.c b/block.c
index 9873b57..7184a0f 100644
--- a/block.c
+++ b/block.c
@@ -2735,7 +2735,7 @@ static AIOPool bdrv_em_co_aio_pool = {
     .cancel             = bdrv_aio_co_cancel_em,
 };
 
-static void bdrv_co_rw_bh(void *opaque)
+static void bdrv_co_em_bh(void *opaque)
 {
     BlockDriverAIOCBCoroutine *acb = opaque;
 
@@ -2758,7 +2758,7 @@ static void coroutine_fn bdrv_co_do_rw(void *opaque)
             acb->req.nb_sectors, acb->req.qiov);
     }
 
-    acb->bh = qemu_bh_new(bdrv_co_rw_bh, acb);
+    acb->bh = qemu_bh_new(bdrv_co_em_bh, acb);
     qemu_bh_schedule(acb->bh);
 }
 
-- 
1.7.6.4

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

* [Qemu-devel] [PATCH 04/19] fix memory leak in aio_write_f
  2011-10-21 17:18 [Qemu-devel] [PULL 00/19] Block patches Kevin Wolf
                   ` (2 preceding siblings ...)
  2011-10-21 17:19 ` [Qemu-devel] [PATCH 03/19] block: rename bdrv_co_rw_bh Kevin Wolf
@ 2011-10-21 17:19 ` Kevin Wolf
  2011-10-21 17:19 ` [Qemu-devel] [PATCH 05/19] xen_disk: Always set feature-barrier = 1 Kevin Wolf
                   ` (15 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Kevin Wolf @ 2011-10-21 17:19 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Alex Jia <ajia@redhat.com>

Haven't released memory of 'ctx' before return.

Signed-off-by: Alex Jia <ajia@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 qemu-io.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/qemu-io.c b/qemu-io.c
index e91af37..c45a413 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -1248,6 +1248,7 @@ static int aio_write_f(int argc, char **argv)
         case 'P':
             pattern = parse_pattern(optarg);
             if (pattern < 0) {
+                free(ctx);
                 return 0;
             }
             break;
-- 
1.7.6.4

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

* [Qemu-devel] [PATCH 05/19] xen_disk: Always set feature-barrier = 1
  2011-10-21 17:18 [Qemu-devel] [PULL 00/19] Block patches Kevin Wolf
                   ` (3 preceding siblings ...)
  2011-10-21 17:19 ` [Qemu-devel] [PATCH 04/19] fix memory leak in aio_write_f Kevin Wolf
@ 2011-10-21 17:19 ` Kevin Wolf
  2011-10-21 17:19 ` [Qemu-devel] [PATCH 06/19] block: unify flush implementations Kevin Wolf
                   ` (14 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Kevin Wolf @ 2011-10-21 17:19 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

The synchronous .bdrv_flush callback doesn't exist any more and a device really
shouldn't poke into the block layer internals anyway. All drivers are supposed
to have a correctly working bdrv_flush, so let's just hard-code this.

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

diff --git a/hw/xen_disk.c b/hw/xen_disk.c
index 8a9fac4..286bbac 100644
--- a/hw/xen_disk.c
+++ b/hw/xen_disk.c
@@ -620,7 +620,7 @@ static void blk_alloc(struct XenDevice *xendev)
 static int blk_init(struct XenDevice *xendev)
 {
     struct XenBlkDev *blkdev = container_of(xendev, struct XenBlkDev, xendev);
-    int index, qflags, have_barriers, info = 0;
+    int index, qflags, info = 0;
 
     /* read xenstore entries */
     if (blkdev->params == NULL) {
@@ -706,7 +706,6 @@ static int blk_init(struct XenDevice *xendev)
                       blkdev->bs->drv ? blkdev->bs->drv->format_name : "-");
         blkdev->file_size = 0;
     }
-    have_barriers = blkdev->bs->drv && blkdev->bs->drv->bdrv_flush ? 1 : 0;
 
     xen_be_printf(xendev, 1, "type \"%s\", fileproto \"%s\", filename \"%s\","
                   " size %" PRId64 " (%" PRId64 " MB)\n",
@@ -714,7 +713,7 @@ static int blk_init(struct XenDevice *xendev)
                   blkdev->file_size, blkdev->file_size >> 20);
 
     /* fill info */
-    xenstore_write_be_int(&blkdev->xendev, "feature-barrier", have_barriers);
+    xenstore_write_be_int(&blkdev->xendev, "feature-barrier", 1);
     xenstore_write_be_int(&blkdev->xendev, "info",            info);
     xenstore_write_be_int(&blkdev->xendev, "sector-size",     blkdev->file_blk);
     xenstore_write_be_int(&blkdev->xendev, "sectors",
-- 
1.7.6.4

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

* [Qemu-devel] [PATCH 06/19] block: unify flush implementations
  2011-10-21 17:18 [Qemu-devel] [PULL 00/19] Block patches Kevin Wolf
                   ` (4 preceding siblings ...)
  2011-10-21 17:19 ` [Qemu-devel] [PATCH 05/19] xen_disk: Always set feature-barrier = 1 Kevin Wolf
@ 2011-10-21 17:19 ` Kevin Wolf
  2011-10-21 17:19 ` [Qemu-devel] [PATCH 07/19] block: drop redundant bdrv_flush implementation Kevin Wolf
                   ` (13 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Kevin Wolf @ 2011-10-21 17:19 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Paolo Bonzini <pbonzini@redhat.com>

Add coroutine support for flush and apply the same emulation that
we already do for read/write.  bdrv_aio_flush is simplified to always
go through a coroutine.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block.c     |  164 ++++++++++++++++++++++++++--------------------------------
 block.h     |    1 +
 block_int.h |    1 +
 3 files changed, 76 insertions(+), 90 deletions(-)

diff --git a/block.c b/block.c
index 7184a0f..7b8b14d 100644
--- a/block.c
+++ b/block.c
@@ -53,17 +53,12 @@ static BlockDriverAIOCB *bdrv_aio_readv_em(BlockDriverState *bs,
 static BlockDriverAIOCB *bdrv_aio_writev_em(BlockDriverState *bs,
         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
         BlockDriverCompletionFunc *cb, void *opaque);
-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 coroutine_fn bdrv_co_readv_em(BlockDriverState *bs,
                                          int64_t sector_num, int nb_sectors,
                                          QEMUIOVector *iov);
 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 int coroutine_fn bdrv_co_do_writev(BlockDriverState *bs,
@@ -203,9 +198,6 @@ void bdrv_register(BlockDriver *bdrv)
         }
     }
 
-    if (!bdrv->bdrv_aio_flush)
-        bdrv->bdrv_aio_flush = bdrv_aio_flush_em;
-
     QLIST_INSERT_HEAD(&bdrv_drivers, bdrv, list);
 }
 
@@ -1027,11 +1019,6 @@ static int bdrv_check_request(BlockDriverState *bs, int64_t sector_num,
                                    nb_sectors * BDRV_SECTOR_SIZE);
 }
 
-static inline bool bdrv_has_async_flush(BlockDriver *drv)
-{
-    return drv->bdrv_aio_flush != bdrv_aio_flush_em;
-}
-
 typedef struct RwCo {
     BlockDriverState *bs;
     int64_t sector_num;
@@ -1759,33 +1746,6 @@ const char *bdrv_get_device_name(BlockDriverState *bs)
     return bs->device_name;
 }
 
-int bdrv_flush(BlockDriverState *bs)
-{
-    if (bs->open_flags & BDRV_O_NO_FLUSH) {
-        return 0;
-    }
-
-    if (bs->drv && bdrv_has_async_flush(bs->drv) && qemu_in_coroutine()) {
-        return bdrv_co_flush_em(bs);
-    }
-
-    if (bs->drv && bs->drv->bdrv_flush) {
-        return bs->drv->bdrv_flush(bs);
-    }
-
-    /*
-     * Some block drivers always operate in either writethrough or unsafe mode
-     * and don't support bdrv_flush therefore. Usually qemu doesn't know how
-     * the server works (because the behaviour is hardcoded or depends on
-     * server-side configuration), so we can't ensure that everything is safe
-     * on disk. Returning an error doesn't work because that would break guests
-     * even if the server operates in writethrough mode.
-     *
-     * Let's hope the user knows what he's doing.
-     */
-    return 0;
-}
-
 void bdrv_flush_all(void)
 {
     BlockDriverState *bs;
@@ -2610,22 +2570,6 @@ fail:
     return -1;
 }
 
-BlockDriverAIOCB *bdrv_aio_flush(BlockDriverState *bs,
-        BlockDriverCompletionFunc *cb, void *opaque)
-{
-    BlockDriver *drv = bs->drv;
-
-    trace_bdrv_aio_flush(bs, opaque);
-
-    if (bs->open_flags & BDRV_O_NO_FLUSH) {
-        return bdrv_aio_noop_em(bs, cb, opaque);
-    }
-
-    if (!drv)
-        return NULL;
-    return drv->bdrv_aio_flush(bs, cb, opaque);
-}
-
 void bdrv_aio_cancel(BlockDriverAIOCB *acb)
 {
     acb->pool->cancel(acb);
@@ -2785,41 +2729,28 @@ static BlockDriverAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs,
     return &acb->common;
 }
 
-static BlockDriverAIOCB *bdrv_aio_flush_em(BlockDriverState *bs,
-        BlockDriverCompletionFunc *cb, void *opaque)
+static void coroutine_fn bdrv_aio_flush_co_entry(void *opaque)
 {
-    BlockDriverAIOCBSync *acb;
-
-    acb = qemu_aio_get(&bdrv_em_aio_pool, bs, cb, opaque);
-    acb->is_write = 1; /* don't bounce in the completion hadler */
-    acb->qiov = NULL;
-    acb->bounce = NULL;
-    acb->ret = 0;
-
-    if (!acb->bh)
-        acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb);
+    BlockDriverAIOCBCoroutine *acb = opaque;
+    BlockDriverState *bs = acb->common.bs;
 
-    bdrv_flush(bs);
+    acb->req.error = bdrv_co_flush(bs);
+    acb->bh = qemu_bh_new(bdrv_co_em_bh, acb);
     qemu_bh_schedule(acb->bh);
-    return &acb->common;
 }
 
-static BlockDriverAIOCB *bdrv_aio_noop_em(BlockDriverState *bs,
+BlockDriverAIOCB *bdrv_aio_flush(BlockDriverState *bs,
         BlockDriverCompletionFunc *cb, void *opaque)
 {
-    BlockDriverAIOCBSync *acb;
+    trace_bdrv_aio_flush(bs, opaque);
 
-    acb = qemu_aio_get(&bdrv_em_aio_pool, bs, cb, opaque);
-    acb->is_write = 1; /* don't bounce in the completion handler */
-    acb->qiov = NULL;
-    acb->bounce = NULL;
-    acb->ret = 0;
+    Coroutine *co;
+    BlockDriverAIOCBCoroutine *acb;
 
-    if (!acb->bh) {
-        acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb);
-    }
+    acb = qemu_aio_get(&bdrv_em_co_aio_pool, bs, cb, opaque);
+    co = qemu_coroutine_create(bdrv_aio_flush_co_entry);
+    qemu_coroutine_enter(co, acb);
 
-    qemu_bh_schedule(acb->bh);
     return &acb->common;
 }
 
@@ -2916,19 +2847,72 @@ static int coroutine_fn bdrv_co_writev_em(BlockDriverState *bs,
     return bdrv_co_io_em(bs, sector_num, nb_sectors, iov, true);
 }
 
-static int coroutine_fn bdrv_co_flush_em(BlockDriverState *bs)
+static void coroutine_fn bdrv_flush_co_entry(void *opaque)
 {
-    CoroutineIOCompletion co = {
-        .coroutine = qemu_coroutine_self(),
+    RwCo *rwco = opaque;
+
+    rwco->ret = bdrv_co_flush(rwco->bs);
+}
+
+int coroutine_fn bdrv_co_flush(BlockDriverState *bs)
+{
+    if (bs->open_flags & BDRV_O_NO_FLUSH) {
+        return 0;
+    } else if (!bs->drv) {
+        return 0;
+    } else if (bs->drv->bdrv_co_flush) {
+        return bs->drv->bdrv_co_flush(bs);
+    } else if (bs->drv->bdrv_aio_flush) {
+        BlockDriverAIOCB *acb;
+        CoroutineIOCompletion co = {
+            .coroutine = qemu_coroutine_self(),
+        };
+
+        acb = bs->drv->bdrv_aio_flush(bs, bdrv_co_io_em_complete, &co);
+        if (acb == NULL) {
+            return -EIO;
+        } else {
+            qemu_coroutine_yield();
+            return co.ret;
+        }
+    } else if (bs->drv->bdrv_flush) {
+        return bs->drv->bdrv_flush(bs);
+    } else {
+        /*
+         * Some block drivers always operate in either writethrough or unsafe
+         * mode and don't support bdrv_flush therefore. Usually qemu doesn't
+         * know how the server works (because the behaviour is hardcoded or
+         * depends on server-side configuration), so we can't ensure that
+         * everything is safe on disk. Returning an error doesn't work because
+         * that would break guests even if the server operates in writethrough
+         * mode.
+         *
+         * Let's hope the user knows what he's doing.
+         */
+        return 0;
+    }
+}
+
+int bdrv_flush(BlockDriverState *bs)
+{
+    Coroutine *co;
+    RwCo rwco = {
+        .bs = bs,
+        .ret = NOT_DONE,
     };
-    BlockDriverAIOCB *acb;
 
-    acb = bdrv_aio_flush(bs, bdrv_co_io_em_complete, &co);
-    if (!acb) {
-        return -EIO;
+    if (qemu_in_coroutine()) {
+        /* Fast-path if already in coroutine context */
+        bdrv_flush_co_entry(&rwco);
+    } else {
+        co = qemu_coroutine_create(bdrv_flush_co_entry);
+        qemu_coroutine_enter(co, &rwco);
+        while (rwco.ret == NOT_DONE) {
+            qemu_aio_wait();
+        }
     }
-    qemu_coroutine_yield();
-    return co.ret;
+
+    return rwco.ret;
 }
 
 /**************************************************************/
diff --git a/block.h b/block.h
index e77988e..65c5166 100644
--- a/block.h
+++ b/block.h
@@ -191,6 +191,7 @@ BlockDriverAIOCB *bdrv_aio_ioctl(BlockDriverState *bs,
 
 /* Ensure contents are flushed to disk.  */
 int bdrv_flush(BlockDriverState *bs);
+int coroutine_fn bdrv_co_flush(BlockDriverState *bs);
 void bdrv_flush_all(void);
 void bdrv_close_all(void);
 
diff --git a/block_int.h b/block_int.h
index f2f4f2d..9cb536d 100644
--- a/block_int.h
+++ b/block_int.h
@@ -83,6 +83,7 @@ struct BlockDriver {
         int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
     int coroutine_fn (*bdrv_co_writev)(BlockDriverState *bs,
         int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
+    int coroutine_fn (*bdrv_co_flush)(BlockDriverState *bs);
 
     int (*bdrv_aio_multiwrite)(BlockDriverState *bs, BlockRequest *reqs,
         int num_reqs);
-- 
1.7.6.4

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

* [Qemu-devel] [PATCH 07/19] block: drop redundant bdrv_flush implementation
  2011-10-21 17:18 [Qemu-devel] [PULL 00/19] Block patches Kevin Wolf
                   ` (5 preceding siblings ...)
  2011-10-21 17:19 ` [Qemu-devel] [PATCH 06/19] block: unify flush implementations Kevin Wolf
@ 2011-10-21 17:19 ` Kevin Wolf
  2011-10-21 17:19 ` [Qemu-devel] [PATCH 08/19] block: add bdrv_co_discard and bdrv_aio_discard support Kevin Wolf
                   ` (12 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Kevin Wolf @ 2011-10-21 17:19 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

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

Block drivers now only need to provide either of .bdrv_co_flush,
.bdrv_aio_flush() or for legacy drivers .bdrv_flush().  Remove
the redundant .bdrv_flush() implementations.

[Paolo Bonzini: change raw driver to bdrv_co_flush]

Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/blkdebug.c  |    6 ------
 block/blkverify.c |    9 ---------
 block/qcow.c      |    6 ------
 block/qcow2.c     |   19 -------------------
 block/qed.c       |    6 ------
 block/raw-posix.c |   18 ------------------
 block/raw.c       |   13 +++----------
 7 files changed, 3 insertions(+), 74 deletions(-)

diff --git a/block/blkdebug.c b/block/blkdebug.c
index b3c5d42..9b88535 100644
--- a/block/blkdebug.c
+++ b/block/blkdebug.c
@@ -397,11 +397,6 @@ static void blkdebug_close(BlockDriverState *bs)
     }
 }
 
-static int blkdebug_flush(BlockDriverState *bs)
-{
-    return bdrv_flush(bs->file);
-}
-
 static BlockDriverAIOCB *blkdebug_aio_flush(BlockDriverState *bs,
     BlockDriverCompletionFunc *cb, void *opaque)
 {
@@ -454,7 +449,6 @@ static BlockDriver bdrv_blkdebug = {
 
     .bdrv_file_open     = blkdebug_open,
     .bdrv_close         = blkdebug_close,
-    .bdrv_flush         = blkdebug_flush,
 
     .bdrv_aio_readv     = blkdebug_aio_readv,
     .bdrv_aio_writev    = blkdebug_aio_writev,
diff --git a/block/blkverify.c b/block/blkverify.c
index c7522b4..483f3b3 100644
--- a/block/blkverify.c
+++ b/block/blkverify.c
@@ -116,14 +116,6 @@ static void blkverify_close(BlockDriverState *bs)
     s->test_file = NULL;
 }
 
-static int blkverify_flush(BlockDriverState *bs)
-{
-    BDRVBlkverifyState *s = bs->opaque;
-
-    /* Only flush test file, the raw file is not important */
-    return bdrv_flush(s->test_file);
-}
-
 static int64_t blkverify_getlength(BlockDriverState *bs)
 {
     BDRVBlkverifyState *s = bs->opaque;
@@ -368,7 +360,6 @@ static BlockDriver bdrv_blkverify = {
 
     .bdrv_file_open     = blkverify_open,
     .bdrv_close         = blkverify_close,
-    .bdrv_flush         = blkverify_flush,
 
     .bdrv_aio_readv     = blkverify_aio_readv,
     .bdrv_aio_writev    = blkverify_aio_writev,
diff --git a/block/qcow.c b/block/qcow.c
index eba5a04..f93e3eb 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -781,11 +781,6 @@ static int qcow_write_compressed(BlockDriverState *bs, int64_t sector_num,
     return 0;
 }
 
-static int qcow_flush(BlockDriverState *bs)
-{
-    return bdrv_flush(bs->file);
-}
-
 static BlockDriverAIOCB *qcow_aio_flush(BlockDriverState *bs,
         BlockDriverCompletionFunc *cb, void *opaque)
 {
@@ -826,7 +821,6 @@ static BlockDriver bdrv_qcow = {
     .bdrv_open		= qcow_open,
     .bdrv_close		= qcow_close,
     .bdrv_create	= qcow_create,
-    .bdrv_flush		= qcow_flush,
     .bdrv_is_allocated	= qcow_is_allocated,
     .bdrv_set_key	= qcow_set_key,
     .bdrv_make_empty	= qcow_make_empty,
diff --git a/block/qcow2.c b/block/qcow2.c
index 510ff68..4dc980c 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1092,24 +1092,6 @@ static int qcow2_write_compressed(BlockDriverState *bs, int64_t sector_num,
     return 0;
 }
 
-static int qcow2_flush(BlockDriverState *bs)
-{
-    BDRVQcowState *s = bs->opaque;
-    int ret;
-
-    ret = qcow2_cache_flush(bs, s->l2_table_cache);
-    if (ret < 0) {
-        return ret;
-    }
-
-    ret = qcow2_cache_flush(bs, s->refcount_block_cache);
-    if (ret < 0) {
-        return ret;
-    }
-
-    return bdrv_flush(bs->file);
-}
-
 static BlockDriverAIOCB *qcow2_aio_flush(BlockDriverState *bs,
                                          BlockDriverCompletionFunc *cb,
                                          void *opaque)
@@ -1242,7 +1224,6 @@ static BlockDriver bdrv_qcow2 = {
     .bdrv_open          = qcow2_open,
     .bdrv_close         = qcow2_close,
     .bdrv_create        = qcow2_create,
-    .bdrv_flush         = qcow2_flush,
     .bdrv_is_allocated  = qcow2_is_allocated,
     .bdrv_set_key       = qcow2_set_key,
     .bdrv_make_empty    = qcow2_make_empty,
diff --git a/block/qed.c b/block/qed.c
index e87dc4d..2e06992 100644
--- a/block/qed.c
+++ b/block/qed.c
@@ -533,11 +533,6 @@ static void bdrv_qed_close(BlockDriverState *bs)
     qemu_vfree(s->l1_table);
 }
 
-static int bdrv_qed_flush(BlockDriverState *bs)
-{
-    return bdrv_flush(bs->file);
-}
-
 static int qed_create(const char *filename, uint32_t cluster_size,
                       uint64_t image_size, uint32_t table_size,
                       const char *backing_file, const char *backing_fmt)
@@ -1479,7 +1474,6 @@ static BlockDriver bdrv_qed = {
     .bdrv_open                = bdrv_qed_open,
     .bdrv_close               = bdrv_qed_close,
     .bdrv_create              = bdrv_qed_create,
-    .bdrv_flush               = bdrv_qed_flush,
     .bdrv_is_allocated        = bdrv_qed_is_allocated,
     .bdrv_make_empty          = bdrv_qed_make_empty,
     .bdrv_aio_readv           = bdrv_qed_aio_readv,
diff --git a/block/raw-posix.c b/block/raw-posix.c
index c7f5544..afcb4c1 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -583,19 +583,6 @@ static int raw_create(const char *filename, QEMUOptionParameter *options)
     return result;
 }
 
-static int raw_flush(BlockDriverState *bs)
-{
-    BDRVRawState *s = bs->opaque;
-    int ret;
-
-    ret = qemu_fdatasync(s->fd);
-    if (ret < 0) {
-        return -errno;
-    }
-
-    return 0;
-}
-
 #ifdef CONFIG_XFS
 static int xfs_discard(BDRVRawState *s, int64_t sector_num, int nb_sectors)
 {
@@ -645,7 +632,6 @@ static BlockDriver bdrv_file = {
     .bdrv_file_open = raw_open,
     .bdrv_close = raw_close,
     .bdrv_create = raw_create,
-    .bdrv_flush = raw_flush,
     .bdrv_discard = raw_discard,
 
     .bdrv_aio_readv = raw_aio_readv,
@@ -915,7 +901,6 @@ static BlockDriver bdrv_host_device = {
     .bdrv_create        = hdev_create,
     .create_options     = raw_create_options,
     .bdrv_has_zero_init = hdev_has_zero_init,
-    .bdrv_flush         = raw_flush,
 
     .bdrv_aio_readv	= raw_aio_readv,
     .bdrv_aio_writev	= raw_aio_writev,
@@ -1035,7 +1020,6 @@ static BlockDriver bdrv_host_floppy = {
     .bdrv_create        = hdev_create,
     .create_options     = raw_create_options,
     .bdrv_has_zero_init = hdev_has_zero_init,
-    .bdrv_flush         = raw_flush,
 
     .bdrv_aio_readv     = raw_aio_readv,
     .bdrv_aio_writev    = raw_aio_writev,
@@ -1135,7 +1119,6 @@ static BlockDriver bdrv_host_cdrom = {
     .bdrv_create        = hdev_create,
     .create_options     = raw_create_options,
     .bdrv_has_zero_init = hdev_has_zero_init,
-    .bdrv_flush         = raw_flush,
 
     .bdrv_aio_readv     = raw_aio_readv,
     .bdrv_aio_writev    = raw_aio_writev,
@@ -1255,7 +1238,6 @@ static BlockDriver bdrv_host_cdrom = {
     .bdrv_create        = hdev_create,
     .create_options     = raw_create_options,
     .bdrv_has_zero_init = hdev_has_zero_init,
-    .bdrv_flush         = raw_flush,
 
     .bdrv_aio_readv     = raw_aio_readv,
     .bdrv_aio_writev    = raw_aio_writev,
diff --git a/block/raw.c b/block/raw.c
index 5ca606b..39a3a9a 100644
--- a/block/raw.c
+++ b/block/raw.c
@@ -25,15 +25,9 @@ static void raw_close(BlockDriverState *bs)
 {
 }
 
-static int raw_flush(BlockDriverState *bs)
+static int coroutine_fn raw_co_flush(BlockDriverState *bs)
 {
-    return bdrv_flush(bs->file);
-}
-
-static BlockDriverAIOCB *raw_aio_flush(BlockDriverState *bs,
-    BlockDriverCompletionFunc *cb, void *opaque)
-{
-    return bdrv_aio_flush(bs->file, cb, opaque);
+    return bdrv_co_flush(bs->file);
 }
 
 static int64_t raw_getlength(BlockDriverState *bs)
@@ -117,12 +111,11 @@ static BlockDriver bdrv_raw = {
     .bdrv_close         = raw_close,
     .bdrv_co_readv      = raw_co_readv,
     .bdrv_co_writev     = raw_co_writev,
-    .bdrv_flush         = raw_flush,
+    .bdrv_co_flush      = raw_co_flush,
     .bdrv_probe         = raw_probe,
     .bdrv_getlength     = raw_getlength,
     .bdrv_truncate      = raw_truncate,
 
-    .bdrv_aio_flush     = raw_aio_flush,
     .bdrv_discard       = raw_discard,
 
     .bdrv_is_inserted   = raw_is_inserted,
-- 
1.7.6.4

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

* [Qemu-devel] [PATCH 08/19] block: add bdrv_co_discard and bdrv_aio_discard support
  2011-10-21 17:18 [Qemu-devel] [PULL 00/19] Block patches Kevin Wolf
                   ` (6 preceding siblings ...)
  2011-10-21 17:19 ` [Qemu-devel] [PATCH 07/19] block: drop redundant bdrv_flush implementation Kevin Wolf
@ 2011-10-21 17:19 ` Kevin Wolf
  2011-10-21 17:19 ` [Qemu-devel] [PATCH 09/19] fdc: Fix floppy port I/O Kevin Wolf
                   ` (11 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Kevin Wolf @ 2011-10-21 17:19 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Paolo Bonzini <pbonzini@redhat.com>

This similarly adds support for coroutine and asynchronous discard.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block.c      |  102 +++++++++++++++++++++++++++++++++++++++++++++++++++------
 block.h      |    4 ++
 block/raw.c  |   10 +++--
 block_int.h  |    9 ++++-
 trace-events |    1 +
 5 files changed, 109 insertions(+), 17 deletions(-)

diff --git a/block.c b/block.c
index 7b8b14d..28508f2 100644
--- a/block.c
+++ b/block.c
@@ -1768,17 +1768,6 @@ int bdrv_has_zero_init(BlockDriverState *bs)
     return 1;
 }
 
-int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors)
-{
-    if (!bs->drv) {
-        return -ENOMEDIUM;
-    }
-    if (!bs->drv->bdrv_discard) {
-        return 0;
-    }
-    return bs->drv->bdrv_discard(bs, sector_num, nb_sectors);
-}
-
 /*
  * Returns true iff the specified sector is present in the disk image. Drivers
  * not implementing the functionality are assumed to not support backing files,
@@ -2754,6 +2743,34 @@ BlockDriverAIOCB *bdrv_aio_flush(BlockDriverState *bs,
     return &acb->common;
 }
 
+static void coroutine_fn bdrv_aio_discard_co_entry(void *opaque)
+{
+    BlockDriverAIOCBCoroutine *acb = opaque;
+    BlockDriverState *bs = acb->common.bs;
+
+    acb->req.error = bdrv_co_discard(bs, acb->req.sector, acb->req.nb_sectors);
+    acb->bh = qemu_bh_new(bdrv_co_em_bh, acb);
+    qemu_bh_schedule(acb->bh);
+}
+
+BlockDriverAIOCB *bdrv_aio_discard(BlockDriverState *bs,
+        int64_t sector_num, int nb_sectors,
+        BlockDriverCompletionFunc *cb, void *opaque)
+{
+    Coroutine *co;
+    BlockDriverAIOCBCoroutine *acb;
+
+    trace_bdrv_aio_discard(bs, sector_num, nb_sectors, opaque);
+
+    acb = qemu_aio_get(&bdrv_em_co_aio_pool, bs, cb, opaque);
+    acb->req.sector = sector_num;
+    acb->req.nb_sectors = nb_sectors;
+    co = qemu_coroutine_create(bdrv_aio_discard_co_entry);
+    qemu_coroutine_enter(co, acb);
+
+    return &acb->common;
+}
+
 void bdrv_init(void)
 {
     module_call_init(MODULE_INIT_BLOCK);
@@ -2915,6 +2932,69 @@ int bdrv_flush(BlockDriverState *bs)
     return rwco.ret;
 }
 
+static void coroutine_fn bdrv_discard_co_entry(void *opaque)
+{
+    RwCo *rwco = opaque;
+
+    rwco->ret = bdrv_co_discard(rwco->bs, rwco->sector_num, rwco->nb_sectors);
+}
+
+int coroutine_fn bdrv_co_discard(BlockDriverState *bs, int64_t sector_num,
+                                 int nb_sectors)
+{
+    if (!bs->drv) {
+        return -ENOMEDIUM;
+    } else if (bdrv_check_request(bs, sector_num, nb_sectors)) {
+        return -EIO;
+    } else if (bs->read_only) {
+        return -EROFS;
+    } else if (bs->drv->bdrv_co_discard) {
+        return bs->drv->bdrv_co_discard(bs, sector_num, nb_sectors);
+    } else if (bs->drv->bdrv_aio_discard) {
+        BlockDriverAIOCB *acb;
+        CoroutineIOCompletion co = {
+            .coroutine = qemu_coroutine_self(),
+        };
+
+        acb = bs->drv->bdrv_aio_discard(bs, sector_num, nb_sectors,
+                                        bdrv_co_io_em_complete, &co);
+        if (acb == NULL) {
+            return -EIO;
+        } else {
+            qemu_coroutine_yield();
+            return co.ret;
+        }
+    } else if (bs->drv->bdrv_discard) {
+        return bs->drv->bdrv_discard(bs, sector_num, nb_sectors);
+    } else {
+        return 0;
+    }
+}
+
+int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors)
+{
+    Coroutine *co;
+    RwCo rwco = {
+        .bs = bs,
+        .sector_num = sector_num,
+        .nb_sectors = nb_sectors,
+        .ret = NOT_DONE,
+    };
+
+    if (qemu_in_coroutine()) {
+        /* Fast-path if already in coroutine context */
+        bdrv_discard_co_entry(&rwco);
+    } else {
+        co = qemu_coroutine_create(bdrv_discard_co_entry);
+        qemu_coroutine_enter(co, &rwco);
+        while (rwco.ret == NOT_DONE) {
+            qemu_aio_wait();
+        }
+    }
+
+    return rwco.ret;
+}
+
 /**************************************************************/
 /* removable device support */
 
diff --git a/block.h b/block.h
index 65c5166..5a042c9 100644
--- a/block.h
+++ b/block.h
@@ -166,6 +166,9 @@ BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num,
                                   BlockDriverCompletionFunc *cb, void *opaque);
 BlockDriverAIOCB *bdrv_aio_flush(BlockDriverState *bs,
                                  BlockDriverCompletionFunc *cb, void *opaque);
+BlockDriverAIOCB *bdrv_aio_discard(BlockDriverState *bs,
+                                   int64_t sector_num, int nb_sectors,
+                                   BlockDriverCompletionFunc *cb, void *opaque);
 void bdrv_aio_cancel(BlockDriverAIOCB *acb);
 
 typedef struct BlockRequest {
@@ -196,6 +199,7 @@ void bdrv_flush_all(void);
 void bdrv_close_all(void);
 
 int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors);
+int bdrv_co_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors);
 int bdrv_has_zero_init(BlockDriverState *bs);
 int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
                       int *pnum);
diff --git a/block/raw.c b/block/raw.c
index 39a3a9a..33cc471 100644
--- a/block/raw.c
+++ b/block/raw.c
@@ -45,9 +45,10 @@ static int raw_probe(const uint8_t *buf, int buf_size, const char *filename)
    return 1; /* everything can be opened as raw image */
 }
 
-static int raw_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors)
+static int coroutine_fn raw_co_discard(BlockDriverState *bs,
+                                       int64_t sector_num, int nb_sectors)
 {
-    return bdrv_discard(bs->file, sector_num, nb_sectors);
+    return bdrv_co_discard(bs->file, sector_num, nb_sectors);
 }
 
 static int raw_is_inserted(BlockDriverState *bs)
@@ -109,15 +110,16 @@ static BlockDriver bdrv_raw = {
 
     .bdrv_open          = raw_open,
     .bdrv_close         = raw_close,
+
     .bdrv_co_readv      = raw_co_readv,
     .bdrv_co_writev     = raw_co_writev,
     .bdrv_co_flush      = raw_co_flush,
+    .bdrv_co_discard    = raw_co_discard,
+
     .bdrv_probe         = raw_probe,
     .bdrv_getlength     = raw_getlength,
     .bdrv_truncate      = raw_truncate,
 
-    .bdrv_discard       = raw_discard,
-
     .bdrv_is_inserted   = raw_is_inserted,
     .bdrv_media_changed = raw_media_changed,
     .bdrv_eject         = raw_eject,
diff --git a/block_int.h b/block_int.h
index 9cb536d..384598f 100644
--- a/block_int.h
+++ b/block_int.h
@@ -63,6 +63,8 @@ struct BlockDriver {
     void (*bdrv_close)(BlockDriverState *bs);
     int (*bdrv_create)(const char *filename, QEMUOptionParameter *options);
     int (*bdrv_flush)(BlockDriverState *bs);
+    int (*bdrv_discard)(BlockDriverState *bs, int64_t sector_num,
+                        int nb_sectors);
     int (*bdrv_is_allocated)(BlockDriverState *bs, int64_t sector_num,
                              int nb_sectors, int *pnum);
     int (*bdrv_set_key)(BlockDriverState *bs, const char *key);
@@ -76,14 +78,17 @@ struct BlockDriver {
         BlockDriverCompletionFunc *cb, void *opaque);
     BlockDriverAIOCB *(*bdrv_aio_flush)(BlockDriverState *bs,
         BlockDriverCompletionFunc *cb, void *opaque);
-    int (*bdrv_discard)(BlockDriverState *bs, int64_t sector_num,
-                        int nb_sectors);
+    BlockDriverAIOCB *(*bdrv_aio_discard)(BlockDriverState *bs,
+        int64_t sector_num, int nb_sectors,
+        BlockDriverCompletionFunc *cb, void *opaque);
 
     int coroutine_fn (*bdrv_co_readv)(BlockDriverState *bs,
         int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
     int coroutine_fn (*bdrv_co_writev)(BlockDriverState *bs,
         int64_t sector_num, int nb_sectors, QEMUIOVector *qiov);
     int coroutine_fn (*bdrv_co_flush)(BlockDriverState *bs);
+    int coroutine_fn (*bdrv_co_discard)(BlockDriverState *bs,
+        int64_t sector_num, int nb_sectors);
 
     int (*bdrv_aio_multiwrite)(BlockDriverState *bs, BlockRequest *reqs,
         int num_reqs);
diff --git a/trace-events b/trace-events
index 7f9cec4..49ac1c1 100644
--- a/trace-events
+++ b/trace-events
@@ -61,6 +61,7 @@ multiwrite_cb(void *mcb, int ret) "mcb %p ret %d"
 bdrv_aio_multiwrite(void *mcb, int num_callbacks, int num_reqs) "mcb %p num_callbacks %d num_reqs %d"
 bdrv_aio_multiwrite_earlyfail(void *mcb) "mcb %p"
 bdrv_aio_multiwrite_latefail(void *mcb, int i) "mcb %p i %d"
+bdrv_aio_discard(void *bs, int64_t sector_num, int nb_sectors, void *opaque) "bs %p sector_num %"PRId64" nb_sectors %d opaque %p"
 bdrv_aio_flush(void *bs, void *opaque) "bs %p opaque %p"
 bdrv_aio_readv(void *bs, int64_t sector_num, int nb_sectors, void *opaque) "bs %p sector_num %"PRId64" nb_sectors %d opaque %p"
 bdrv_aio_writev(void *bs, int64_t sector_num, int nb_sectors, void *opaque) "bs %p sector_num %"PRId64" nb_sectors %d opaque %p"
-- 
1.7.6.4

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

* [Qemu-devel] [PATCH 09/19] fdc: Fix floppy port I/O
  2011-10-21 17:18 [Qemu-devel] [PULL 00/19] Block patches Kevin Wolf
                   ` (7 preceding siblings ...)
  2011-10-21 17:19 ` [Qemu-devel] [PATCH 08/19] block: add bdrv_co_discard and bdrv_aio_discard support Kevin Wolf
@ 2011-10-21 17:19 ` Kevin Wolf
  2011-10-21 17:19 ` [Qemu-devel] [PATCH 10/19] qemu-img: Don't allow preallocation and compression at the same time Kevin Wolf
                   ` (10 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Kevin Wolf @ 2011-10-21 17:19 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

The floppy device was broken by commit 212ec7ba (fdc: Convert to
isa_register_portio_list). While the old interface provided the port number
relative to the floppy drive's io_base, the new one provides the real port
number, so we need to apply a bitmask now to get the register number.

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

diff --git a/hw/fdc.c b/hw/fdc.c
index 4b06e04..f8af2de 100644
--- a/hw/fdc.c
+++ b/hw/fdc.c
@@ -434,6 +434,7 @@ static uint32_t fdctrl_read (void *opaque, uint32_t reg)
     FDCtrl *fdctrl = opaque;
     uint32_t retval;
 
+    reg &= 7;
     switch (reg) {
     case FD_REG_SRA:
         retval = fdctrl_read_statusA(fdctrl);
@@ -471,6 +472,7 @@ static void fdctrl_write (void *opaque, uint32_t reg, uint32_t value)
 
     FLOPPY_DPRINTF("write reg%d: 0x%02x\n", reg & 7, value);
 
+    reg &= 7;
     switch (reg) {
     case FD_REG_DOR:
         fdctrl_write_dor(fdctrl, value);
-- 
1.7.6.4

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

* [Qemu-devel] [PATCH 10/19] qemu-img: Don't allow preallocation and compression at the same time
  2011-10-21 17:18 [Qemu-devel] [PULL 00/19] Block patches Kevin Wolf
                   ` (8 preceding siblings ...)
  2011-10-21 17:19 ` [Qemu-devel] [PATCH 09/19] fdc: Fix floppy port I/O Kevin Wolf
@ 2011-10-21 17:19 ` Kevin Wolf
  2011-10-21 17:19 ` [Qemu-devel] [PATCH 11/19] qcow2: Fix bdrv_write_compressed error handling Kevin Wolf
                   ` (9 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Kevin Wolf @ 2011-10-21 17:19 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

Only qcow and qcow2 can do compression at all, and they require unallocated
clusters when writing the compressed data.

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

diff --git a/qemu-img.c b/qemu-img.c
index 6a39731..86127f0 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -824,6 +824,8 @@ static int img_convert(int argc, char **argv)
     if (compress) {
         QEMUOptionParameter *encryption =
             get_option_parameter(param, BLOCK_OPT_ENCRYPT);
+        QEMUOptionParameter *preallocation =
+            get_option_parameter(param, BLOCK_OPT_PREALLOC);
 
         if (!drv->bdrv_write_compressed) {
             error_report("Compression not supported for this file format");
@@ -837,6 +839,15 @@ static int img_convert(int argc, char **argv)
             ret = -1;
             goto out;
         }
+
+        if (preallocation && preallocation->value.s
+            && strcmp(preallocation->value.s, "off"))
+        {
+            error_report("Compression and preallocation not supported at "
+                         "the same time");
+            ret = -1;
+            goto out;
+        }
     }
 
     /* Create the new image */
-- 
1.7.6.4

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

* [Qemu-devel] [PATCH 11/19] qcow2: Fix bdrv_write_compressed error handling
  2011-10-21 17:18 [Qemu-devel] [PULL 00/19] Block patches Kevin Wolf
                   ` (9 preceding siblings ...)
  2011-10-21 17:19 ` [Qemu-devel] [PATCH 10/19] qemu-img: Don't allow preallocation and compression at the same time Kevin Wolf
@ 2011-10-21 17:19 ` Kevin Wolf
  2011-10-21 17:19 ` [Qemu-devel] [PATCH 12/19] pc: Fix floppy drives with if=none Kevin Wolf
                   ` (8 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Kevin Wolf @ 2011-10-21 17:19 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

If during allocation of compressed clusters the cluster was already allocated
uncompressed, fail and properly release the l2_table (the latter avoids a
failed assertion).

While at it, make it return some real error numbers instead of -1.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Dong Xu Wang <wdongxu@linux.vnet.ibm.com>
---
 block/qcow2-cluster.c |    6 ++++--
 block/qcow2.c         |   29 ++++++++++++++++++-----------
 2 files changed, 22 insertions(+), 13 deletions(-)

diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index 2f76311..f4e049f 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -568,8 +568,10 @@ uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
     }
 
     cluster_offset = be64_to_cpu(l2_table[l2_index]);
-    if (cluster_offset & QCOW_OFLAG_COPIED)
-        return cluster_offset & ~QCOW_OFLAG_COPIED;
+    if (cluster_offset & QCOW_OFLAG_COPIED) {
+        qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table);
+        return 0;
+    }
 
     if (cluster_offset)
         qcow2_free_any_clusters(bs, cluster_offset, 1);
diff --git a/block/qcow2.c b/block/qcow2.c
index 4dc980c..91f4f04 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1053,8 +1053,8 @@ static int qcow2_write_compressed(BlockDriverState *bs, int64_t sector_num,
                        Z_DEFLATED, -12,
                        9, Z_DEFAULT_STRATEGY);
     if (ret != 0) {
-        g_free(out_buf);
-        return -1;
+        ret = -EINVAL;
+        goto fail;
     }
 
     strm.avail_in = s->cluster_size;
@@ -1064,9 +1064,9 @@ static int qcow2_write_compressed(BlockDriverState *bs, int64_t sector_num,
 
     ret = deflate(&strm, Z_FINISH);
     if (ret != Z_STREAM_END && ret != Z_OK) {
-        g_free(out_buf);
         deflateEnd(&strm);
-        return -1;
+        ret = -EINVAL;
+        goto fail;
     }
     out_len = strm.next_out - out_buf;
 
@@ -1074,22 +1074,29 @@ static int qcow2_write_compressed(BlockDriverState *bs, int64_t sector_num,
 
     if (ret != Z_STREAM_END || out_len >= s->cluster_size) {
         /* could not compress: write normal cluster */
-        bdrv_write(bs, sector_num, buf, s->cluster_sectors);
+        ret = bdrv_write(bs, sector_num, buf, s->cluster_sectors);
+        if (ret < 0) {
+            goto fail;
+        }
     } else {
         cluster_offset = qcow2_alloc_compressed_cluster_offset(bs,
             sector_num << 9, out_len);
-        if (!cluster_offset)
-            return -1;
+        if (!cluster_offset) {
+            ret = -EIO;
+            goto fail;
+        }
         cluster_offset &= s->cluster_offset_mask;
         BLKDBG_EVENT(bs->file, BLKDBG_WRITE_COMPRESSED);
-        if (bdrv_pwrite(bs->file, cluster_offset, out_buf, out_len) != out_len) {
-            g_free(out_buf);
-            return -1;
+        ret = bdrv_pwrite(bs->file, cluster_offset, out_buf, out_len);
+        if (ret < 0) {
+            goto fail;
         }
     }
 
+    ret = 0;
+fail:
     g_free(out_buf);
-    return 0;
+    return ret;
 }
 
 static BlockDriverAIOCB *qcow2_aio_flush(BlockDriverState *bs,
-- 
1.7.6.4

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

* [Qemu-devel] [PATCH 12/19] pc: Fix floppy drives with if=none
  2011-10-21 17:18 [Qemu-devel] [PULL 00/19] Block patches Kevin Wolf
                   ` (10 preceding siblings ...)
  2011-10-21 17:19 ` [Qemu-devel] [PATCH 11/19] qcow2: Fix bdrv_write_compressed error handling Kevin Wolf
@ 2011-10-21 17:19 ` Kevin Wolf
  2011-10-21 17:19 ` [Qemu-devel] [PATCH 13/19] vmdk: fix return values of vmdk_parent_open Kevin Wolf
                   ` (7 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Kevin Wolf @ 2011-10-21 17:19 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

Commit 63ffb564 broke floppy devices specified on the command line like
-drive file=...,if=none,id=floppy -global isa-fdc.driveA=floppy because it
relies on drive_get() which works only with -fda/-drive if=floppy.

This patch resembles what we're already doing for IDE, i.e. remember the floppy
device that was created and use that to extract the BlockDriverStates where
needed.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
---
 hw/fdc.c     |   12 ++++++++++++
 hw/fdc.h     |    9 +++++++--
 hw/pc.c      |   25 ++++++++++++++-----------
 hw/pc.h      |    3 ++-
 hw/pc_piix.c |    5 +++--
 5 files changed, 38 insertions(+), 16 deletions(-)

diff --git a/hw/fdc.c b/hw/fdc.c
index f8af2de..ecaad09 100644
--- a/hw/fdc.c
+++ b/hw/fdc.c
@@ -1947,6 +1947,18 @@ static int sun4m_fdc_init1(SysBusDevice *dev)
     return fdctrl_init_common(fdctrl);
 }
 
+void fdc_get_bs(BlockDriverState *bs[], ISADevice *dev)
+{
+    FDCtrlISABus *isa = DO_UPCAST(FDCtrlISABus, busdev, dev);
+    FDCtrl *fdctrl = &isa->state;
+    int i;
+
+    for (i = 0; i < MAX_FD; i++) {
+        bs[i] = fdctrl->drives[i].bs;
+    }
+}
+
+
 static const VMStateDescription vmstate_isa_fdc ={
     .name = "fdc",
     .version_id = 2,
diff --git a/hw/fdc.h b/hw/fdc.h
index 09f73c6..506feb6 100644
--- a/hw/fdc.h
+++ b/hw/fdc.h
@@ -7,14 +7,15 @@
 /* fdc.c */
 #define MAX_FD 2
 
-static inline void fdctrl_init_isa(DriveInfo **fds)
+static inline ISADevice *fdctrl_init_isa(DriveInfo **fds)
 {
     ISADevice *dev;
 
     dev = isa_try_create("isa-fdc");
     if (!dev) {
-        return;
+        return NULL;
     }
+
     if (fds[0]) {
         qdev_prop_set_drive_nofail(&dev->qdev, "driveA", fds[0]->bdrv);
     }
@@ -22,10 +23,14 @@ static inline void fdctrl_init_isa(DriveInfo **fds)
         qdev_prop_set_drive_nofail(&dev->qdev, "driveB", fds[1]->bdrv);
     }
     qdev_init_nofail(&dev->qdev);
+
+    return dev;
 }
 
 void fdctrl_init_sysbus(qemu_irq irq, int dma_chann,
                         target_phys_addr_t mmio_base, DriveInfo **fds);
 void sun4m_fdctrl_init(qemu_irq irq, target_phys_addr_t io_base,
                        DriveInfo **fds, qemu_irq *fdc_tc);
+void fdc_get_bs(BlockDriverState *bs[], ISADevice *dev);
+
 #endif
diff --git a/hw/pc.c b/hw/pc.c
index f0802b7..eb4c2d8 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -331,12 +331,12 @@ static void pc_cmos_init_late(void *opaque)
 
 void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size,
                   const char *boot_device,
-                  BusState *idebus0, BusState *idebus1,
+                  ISADevice *floppy, BusState *idebus0, BusState *idebus1,
                   ISADevice *s)
 {
     int val, nb, nb_heads, max_track, last_sect, i;
     FDriveType fd_type[2];
-    DriveInfo *fd[2];
+    BlockDriverState *fd[MAX_FD];
     static pc_cmos_init_late_arg arg;
 
     /* various important CMOS locations needed by PC/Bochs bios */
@@ -378,14 +378,16 @@ void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size,
     }
 
     /* floppy type */
-    for (i = 0; i < 2; i++) {
-        fd[i] = drive_get(IF_FLOPPY, 0, i);
-        if (fd[i] && bdrv_is_inserted(fd[i]->bdrv)) {
-            bdrv_get_floppy_geometry_hint(fd[i]->bdrv, &nb_heads, &max_track,
-                                          &last_sect, FDRIVE_DRV_NONE,
-                                          &fd_type[i]);
-        } else {
-            fd_type[i] = FDRIVE_DRV_NONE;
+    if (floppy) {
+        fdc_get_bs(fd, floppy);
+        for (i = 0; i < 2; i++) {
+            if (fd[i] && bdrv_is_inserted(fd[i])) {
+                bdrv_get_floppy_geometry_hint(fd[i], &nb_heads, &max_track,
+                                              &last_sect, FDRIVE_DRV_NONE,
+                                              &fd_type[i]);
+            } else {
+                fd_type[i] = FDRIVE_DRV_NONE;
+            }
         }
     }
     val = (cmos_get_fd_drive_type(fd_type[0]) << 4) |
@@ -1124,6 +1126,7 @@ static void cpu_request_exit(void *opaque, int irq, int level)
 
 void pc_basic_device_init(qemu_irq *gsi,
                           ISADevice **rtc_state,
+                          ISADevice **floppy,
                           bool no_vmport)
 {
     int i;
@@ -1188,7 +1191,7 @@ void pc_basic_device_init(qemu_irq *gsi,
     for(i = 0; i < MAX_FD; i++) {
         fd[i] = drive_get(IF_FLOPPY, 0, i);
     }
-    fdctrl_init_isa(fd);
+    *floppy = fdctrl_init_isa(fd);
 }
 
 void pc_pci_device_init(PCIBus *pci_bus)
diff --git a/hw/pc.h b/hw/pc.h
index b8ad9a3..4515006 100644
--- a/hw/pc.h
+++ b/hw/pc.h
@@ -142,11 +142,12 @@ qemu_irq *pc_allocate_cpu_irq(void);
 void pc_vga_init(PCIBus *pci_bus);
 void pc_basic_device_init(qemu_irq *gsi,
                           ISADevice **rtc_state,
+                          ISADevice **floppy,
                           bool no_vmport);
 void pc_init_ne2k_isa(NICInfo *nd);
 void pc_cmos_init(ram_addr_t ram_size, ram_addr_t above_4g_mem_size,
                   const char *boot_device,
-                  BusState *ide0, BusState *ide1,
+                  ISADevice *floppy, BusState *ide0, BusState *ide1,
                   ISADevice *s);
 void pc_pci_device_init(PCIBus *pci_bus);
 
diff --git a/hw/pc_piix.c b/hw/pc_piix.c
index c89042f..8c7f2b7 100644
--- a/hw/pc_piix.c
+++ b/hw/pc_piix.c
@@ -95,6 +95,7 @@ static void pc_init1(MemoryRegion *system_memory,
     DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
     BusState *idebus[MAX_IDE_BUS];
     ISADevice *rtc_state;
+    ISADevice *floppy;
     MemoryRegion *ram_memory;
     MemoryRegion *pci_memory;
     MemoryRegion *rom_memory;
@@ -174,7 +175,7 @@ static void pc_init1(MemoryRegion *system_memory,
     }
 
     /* init basic PC hardware */
-    pc_basic_device_init(gsi, &rtc_state, xen_enabled());
+    pc_basic_device_init(gsi, &rtc_state, &floppy, xen_enabled());
 
     for(i = 0; i < nb_nics; i++) {
         NICInfo *nd = &nd_table[i];
@@ -207,7 +208,7 @@ static void pc_init1(MemoryRegion *system_memory,
     audio_init(gsi, pci_enabled ? pci_bus : NULL);
 
     pc_cmos_init(below_4g_mem_size, above_4g_mem_size, boot_device,
-                 idebus[0], idebus[1], rtc_state);
+                 floppy, idebus[0], idebus[1], rtc_state);
 
     if (pci_enabled && usb_enabled) {
         usb_uhci_piix3_init(pci_bus, piix3_devfn + 2);
-- 
1.7.6.4

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

* [Qemu-devel] [PATCH 13/19] vmdk: fix return values of vmdk_parent_open
  2011-10-21 17:18 [Qemu-devel] [PULL 00/19] Block patches Kevin Wolf
                   ` (11 preceding siblings ...)
  2011-10-21 17:19 ` [Qemu-devel] [PATCH 12/19] pc: Fix floppy drives with if=none Kevin Wolf
@ 2011-10-21 17:19 ` Kevin Wolf
  2011-10-21 17:19 ` [Qemu-devel] [PATCH 14/19] vmdk: clean up open Kevin Wolf
                   ` (6 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Kevin Wolf @ 2011-10-21 17:19 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Paolo Bonzini <pbonzini@redhat.com>

While vmdk_open_desc_file (touched by the patch) correctly changed -1
to -EINVAL, vmdk_open did not.  Fix it directly in vmdk_parent_open.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/vmdk.c |   15 +++++++++------
 1 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/block/vmdk.c b/block/vmdk.c
index 5d16ec4..ea00938 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -283,10 +283,12 @@ static int vmdk_parent_open(BlockDriverState *bs)
     char *p_name;
     char desc[DESC_SIZE + 1];
     BDRVVmdkState *s = bs->opaque;
+    int ret;
 
     desc[DESC_SIZE] = '\0';
-    if (bdrv_pread(bs->file, s->desc_offset, desc, DESC_SIZE) != DESC_SIZE) {
-        return -1;
+    ret = bdrv_pread(bs->file, s->desc_offset, desc, DESC_SIZE);
+    if (ret < 0) {
+        return ret;
     }
 
     p_name = strstr(desc, "parentFileNameHint");
@@ -296,10 +298,10 @@ static int vmdk_parent_open(BlockDriverState *bs)
         p_name += sizeof("parentFileNameHint") + 1;
         end_name = strchr(p_name, '\"');
         if (end_name == NULL) {
-            return -1;
+            return -EINVAL;
         }
         if ((end_name - p_name) > sizeof(bs->backing_file) - 1) {
-            return -1;
+            return -EINVAL;
         }
 
         pstrcpy(bs->backing_file, end_name - p_name + 1, p_name);
@@ -629,9 +631,10 @@ static int vmdk_open_desc_file(BlockDriverState *bs, int flags,
     }
 
     /* try to open parent images, if exist */
-    if (vmdk_parent_open(bs)) {
+    ret = vmdk_parent_open(bs);
+    if (ret) {
         vmdk_free_extents(bs);
-        return -EINVAL;
+        return ret;
     }
     s->parent_cid = vmdk_read_cid(bs, 1);
     return 0;
-- 
1.7.6.4

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

* [Qemu-devel] [PATCH 14/19] vmdk: clean up open
  2011-10-21 17:18 [Qemu-devel] [PULL 00/19] Block patches Kevin Wolf
                   ` (12 preceding siblings ...)
  2011-10-21 17:19 ` [Qemu-devel] [PATCH 13/19] vmdk: fix return values of vmdk_parent_open Kevin Wolf
@ 2011-10-21 17:19 ` Kevin Wolf
  2011-10-21 17:19 ` [Qemu-devel] [PATCH 15/19] block: add a CoMutex to synchronous read drivers Kevin Wolf
                   ` (5 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Kevin Wolf @ 2011-10-21 17:19 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Paolo Bonzini <pbonzini@redhat.com>

Move vmdk_parent_open to vmdk_open.  There's another path how
vmdk_parent_open can be reached:

  vmdk_parse_extents() ->  vmdk_open_sparse() ->  vmdk_open_vmdk4() ->
  vmdk_open_desc_file().

If that can happen, however, the code is bogus.  vmdk_parent_open
reads from bs->file:

    if (bdrv_pread(bs->file, s->desc_offset, desc, DESC_SIZE) != DESC_SIZE) {

but it is always called with s->desc_offset == 0 and with the same
bs->file.  So the data that vmdk_parent_open reads comes always from the
same place, and anyway there is only one place where it can write it,
namely bs->backing_file.

So, if it cannot happen, the patched code is okay.

It is also possible that the recursive call can happen, but only once.  In
that case there would still be a bug in vmdk_open_desc_file setting
s->desc_offset = 0, but the patched code is okay.

Finally, in the case where multiple recursive calls can happen the code
would need to be rewritten anyway.  It is likely that this would anyway
involve adding several parameters to vmdk_parent_open, and calling it from
vmdk_open_vmdk4.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/vmdk.c |   37 +++++++++++++++----------------------
 1 files changed, 15 insertions(+), 22 deletions(-)

diff --git a/block/vmdk.c b/block/vmdk.c
index ea00938..ace2977 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -624,20 +624,7 @@ static int vmdk_open_desc_file(BlockDriverState *bs, int flags,
         return -ENOTSUP;
     }
     s->desc_offset = 0;
-    ret = vmdk_parse_extents(buf, bs, bs->file->filename);
-    if (ret) {
-        vmdk_free_extents(bs);
-        return ret;
-    }
-
-    /* try to open parent images, if exist */
-    ret = vmdk_parent_open(bs);
-    if (ret) {
-        vmdk_free_extents(bs);
-        return ret;
-    }
-    s->parent_cid = vmdk_read_cid(bs, 1);
-    return 0;
+    return vmdk_parse_extents(buf, bs, bs->file->filename);
 }
 
 static int vmdk_open(BlockDriverState *bs, int flags)
@@ -647,17 +634,23 @@ static int vmdk_open(BlockDriverState *bs, int flags)
 
     if (vmdk_open_sparse(bs, bs->file, flags) == 0) {
         s->desc_offset = 0x200;
-        /* try to open parent images, if exist */
-        ret = vmdk_parent_open(bs);
+    } else {
+        ret = vmdk_open_desc_file(bs, flags, 0);
         if (ret) {
-            vmdk_free_extents(bs);
-            return ret;
+            goto fail;
         }
-        s->parent_cid = vmdk_read_cid(bs, 1);
-        return 0;
-    } else {
-        return vmdk_open_desc_file(bs, flags, 0);
     }
+    /* try to open parent images, if exist */
+    ret = vmdk_parent_open(bs);
+    if (ret) {
+        goto fail;
+    }
+    s->parent_cid = vmdk_read_cid(bs, 1);
+    return ret;
+
+fail:
+    vmdk_free_extents(bs);
+    return ret;
 }
 
 static int get_whole_cluster(BlockDriverState *bs,
-- 
1.7.6.4

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

* [Qemu-devel] [PATCH 15/19] block: add a CoMutex to synchronous read drivers
  2011-10-21 17:18 [Qemu-devel] [PULL 00/19] Block patches Kevin Wolf
                   ` (13 preceding siblings ...)
  2011-10-21 17:19 ` [Qemu-devel] [PATCH 14/19] vmdk: clean up open Kevin Wolf
@ 2011-10-21 17:19 ` Kevin Wolf
  2011-10-21 17:19 ` [Qemu-devel] [PATCH 16/19] block: take lock around bdrv_read implementations Kevin Wolf
                   ` (4 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Kevin Wolf @ 2011-10-21 17:19 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Paolo Bonzini <pbonzini@redhat.com>

The big conversion of bdrv_read/write to coroutines caused the two
homonymous callbacks in BlockDriver to become reentrant.  It goes
like this:

1) bdrv_read is now called in a coroutine, and calls bdrv_read or
bdrv_pread.

2) the nested bdrv_read goes through the fast path in bdrv_rw_co_entry;

3) in the common case when the protocol is file, bdrv_co_do_readv calls
bdrv_co_readv_em (and from here goes to bdrv_co_io_em), which yields
until the AIO operation is complete;

4) if bdrv_read had been called from a bottom half, the main loop
is free to iterate again: a device model or another bottom half
can then come and call bdrv_read again.

This applies to all four of read/write/flush/discard.  It would also
apply to is_allocated, but it is not used from within coroutines:
besides qemu-img.c and qemu-io.c, which operate synchronously, the
only user is the monitor.  Copy-on-read will introduce a use in the
block layer, and will require converting it.

The solution is "simply" to convert all drivers to coroutines!  We
just need to add a CoMutex that is taken around affected operations.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/bochs.c     |    2 ++
 block/cloop.c     |    2 ++
 block/cow.c       |    2 ++
 block/dmg.c       |    2 ++
 block/nbd.c       |    2 ++
 block/parallels.c |    2 ++
 block/vmdk.c      |    2 ++
 block/vpc.c       |    2 ++
 block/vvfat.c     |    2 ++
 9 files changed, 18 insertions(+), 0 deletions(-)

diff --git a/block/bochs.c b/block/bochs.c
index 3c2f8d1..b0f8072 100644
--- a/block/bochs.c
+++ b/block/bochs.c
@@ -80,6 +80,7 @@ struct bochs_header {
 };
 
 typedef struct BDRVBochsState {
+    CoMutex lock;
     uint32_t *catalog_bitmap;
     int catalog_size;
 
@@ -150,6 +151,7 @@ static int bochs_open(BlockDriverState *bs, int flags)
 
     s->extent_size = le32_to_cpu(bochs.extra.redolog.extent);
 
+    qemu_co_mutex_init(&s->lock);
     return 0;
  fail:
     return -1;
diff --git a/block/cloop.c b/block/cloop.c
index 8cff9f2..a91f372 100644
--- a/block/cloop.c
+++ b/block/cloop.c
@@ -27,6 +27,7 @@
 #include <zlib.h>
 
 typedef struct BDRVCloopState {
+    CoMutex lock;
     uint32_t block_size;
     uint32_t n_blocks;
     uint64_t* offsets;
@@ -93,6 +94,7 @@ static int cloop_open(BlockDriverState *bs, int flags)
 
     s->sectors_per_block = s->block_size/512;
     bs->total_sectors = s->n_blocks*s->sectors_per_block;
+    qemu_co_mutex_init(&s->lock);
     return 0;
 
 cloop_close:
diff --git a/block/cow.c b/block/cow.c
index 4cf543c..2f426e7 100644
--- a/block/cow.c
+++ b/block/cow.c
@@ -42,6 +42,7 @@ struct cow_header_v2 {
 };
 
 typedef struct BDRVCowState {
+    CoMutex lock;
     int64_t cow_sectors_offset;
 } BDRVCowState;
 
@@ -84,6 +85,7 @@ static int cow_open(BlockDriverState *bs, int flags)
 
     bitmap_size = ((bs->total_sectors + 7) >> 3) + sizeof(cow_header);
     s->cow_sectors_offset = (bitmap_size + 511) & ~511;
+    qemu_co_mutex_init(&s->lock);
     return 0;
  fail:
     return -1;
diff --git a/block/dmg.c b/block/dmg.c
index 64c3cce..111aeae 100644
--- a/block/dmg.c
+++ b/block/dmg.c
@@ -28,6 +28,7 @@
 #include <zlib.h>
 
 typedef struct BDRVDMGState {
+    CoMutex lock;
     /* each chunk contains a certain number of sectors,
      * offsets[i] is the offset in the .dmg file,
      * lengths[i] is the length of the compressed chunk,
@@ -177,6 +178,7 @@ static int dmg_open(BlockDriverState *bs, int flags)
 
     s->current_chunk = s->n_chunks;
 
+    qemu_co_mutex_init(&s->lock);
     return 0;
 fail:
     return -1;
diff --git a/block/nbd.c b/block/nbd.c
index 76f04d8..14ab225 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -47,6 +47,7 @@
 #endif
 
 typedef struct BDRVNBDState {
+    CoMutex lock;
     int sock;
     uint32_t nbdflags;
     off_t size;
@@ -175,6 +176,7 @@ static int nbd_open(BlockDriverState *bs, const char* filename, int flags)
      */
     result = nbd_establish_connection(bs);
 
+    qemu_co_mutex_init(&s->lock);
     return result;
 }
 
diff --git a/block/parallels.c b/block/parallels.c
index c64103d..b86e87e 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -46,6 +46,7 @@ struct parallels_header {
 } QEMU_PACKED;
 
 typedef struct BDRVParallelsState {
+    CoMutex lock;
 
     uint32_t *catalog_bitmap;
     int catalog_size;
@@ -95,6 +96,7 @@ static int parallels_open(BlockDriverState *bs, int flags)
     for (i = 0; i < s->catalog_size; i++)
 	le32_to_cpus(&s->catalog_bitmap[i]);
 
+    qemu_co_mutex_init(&s->lock);
     return 0;
 fail:
     if (s->catalog_bitmap)
diff --git a/block/vmdk.c b/block/vmdk.c
index ace2977..1ce220d 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -90,6 +90,7 @@ typedef struct VmdkExtent {
 } VmdkExtent;
 
 typedef struct BDRVVmdkState {
+    CoMutex lock;
     int desc_offset;
     bool cid_updated;
     uint32_t parent_cid;
@@ -646,6 +647,7 @@ static int vmdk_open(BlockDriverState *bs, int flags)
         goto fail;
     }
     s->parent_cid = vmdk_read_cid(bs, 1);
+    qemu_co_mutex_init(&s->lock);
     return ret;
 
 fail:
diff --git a/block/vpc.c b/block/vpc.c
index cb6c570..9155ee1 100644
--- a/block/vpc.c
+++ b/block/vpc.c
@@ -110,6 +110,7 @@ struct vhd_dyndisk_header {
 };
 
 typedef struct BDRVVPCState {
+    CoMutex lock;
     uint8_t footer_buf[HEADER_SIZE];
     uint64_t free_data_block_offset;
     int max_table_entries;
@@ -226,6 +227,7 @@ static int vpc_open(BlockDriverState *bs, int flags)
     s->last_pagetable = -1;
 #endif
 
+    qemu_co_mutex_init(&s->lock);
     return 0;
  fail:
     return err;
diff --git a/block/vvfat.c b/block/vvfat.c
index 7e9e35a..864bfcf 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -317,6 +317,7 @@ static void print_mapping(const struct mapping_t* mapping);
 /* here begins the real VVFAT driver */
 
 typedef struct BDRVVVFATState {
+    CoMutex lock;
     BlockDriverState* bs; /* pointer to parent */
     unsigned int first_sectors_number; /* 1 for a single partition, 0x40 for a disk with partition table */
     unsigned char first_sectors[0x40*0x200];
@@ -1065,6 +1066,7 @@ DLOG(if (stderr == NULL) {
 	bs->heads = bs->cyls = bs->secs = 0;
 
     //    assert(is_consistent(s));
+    qemu_co_mutex_init(&s->lock);
     return 0;
 }
 
-- 
1.7.6.4

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

* [Qemu-devel] [PATCH 16/19] block: take lock around bdrv_read implementations
  2011-10-21 17:18 [Qemu-devel] [PULL 00/19] Block patches Kevin Wolf
                   ` (14 preceding siblings ...)
  2011-10-21 17:19 ` [Qemu-devel] [PATCH 15/19] block: add a CoMutex to synchronous read drivers Kevin Wolf
@ 2011-10-21 17:19 ` Kevin Wolf
  2011-10-21 17:19 ` [Qemu-devel] [PATCH 17/19] block: take lock around bdrv_write implementations Kevin Wolf
                   ` (3 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Kevin Wolf @ 2011-10-21 17:19 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Paolo Bonzini <pbonzini@redhat.com>

This does the first part of the conversion to coroutines, by
wrapping bdrv_read implementations to take the mutex.

Drivers that implement bdrv_read rather than bdrv_co_readv can
then benefit from asynchronous operation (at least if the underlying
protocol supports it, which is not the case for raw-win32), even
though they still operate with a bounce buffer.

raw-win32 does not need the lock, because it cannot yield.
nbd also doesn't probably, but better be safe.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/bochs.c     |   13 ++++++++++++-
 block/cloop.c     |   13 ++++++++++++-
 block/cow.c       |   13 ++++++++++++-
 block/dmg.c       |   13 ++++++++++++-
 block/nbd.c       |   13 ++++++++++++-
 block/parallels.c |   13 ++++++++++++-
 block/vmdk.c      |   13 ++++++++++++-
 block/vpc.c       |   13 ++++++++++++-
 block/vvfat.c     |   13 ++++++++++++-
 9 files changed, 108 insertions(+), 9 deletions(-)

diff --git a/block/bochs.c b/block/bochs.c
index b0f8072..ab7944d 100644
--- a/block/bochs.c
+++ b/block/bochs.c
@@ -209,6 +209,17 @@ static int bochs_read(BlockDriverState *bs, int64_t sector_num,
     return 0;
 }
 
+static coroutine_fn int bochs_co_read(BlockDriverState *bs, int64_t sector_num,
+                                      uint8_t *buf, int nb_sectors)
+{
+    int ret;
+    BDRVBochsState *s = bs->opaque;
+    qemu_co_mutex_lock(&s->lock);
+    ret = bochs_read(bs, sector_num, buf, nb_sectors);
+    qemu_co_mutex_unlock(&s->lock);
+    return ret;
+}
+
 static void bochs_close(BlockDriverState *bs)
 {
     BDRVBochsState *s = bs->opaque;
@@ -220,7 +231,7 @@ static BlockDriver bdrv_bochs = {
     .instance_size	= sizeof(BDRVBochsState),
     .bdrv_probe		= bochs_probe,
     .bdrv_open		= bochs_open,
-    .bdrv_read		= bochs_read,
+    .bdrv_read          = bochs_co_read,
     .bdrv_close		= bochs_close,
 };
 
diff --git a/block/cloop.c b/block/cloop.c
index a91f372..775f8a9 100644
--- a/block/cloop.c
+++ b/block/cloop.c
@@ -146,6 +146,17 @@ static int cloop_read(BlockDriverState *bs, int64_t sector_num,
     return 0;
 }
 
+static coroutine_fn int cloop_co_read(BlockDriverState *bs, int64_t sector_num,
+                                      uint8_t *buf, int nb_sectors)
+{
+    int ret;
+    BDRVCloopState *s = bs->opaque;
+    qemu_co_mutex_lock(&s->lock);
+    ret = cloop_read(bs, sector_num, buf, nb_sectors);
+    qemu_co_mutex_unlock(&s->lock);
+    return ret;
+}
+
 static void cloop_close(BlockDriverState *bs)
 {
     BDRVCloopState *s = bs->opaque;
@@ -161,7 +172,7 @@ static BlockDriver bdrv_cloop = {
     .instance_size	= sizeof(BDRVCloopState),
     .bdrv_probe		= cloop_probe,
     .bdrv_open		= cloop_open,
-    .bdrv_read		= cloop_read,
+    .bdrv_read          = cloop_co_read,
     .bdrv_close		= cloop_close,
 };
 
diff --git a/block/cow.c b/block/cow.c
index 2f426e7..a5fcd20 100644
--- a/block/cow.c
+++ b/block/cow.c
@@ -201,6 +201,17 @@ static int cow_read(BlockDriverState *bs, int64_t sector_num,
     return 0;
 }
 
+static coroutine_fn int cow_co_read(BlockDriverState *bs, int64_t sector_num,
+                                    uint8_t *buf, int nb_sectors)
+{
+    int ret;
+    BDRVCowState *s = bs->opaque;
+    qemu_co_mutex_lock(&s->lock);
+    ret = cow_read(bs, sector_num, buf, nb_sectors);
+    qemu_co_mutex_unlock(&s->lock);
+    return ret;
+}
+
 static int cow_write(BlockDriverState *bs, int64_t sector_num,
                      const uint8_t *buf, int nb_sectors)
 {
@@ -308,7 +319,7 @@ static BlockDriver bdrv_cow = {
     .instance_size	= sizeof(BDRVCowState),
     .bdrv_probe		= cow_probe,
     .bdrv_open		= cow_open,
-    .bdrv_read		= cow_read,
+    .bdrv_read          = cow_co_read,
     .bdrv_write		= cow_write,
     .bdrv_close		= cow_close,
     .bdrv_create	= cow_create,
diff --git a/block/dmg.c b/block/dmg.c
index 111aeae..37902a4 100644
--- a/block/dmg.c
+++ b/block/dmg.c
@@ -282,6 +282,17 @@ static int dmg_read(BlockDriverState *bs, int64_t sector_num,
     return 0;
 }
 
+static coroutine_fn int dmg_co_read(BlockDriverState *bs, int64_t sector_num,
+                                    uint8_t *buf, int nb_sectors)
+{
+    int ret;
+    BDRVDMGState *s = bs->opaque;
+    qemu_co_mutex_lock(&s->lock);
+    ret = dmg_read(bs, sector_num, buf, nb_sectors);
+    qemu_co_mutex_unlock(&s->lock);
+    return ret;
+}
+
 static void dmg_close(BlockDriverState *bs)
 {
     BDRVDMGState *s = bs->opaque;
@@ -302,7 +313,7 @@ static BlockDriver bdrv_dmg = {
     .instance_size	= sizeof(BDRVDMGState),
     .bdrv_probe		= dmg_probe,
     .bdrv_open		= dmg_open,
-    .bdrv_read		= dmg_read,
+    .bdrv_read          = dmg_co_read,
     .bdrv_close		= dmg_close,
 };
 
diff --git a/block/nbd.c b/block/nbd.c
index 14ab225..6b22ae1 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -240,6 +240,17 @@ static int nbd_write(BlockDriverState *bs, int64_t sector_num,
     return 0;
 }
 
+static coroutine_fn int nbd_co_read(BlockDriverState *bs, int64_t sector_num,
+                                    uint8_t *buf, int nb_sectors)
+{
+    int ret;
+    BDRVNBDState *s = bs->opaque;
+    qemu_co_mutex_lock(&s->lock);
+    ret = nbd_read(bs, sector_num, buf, nb_sectors);
+    qemu_co_mutex_unlock(&s->lock);
+    return ret;
+}
+
 static void nbd_close(BlockDriverState *bs)
 {
     BDRVNBDState *s = bs->opaque;
@@ -260,7 +271,7 @@ static BlockDriver bdrv_nbd = {
     .format_name	= "nbd",
     .instance_size	= sizeof(BDRVNBDState),
     .bdrv_file_open	= nbd_open,
-    .bdrv_read		= nbd_read,
+    .bdrv_read          = nbd_co_read,
     .bdrv_write		= nbd_write,
     .bdrv_close		= nbd_close,
     .bdrv_getlength	= nbd_getlength,
diff --git a/block/parallels.c b/block/parallels.c
index b86e87e..d30f0ec 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -136,6 +136,17 @@ static int parallels_read(BlockDriverState *bs, int64_t sector_num,
     return 0;
 }
 
+static coroutine_fn int parallels_co_read(BlockDriverState *bs, int64_t sector_num,
+                                          uint8_t *buf, int nb_sectors)
+{
+    int ret;
+    BDRVParallelsState *s = bs->opaque;
+    qemu_co_mutex_lock(&s->lock);
+    ret = parallels_read(bs, sector_num, buf, nb_sectors);
+    qemu_co_mutex_unlock(&s->lock);
+    return ret;
+}
+
 static void parallels_close(BlockDriverState *bs)
 {
     BDRVParallelsState *s = bs->opaque;
@@ -147,7 +158,7 @@ static BlockDriver bdrv_parallels = {
     .instance_size	= sizeof(BDRVParallelsState),
     .bdrv_probe		= parallels_probe,
     .bdrv_open		= parallels_open,
-    .bdrv_read		= parallels_read,
+    .bdrv_read          = parallels_co_read,
     .bdrv_close		= parallels_close,
 };
 
diff --git a/block/vmdk.c b/block/vmdk.c
index 1ce220d..0e791f2 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -1024,6 +1024,17 @@ static int vmdk_read(BlockDriverState *bs, int64_t sector_num,
     return 0;
 }
 
+static coroutine_fn int vmdk_co_read(BlockDriverState *bs, int64_t sector_num,
+                                     uint8_t *buf, int nb_sectors)
+{
+    int ret;
+    BDRVVmdkState *s = bs->opaque;
+    qemu_co_mutex_lock(&s->lock);
+    ret = vmdk_read(bs, sector_num, buf, nb_sectors);
+    qemu_co_mutex_unlock(&s->lock);
+    return ret;
+}
+
 static int vmdk_write(BlockDriverState *bs, int64_t sector_num,
                      const uint8_t *buf, int nb_sectors)
 {
@@ -1542,7 +1553,7 @@ static BlockDriver bdrv_vmdk = {
     .instance_size  = sizeof(BDRVVmdkState),
     .bdrv_probe     = vmdk_probe,
     .bdrv_open      = vmdk_open,
-    .bdrv_read      = vmdk_read,
+    .bdrv_read      = vmdk_co_read,
     .bdrv_write     = vmdk_write,
     .bdrv_close     = vmdk_close,
     .bdrv_create    = vmdk_create,
diff --git a/block/vpc.c b/block/vpc.c
index 9155ee1..0941533 100644
--- a/block/vpc.c
+++ b/block/vpc.c
@@ -409,6 +409,17 @@ static int vpc_read(BlockDriverState *bs, int64_t sector_num,
     return 0;
 }
 
+static coroutine_fn int vpc_co_read(BlockDriverState *bs, int64_t sector_num,
+                                    uint8_t *buf, int nb_sectors)
+{
+    int ret;
+    BDRVVPCState *s = bs->opaque;
+    qemu_co_mutex_lock(&s->lock);
+    ret = vpc_read(bs, sector_num, buf, nb_sectors);
+    qemu_co_mutex_unlock(&s->lock);
+    return ret;
+}
+
 static int vpc_write(BlockDriverState *bs, int64_t sector_num,
     const uint8_t *buf, int nb_sectors)
 {
@@ -641,7 +652,7 @@ static BlockDriver bdrv_vpc = {
     .instance_size  = sizeof(BDRVVPCState),
     .bdrv_probe     = vpc_probe,
     .bdrv_open      = vpc_open,
-    .bdrv_read      = vpc_read,
+    .bdrv_read      = vpc_co_read,
     .bdrv_write     = vpc_write,
     .bdrv_flush     = vpc_flush,
     .bdrv_close     = vpc_close,
diff --git a/block/vvfat.c b/block/vvfat.c
index 864bfcf..970cccf 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -1281,6 +1281,17 @@ DLOG(fprintf(stderr, "sector %d not allocated\n", (int)sector_num));
     return 0;
 }
 
+static coroutine_fn int vvfat_co_read(BlockDriverState *bs, int64_t sector_num,
+                                      uint8_t *buf, int nb_sectors)
+{
+    int ret;
+    BDRVVVFATState *s = bs->opaque;
+    qemu_co_mutex_lock(&s->lock);
+    ret = vvfat_read(bs, sector_num, buf, nb_sectors);
+    qemu_co_mutex_unlock(&s->lock);
+    return ret;
+}
+
 /* LATER TODO: statify all functions */
 
 /*
@@ -2805,7 +2816,7 @@ static BlockDriver bdrv_vvfat = {
     .format_name	= "vvfat",
     .instance_size	= sizeof(BDRVVVFATState),
     .bdrv_file_open	= vvfat_open,
-    .bdrv_read		= vvfat_read,
+    .bdrv_read          = vvfat_co_read,
     .bdrv_write		= vvfat_write,
     .bdrv_close		= vvfat_close,
     .bdrv_is_allocated	= vvfat_is_allocated,
-- 
1.7.6.4

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

* [Qemu-devel] [PATCH 17/19] block: take lock around bdrv_write implementations
  2011-10-21 17:18 [Qemu-devel] [PULL 00/19] Block patches Kevin Wolf
                   ` (15 preceding siblings ...)
  2011-10-21 17:19 ` [Qemu-devel] [PATCH 16/19] block: take lock around bdrv_read implementations Kevin Wolf
@ 2011-10-21 17:19 ` Kevin Wolf
  2011-10-21 17:19 ` [Qemu-devel] [PATCH 18/19] block: change flush to co_flush Kevin Wolf
                   ` (2 subsequent siblings)
  19 siblings, 0 replies; 21+ messages in thread
From: Kevin Wolf @ 2011-10-21 17:19 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Paolo Bonzini <pbonzini@redhat.com>

This does the first part of the conversion to coroutines, by
wrapping bdrv_write implementations to take the mutex.

Drivers that implement bdrv_write rather than bdrv_co_writev can
then benefit from asynchronous operation (at least if the underlying
protocol supports it, which is not the case for raw-win32), even
though they still operate with a bounce buffer.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/cow.c   |   13 ++++++++++++-
 block/nbd.c   |   13 ++++++++++++-
 block/vmdk.c  |   13 ++++++++++++-
 block/vpc.c   |   13 ++++++++++++-
 block/vvfat.c |   13 ++++++++++++-
 5 files changed, 60 insertions(+), 5 deletions(-)

diff --git a/block/cow.c b/block/cow.c
index a5fcd20..29fa844 100644
--- a/block/cow.c
+++ b/block/cow.c
@@ -226,6 +226,17 @@ static int cow_write(BlockDriverState *bs, int64_t sector_num,
     return cow_update_bitmap(bs, sector_num, nb_sectors);
 }
 
+static coroutine_fn int cow_co_write(BlockDriverState *bs, int64_t sector_num,
+                                     const uint8_t *buf, int nb_sectors)
+{
+    int ret;
+    BDRVCowState *s = bs->opaque;
+    qemu_co_mutex_lock(&s->lock);
+    ret = cow_write(bs, sector_num, buf, nb_sectors);
+    qemu_co_mutex_unlock(&s->lock);
+    return ret;
+}
+
 static void cow_close(BlockDriverState *bs)
 {
 }
@@ -320,7 +331,7 @@ static BlockDriver bdrv_cow = {
     .bdrv_probe		= cow_probe,
     .bdrv_open		= cow_open,
     .bdrv_read          = cow_co_read,
-    .bdrv_write		= cow_write,
+    .bdrv_write         = cow_co_write,
     .bdrv_close		= cow_close,
     .bdrv_create	= cow_create,
     .bdrv_flush		= cow_flush,
diff --git a/block/nbd.c b/block/nbd.c
index 6b22ae1..882b2dc 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -251,6 +251,17 @@ static coroutine_fn int nbd_co_read(BlockDriverState *bs, int64_t sector_num,
     return ret;
 }
 
+static coroutine_fn int nbd_co_write(BlockDriverState *bs, int64_t sector_num,
+                                     const uint8_t *buf, int nb_sectors)
+{
+    int ret;
+    BDRVNBDState *s = bs->opaque;
+    qemu_co_mutex_lock(&s->lock);
+    ret = nbd_write(bs, sector_num, buf, nb_sectors);
+    qemu_co_mutex_unlock(&s->lock);
+    return ret;
+}
+
 static void nbd_close(BlockDriverState *bs)
 {
     BDRVNBDState *s = bs->opaque;
@@ -272,7 +283,7 @@ static BlockDriver bdrv_nbd = {
     .instance_size	= sizeof(BDRVNBDState),
     .bdrv_file_open	= nbd_open,
     .bdrv_read          = nbd_co_read,
-    .bdrv_write		= nbd_write,
+    .bdrv_write         = nbd_co_write,
     .bdrv_close		= nbd_close,
     .bdrv_getlength	= nbd_getlength,
     .protocol_name	= "nbd",
diff --git a/block/vmdk.c b/block/vmdk.c
index 0e791f2..3b376ed 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -1116,6 +1116,17 @@ static int vmdk_write(BlockDriverState *bs, int64_t sector_num,
     return 0;
 }
 
+static coroutine_fn int vmdk_co_write(BlockDriverState *bs, int64_t sector_num,
+                                      const uint8_t *buf, int nb_sectors)
+{
+    int ret;
+    BDRVVmdkState *s = bs->opaque;
+    qemu_co_mutex_lock(&s->lock);
+    ret = vmdk_write(bs, sector_num, buf, nb_sectors);
+    qemu_co_mutex_unlock(&s->lock);
+    return ret;
+}
+
 
 static int vmdk_create_extent(const char *filename, int64_t filesize,
                               bool flat, bool compress)
@@ -1554,7 +1565,7 @@ static BlockDriver bdrv_vmdk = {
     .bdrv_probe     = vmdk_probe,
     .bdrv_open      = vmdk_open,
     .bdrv_read      = vmdk_co_read,
-    .bdrv_write     = vmdk_write,
+    .bdrv_write     = vmdk_co_write,
     .bdrv_close     = vmdk_close,
     .bdrv_create    = vmdk_create,
     .bdrv_flush     = vmdk_flush,
diff --git a/block/vpc.c b/block/vpc.c
index 0941533..74ca642 100644
--- a/block/vpc.c
+++ b/block/vpc.c
@@ -456,6 +456,17 @@ static int vpc_write(BlockDriverState *bs, int64_t sector_num,
     return 0;
 }
 
+static coroutine_fn int vpc_co_write(BlockDriverState *bs, int64_t sector_num,
+                                     const uint8_t *buf, int nb_sectors)
+{
+    int ret;
+    BDRVVPCState *s = bs->opaque;
+    qemu_co_mutex_lock(&s->lock);
+    ret = vpc_write(bs, sector_num, buf, nb_sectors);
+    qemu_co_mutex_unlock(&s->lock);
+    return ret;
+}
+
 static int vpc_flush(BlockDriverState *bs)
 {
     return bdrv_flush(bs->file);
@@ -653,7 +664,7 @@ static BlockDriver bdrv_vpc = {
     .bdrv_probe     = vpc_probe,
     .bdrv_open      = vpc_open,
     .bdrv_read      = vpc_co_read,
-    .bdrv_write     = vpc_write,
+    .bdrv_write     = vpc_co_write,
     .bdrv_flush     = vpc_flush,
     .bdrv_close     = vpc_close,
     .bdrv_create    = vpc_create,
diff --git a/block/vvfat.c b/block/vvfat.c
index 970cccf..e1fcdbc 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -2727,6 +2727,17 @@ DLOG(checkpoint());
     return 0;
 }
 
+static coroutine_fn int vvfat_co_write(BlockDriverState *bs, int64_t sector_num,
+                                       const uint8_t *buf, int nb_sectors)
+{
+    int ret;
+    BDRVVVFATState *s = bs->opaque;
+    qemu_co_mutex_lock(&s->lock);
+    ret = vvfat_write(bs, sector_num, buf, nb_sectors);
+    qemu_co_mutex_unlock(&s->lock);
+    return ret;
+}
+
 static int vvfat_is_allocated(BlockDriverState *bs,
 	int64_t sector_num, int nb_sectors, int* n)
 {
@@ -2817,7 +2828,7 @@ static BlockDriver bdrv_vvfat = {
     .instance_size	= sizeof(BDRVVVFATState),
     .bdrv_file_open	= vvfat_open,
     .bdrv_read          = vvfat_co_read,
-    .bdrv_write		= vvfat_write,
+    .bdrv_write         = vvfat_co_write,
     .bdrv_close		= vvfat_close,
     .bdrv_is_allocated	= vvfat_is_allocated,
     .protocol_name	= "fat",
-- 
1.7.6.4

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

* [Qemu-devel] [PATCH 18/19] block: change flush to co_flush
  2011-10-21 17:18 [Qemu-devel] [PULL 00/19] Block patches Kevin Wolf
                   ` (16 preceding siblings ...)
  2011-10-21 17:19 ` [Qemu-devel] [PATCH 17/19] block: take lock around bdrv_write implementations Kevin Wolf
@ 2011-10-21 17:19 ` Kevin Wolf
  2011-10-21 17:19 ` [Qemu-devel] [PATCH 19/19] block: change discard to co_discard Kevin Wolf
  2011-10-24 16:19 ` [Qemu-devel] [PULL 00/19] Block patches Anthony Liguori
  19 siblings, 0 replies; 21+ messages in thread
From: Kevin Wolf @ 2011-10-21 17:19 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Paolo Bonzini <pbonzini@redhat.com>

Since coroutine operation is now mandatory, convert all bdrv_flush
implementations to coroutines.  For qcow2, this means taking the lock.
Other implementations are simpler and just forward bdrv_flush to the
underlying protocol, so they can avoid the lock.

The bdrv_flush callback is then unused and can be eliminated.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block.c           |    2 --
 block/cow.c       |    6 +++---
 block/qcow.c      |   11 +++++------
 block/qcow2.c     |   14 +++++++-------
 block/raw-win32.c |    4 ++--
 block/rbd.c       |    4 ++--
 block/vdi.c       |    6 +++---
 block/vmdk.c      |    8 ++++----
 block/vpc.c       |    6 +++---
 block_int.h       |    1 -
 10 files changed, 29 insertions(+), 33 deletions(-)

diff --git a/block.c b/block.c
index 28508f2..81fb709 100644
--- a/block.c
+++ b/block.c
@@ -2892,8 +2892,6 @@ int coroutine_fn bdrv_co_flush(BlockDriverState *bs)
             qemu_coroutine_yield();
             return co.ret;
         }
-    } else if (bs->drv->bdrv_flush) {
-        return bs->drv->bdrv_flush(bs);
     } else {
         /*
          * Some block drivers always operate in either writethrough or unsafe
diff --git a/block/cow.c b/block/cow.c
index 29fa844..707c0aa 100644
--- a/block/cow.c
+++ b/block/cow.c
@@ -306,9 +306,9 @@ exit:
     return ret;
 }
 
-static int cow_flush(BlockDriverState *bs)
+static coroutine_fn int cow_co_flush(BlockDriverState *bs)
 {
-    return bdrv_flush(bs->file);
+    return bdrv_co_flush(bs->file);
 }
 
 static QEMUOptionParameter cow_create_options[] = {
@@ -334,7 +334,7 @@ static BlockDriver bdrv_cow = {
     .bdrv_write         = cow_co_write,
     .bdrv_close		= cow_close,
     .bdrv_create	= cow_create,
-    .bdrv_flush		= cow_flush,
+    .bdrv_co_flush      = cow_co_flush,
     .bdrv_is_allocated	= cow_is_allocated,
 
     .create_options = cow_create_options,
diff --git a/block/qcow.c b/block/qcow.c
index f93e3eb..ab36b29 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -781,10 +781,9 @@ static int qcow_write_compressed(BlockDriverState *bs, int64_t sector_num,
     return 0;
 }
 
-static BlockDriverAIOCB *qcow_aio_flush(BlockDriverState *bs,
-        BlockDriverCompletionFunc *cb, void *opaque)
+static coroutine_fn int qcow_co_flush(BlockDriverState *bs)
 {
-    return bdrv_aio_flush(bs->file, cb, opaque);
+    return bdrv_co_flush(bs->file);
 }
 
 static int qcow_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
@@ -824,9 +823,9 @@ static BlockDriver bdrv_qcow = {
     .bdrv_is_allocated	= qcow_is_allocated,
     .bdrv_set_key	= qcow_set_key,
     .bdrv_make_empty	= qcow_make_empty,
-    .bdrv_co_readv  = qcow_co_readv,
-    .bdrv_co_writev = qcow_co_writev,
-    .bdrv_aio_flush	= qcow_aio_flush,
+    .bdrv_co_readv      = qcow_co_readv,
+    .bdrv_co_writev     = qcow_co_writev,
+    .bdrv_co_flush      = qcow_co_flush,
     .bdrv_write_compressed = qcow_write_compressed,
     .bdrv_get_info	= qcow_get_info,
 
diff --git a/block/qcow2.c b/block/qcow2.c
index 91f4f04..6ef38bf 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1099,24 +1099,24 @@ fail:
     return ret;
 }
 
-static BlockDriverAIOCB *qcow2_aio_flush(BlockDriverState *bs,
-                                         BlockDriverCompletionFunc *cb,
-                                         void *opaque)
+static int qcow2_co_flush(BlockDriverState *bs)
 {
     BDRVQcowState *s = bs->opaque;
     int ret;
 
+    qemu_co_mutex_lock(&s->lock);
     ret = qcow2_cache_flush(bs, s->l2_table_cache);
     if (ret < 0) {
-        return NULL;
+        return ret;
     }
 
     ret = qcow2_cache_flush(bs, s->refcount_block_cache);
     if (ret < 0) {
-        return NULL;
+        return ret;
     }
+    qemu_co_mutex_unlock(&s->lock);
 
-    return bdrv_aio_flush(bs->file, cb, opaque);
+    return bdrv_co_flush(bs->file);
 }
 
 static int64_t qcow2_vm_state_offset(BDRVQcowState *s)
@@ -1237,7 +1237,7 @@ static BlockDriver bdrv_qcow2 = {
 
     .bdrv_co_readv      = qcow2_co_readv,
     .bdrv_co_writev     = qcow2_co_writev,
-    .bdrv_aio_flush     = qcow2_aio_flush,
+    .bdrv_co_flush      = qcow2_co_flush,
 
     .bdrv_discard           = qcow2_discard,
     .bdrv_truncate          = qcow2_truncate,
diff --git a/block/raw-win32.c b/block/raw-win32.c
index b7dd357..f5f73bc 100644
--- a/block/raw-win32.c
+++ b/block/raw-win32.c
@@ -281,7 +281,7 @@ static BlockDriver bdrv_file = {
     .bdrv_file_open	= raw_open,
     .bdrv_close		= raw_close,
     .bdrv_create	= raw_create,
-    .bdrv_flush		= raw_flush,
+    .bdrv_co_flush      = raw_flush,
     .bdrv_read		= raw_read,
     .bdrv_write		= raw_write,
     .bdrv_truncate	= raw_truncate,
@@ -409,7 +409,7 @@ static BlockDriver bdrv_host_device = {
     .bdrv_probe_device	= hdev_probe_device,
     .bdrv_file_open	= hdev_open,
     .bdrv_close		= raw_close,
-    .bdrv_flush		= raw_flush,
+    .bdrv_co_flush      = raw_flush,
     .bdrv_has_zero_init = hdev_has_zero_init,
 
     .bdrv_read		= raw_read,
diff --git a/block/rbd.c b/block/rbd.c
index 3068c82..c684e0c 100644
--- a/block/rbd.c
+++ b/block/rbd.c
@@ -705,7 +705,7 @@ static BlockDriverAIOCB *qemu_rbd_aio_writev(BlockDriverState *bs,
     return rbd_aio_rw_vector(bs, sector_num, qiov, nb_sectors, cb, opaque, 1);
 }
 
-static int qemu_rbd_flush(BlockDriverState *bs)
+static int qemu_rbd_co_flush(BlockDriverState *bs)
 {
 #if LIBRBD_VERSION_CODE >= LIBRBD_VERSION(0, 1, 1)
     /* rbd_flush added in 0.1.1 */
@@ -851,7 +851,7 @@ static BlockDriver bdrv_rbd = {
     .bdrv_file_open     = qemu_rbd_open,
     .bdrv_close         = qemu_rbd_close,
     .bdrv_create        = qemu_rbd_create,
-    .bdrv_flush         = qemu_rbd_flush,
+    .bdrv_co_flush      = qemu_rbd_co_flush,
     .bdrv_get_info      = qemu_rbd_getinfo,
     .create_options     = qemu_rbd_create_options,
     .bdrv_getlength     = qemu_rbd_getlength,
diff --git a/block/vdi.c b/block/vdi.c
index 1d5ad2b..883046d 100644
--- a/block/vdi.c
+++ b/block/vdi.c
@@ -936,10 +936,10 @@ static void vdi_close(BlockDriverState *bs)
 {
 }
 
-static int vdi_flush(BlockDriverState *bs)
+static coroutine_fn int vdi_co_flush(BlockDriverState *bs)
 {
     logout("\n");
-    return bdrv_flush(bs->file);
+    return bdrv_co_flush(bs->file);
 }
 
 
@@ -975,7 +975,7 @@ static BlockDriver bdrv_vdi = {
     .bdrv_open = vdi_open,
     .bdrv_close = vdi_close,
     .bdrv_create = vdi_create,
-    .bdrv_flush = vdi_flush,
+    .bdrv_co_flush = vdi_co_flush,
     .bdrv_is_allocated = vdi_is_allocated,
     .bdrv_make_empty = vdi_make_empty,
 
diff --git a/block/vmdk.c b/block/vmdk.c
index 3b376ed..6be592f 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -1494,14 +1494,14 @@ static void vmdk_close(BlockDriverState *bs)
     vmdk_free_extents(bs);
 }
 
-static int vmdk_flush(BlockDriverState *bs)
+static coroutine_fn int vmdk_co_flush(BlockDriverState *bs)
 {
     int i, ret, err;
     BDRVVmdkState *s = bs->opaque;
 
-    ret = bdrv_flush(bs->file);
+    ret = bdrv_co_flush(bs->file);
     for (i = 0; i < s->num_extents; i++) {
-        err = bdrv_flush(s->extents[i].file);
+        err = bdrv_co_flush(s->extents[i].file);
         if (err < 0) {
             ret = err;
         }
@@ -1568,7 +1568,7 @@ static BlockDriver bdrv_vmdk = {
     .bdrv_write     = vmdk_co_write,
     .bdrv_close     = vmdk_close,
     .bdrv_create    = vmdk_create,
-    .bdrv_flush     = vmdk_flush,
+    .bdrv_co_flush  = vmdk_co_flush,
     .bdrv_is_allocated  = vmdk_is_allocated,
     .bdrv_get_allocated_file_size  = vmdk_get_allocated_file_size,
 
diff --git a/block/vpc.c b/block/vpc.c
index 74ca642..79be7d0 100644
--- a/block/vpc.c
+++ b/block/vpc.c
@@ -467,9 +467,9 @@ static coroutine_fn int vpc_co_write(BlockDriverState *bs, int64_t sector_num,
     return ret;
 }
 
-static int vpc_flush(BlockDriverState *bs)
+static coroutine_fn int vpc_co_flush(BlockDriverState *bs)
 {
-    return bdrv_flush(bs->file);
+    return bdrv_co_flush(bs->file);
 }
 
 /*
@@ -665,7 +665,7 @@ static BlockDriver bdrv_vpc = {
     .bdrv_open      = vpc_open,
     .bdrv_read      = vpc_co_read,
     .bdrv_write     = vpc_co_write,
-    .bdrv_flush     = vpc_flush,
+    .bdrv_co_flush  = vpc_co_flush,
     .bdrv_close     = vpc_close,
     .bdrv_create    = vpc_create,
 
diff --git a/block_int.h b/block_int.h
index 384598f..bc3b07e 100644
--- a/block_int.h
+++ b/block_int.h
@@ -62,7 +62,6 @@ struct BlockDriver {
                       const uint8_t *buf, int nb_sectors);
     void (*bdrv_close)(BlockDriverState *bs);
     int (*bdrv_create)(const char *filename, QEMUOptionParameter *options);
-    int (*bdrv_flush)(BlockDriverState *bs);
     int (*bdrv_discard)(BlockDriverState *bs, int64_t sector_num,
                         int nb_sectors);
     int (*bdrv_is_allocated)(BlockDriverState *bs, int64_t sector_num,
-- 
1.7.6.4

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

* [Qemu-devel] [PATCH 19/19] block: change discard to co_discard
  2011-10-21 17:18 [Qemu-devel] [PULL 00/19] Block patches Kevin Wolf
                   ` (17 preceding siblings ...)
  2011-10-21 17:19 ` [Qemu-devel] [PATCH 18/19] block: change flush to co_flush Kevin Wolf
@ 2011-10-21 17:19 ` Kevin Wolf
  2011-10-24 16:19 ` [Qemu-devel] [PULL 00/19] Block patches Anthony Liguori
  19 siblings, 0 replies; 21+ messages in thread
From: Kevin Wolf @ 2011-10-21 17:19 UTC (permalink / raw)
  To: anthony; +Cc: kwolf, qemu-devel

From: Paolo Bonzini <pbonzini@redhat.com>

Since coroutine operation is now mandatory, convert both bdrv_discard
implementations to coroutines.  For qcow2, this means taking the lock
around the operation.  raw-posix remains synchronous.

The bdrv_discard callback is then unused and can be eliminated.

Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block.c           |    2 --
 block/qcow2.c     |   14 ++++++++++----
 block/raw-posix.c |    5 +++--
 block_int.h       |    2 --
 4 files changed, 13 insertions(+), 10 deletions(-)

diff --git a/block.c b/block.c
index 81fb709..70aab63 100644
--- a/block.c
+++ b/block.c
@@ -2962,8 +2962,6 @@ int coroutine_fn bdrv_co_discard(BlockDriverState *bs, int64_t sector_num,
             qemu_coroutine_yield();
             return co.ret;
         }
-    } else if (bs->drv->bdrv_discard) {
-        return bs->drv->bdrv_discard(bs, sector_num, nb_sectors);
     } else {
         return 0;
     }
diff --git a/block/qcow2.c b/block/qcow2.c
index 6ef38bf..a181932 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -978,11 +978,17 @@ static int qcow2_make_empty(BlockDriverState *bs)
     return 0;
 }
 
-static int qcow2_discard(BlockDriverState *bs, int64_t sector_num,
-    int nb_sectors)
+static coroutine_fn int qcow2_co_discard(BlockDriverState *bs,
+    int64_t sector_num, int nb_sectors)
 {
-    return qcow2_discard_clusters(bs, sector_num << BDRV_SECTOR_BITS,
+    int ret;
+    BDRVQcowState *s = bs->opaque;
+
+    qemu_co_mutex_lock(&s->lock);
+    ret = qcow2_discard_clusters(bs, sector_num << BDRV_SECTOR_BITS,
         nb_sectors);
+    qemu_co_mutex_unlock(&s->lock);
+    return ret;
 }
 
 static int qcow2_truncate(BlockDriverState *bs, int64_t offset)
@@ -1239,7 +1245,7 @@ static BlockDriver bdrv_qcow2 = {
     .bdrv_co_writev     = qcow2_co_writev,
     .bdrv_co_flush      = qcow2_co_flush,
 
-    .bdrv_discard           = qcow2_discard,
+    .bdrv_co_discard        = qcow2_co_discard,
     .bdrv_truncate          = qcow2_truncate,
     .bdrv_write_compressed  = qcow2_write_compressed,
 
diff --git a/block/raw-posix.c b/block/raw-posix.c
index afcb4c1..a3de373 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -602,7 +602,8 @@ static int xfs_discard(BDRVRawState *s, int64_t sector_num, int nb_sectors)
 }
 #endif
 
-static int raw_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors)
+static coroutine_fn int raw_co_discard(BlockDriverState *bs,
+    int64_t sector_num, int nb_sectors)
 {
 #ifdef CONFIG_XFS
     BDRVRawState *s = bs->opaque;
@@ -632,7 +633,7 @@ static BlockDriver bdrv_file = {
     .bdrv_file_open = raw_open,
     .bdrv_close = raw_close,
     .bdrv_create = raw_create,
-    .bdrv_discard = raw_discard,
+    .bdrv_co_discard = raw_co_discard,
 
     .bdrv_aio_readv = raw_aio_readv,
     .bdrv_aio_writev = raw_aio_writev,
diff --git a/block_int.h b/block_int.h
index bc3b07e..dac00f5 100644
--- a/block_int.h
+++ b/block_int.h
@@ -62,8 +62,6 @@ struct BlockDriver {
                       const uint8_t *buf, int nb_sectors);
     void (*bdrv_close)(BlockDriverState *bs);
     int (*bdrv_create)(const char *filename, QEMUOptionParameter *options);
-    int (*bdrv_discard)(BlockDriverState *bs, int64_t sector_num,
-                        int nb_sectors);
     int (*bdrv_is_allocated)(BlockDriverState *bs, int64_t sector_num,
                              int nb_sectors, int *pnum);
     int (*bdrv_set_key)(BlockDriverState *bs, const char *key);
-- 
1.7.6.4

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

* Re: [Qemu-devel] [PULL 00/19] Block patches
  2011-10-21 17:18 [Qemu-devel] [PULL 00/19] Block patches Kevin Wolf
                   ` (18 preceding siblings ...)
  2011-10-21 17:19 ` [Qemu-devel] [PATCH 19/19] block: change discard to co_discard Kevin Wolf
@ 2011-10-24 16:19 ` Anthony Liguori
  19 siblings, 0 replies; 21+ messages in thread
From: Anthony Liguori @ 2011-10-24 16:19 UTC (permalink / raw)
  To: Kevin Wolf; +Cc: qemu-devel

On 10/21/2011 12:18 PM, Kevin Wolf wrote:
> The following changes since commit c2e2343e1faae7bbc77574c12a25881b1b696808:
>
>    hw/arm_gic.c: Fix save/load of irq_target array (2011-10-21 17:19:56 +0200)
>
> are available in the git repository at:
>    git://repo.or.cz/qemu/kevin.git for-anthony

Pulled.  Thanks.

Regards,

Anthony Liguori

>
> Alex Jia (1):
>        fix memory leak in aio_write_f
>
> Kevin Wolf (5):
>        xen_disk: Always set feature-barrier = 1
>        fdc: Fix floppy port I/O
>        qemu-img: Don't allow preallocation and compression at the same time
>        qcow2: Fix bdrv_write_compressed error handling
>        pc: Fix floppy drives with if=none
>
> Paolo Bonzini (12):
>        sheepdog: add coroutine_fn markers
>        add socket_set_block
>        block: rename bdrv_co_rw_bh
>        block: unify flush implementations
>        block: add bdrv_co_discard and bdrv_aio_discard support
>        vmdk: fix return values of vmdk_parent_open
>        vmdk: clean up open
>        block: add a CoMutex to synchronous read drivers
>        block: take lock around bdrv_read implementations
>        block: take lock around bdrv_write implementations
>        block: change flush to co_flush
>        block: change discard to co_discard
>
> Stefan Hajnoczi (1):
>        block: drop redundant bdrv_flush implementation
>
>   block.c               |  258 ++++++++++++++++++++++++++++++-------------------
>   block.h               |    5 +
>   block/blkdebug.c      |    6 -
>   block/blkverify.c     |    9 --
>   block/bochs.c         |   15 +++-
>   block/cloop.c         |   15 +++-
>   block/cow.c           |   34 ++++++-
>   block/dmg.c           |   15 +++-
>   block/nbd.c           |   28 +++++-
>   block/parallels.c     |   15 +++-
>   block/qcow.c          |   17 +---
>   block/qcow2-cluster.c |    6 +-
>   block/qcow2.c         |   72 ++++++--------
>   block/qed.c           |    6 -
>   block/raw-posix.c     |   23 +----
>   block/raw-win32.c     |    4 +-
>   block/raw.c           |   23 ++---
>   block/rbd.c           |    4 +-
>   block/sheepdog.c      |   14 ++--
>   block/vdi.c           |    6 +-
>   block/vmdk.c          |   82 ++++++++++------
>   block/vpc.c           |   34 ++++++-
>   block/vvfat.c         |   28 +++++-
>   block_int.h           |    9 +-
>   hw/fdc.c              |   14 +++
>   hw/fdc.h              |    9 ++-
>   hw/pc.c               |   25 +++--
>   hw/pc.h               |    3 +-
>   hw/pc_piix.c          |    5 +-
>   hw/xen_disk.c         |    5 +-
>   oslib-posix.c         |    7 ++
>   oslib-win32.c         |    6 +
>   qemu-img.c            |   11 ++
>   qemu-io.c             |    1 +
>   qemu_socket.h         |    1 +
>   trace-events          |    1 +
>   36 files changed, 524 insertions(+), 292 deletions(-)
>
>

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

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

Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-10-21 17:18 [Qemu-devel] [PULL 00/19] Block patches Kevin Wolf
2011-10-21 17:18 ` [Qemu-devel] [PATCH 01/19] sheepdog: add coroutine_fn markers Kevin Wolf
2011-10-21 17:18 ` [Qemu-devel] [PATCH 02/19] add socket_set_block Kevin Wolf
2011-10-21 17:19 ` [Qemu-devel] [PATCH 03/19] block: rename bdrv_co_rw_bh Kevin Wolf
2011-10-21 17:19 ` [Qemu-devel] [PATCH 04/19] fix memory leak in aio_write_f Kevin Wolf
2011-10-21 17:19 ` [Qemu-devel] [PATCH 05/19] xen_disk: Always set feature-barrier = 1 Kevin Wolf
2011-10-21 17:19 ` [Qemu-devel] [PATCH 06/19] block: unify flush implementations Kevin Wolf
2011-10-21 17:19 ` [Qemu-devel] [PATCH 07/19] block: drop redundant bdrv_flush implementation Kevin Wolf
2011-10-21 17:19 ` [Qemu-devel] [PATCH 08/19] block: add bdrv_co_discard and bdrv_aio_discard support Kevin Wolf
2011-10-21 17:19 ` [Qemu-devel] [PATCH 09/19] fdc: Fix floppy port I/O Kevin Wolf
2011-10-21 17:19 ` [Qemu-devel] [PATCH 10/19] qemu-img: Don't allow preallocation and compression at the same time Kevin Wolf
2011-10-21 17:19 ` [Qemu-devel] [PATCH 11/19] qcow2: Fix bdrv_write_compressed error handling Kevin Wolf
2011-10-21 17:19 ` [Qemu-devel] [PATCH 12/19] pc: Fix floppy drives with if=none Kevin Wolf
2011-10-21 17:19 ` [Qemu-devel] [PATCH 13/19] vmdk: fix return values of vmdk_parent_open Kevin Wolf
2011-10-21 17:19 ` [Qemu-devel] [PATCH 14/19] vmdk: clean up open Kevin Wolf
2011-10-21 17:19 ` [Qemu-devel] [PATCH 15/19] block: add a CoMutex to synchronous read drivers Kevin Wolf
2011-10-21 17:19 ` [Qemu-devel] [PATCH 16/19] block: take lock around bdrv_read implementations Kevin Wolf
2011-10-21 17:19 ` [Qemu-devel] [PATCH 17/19] block: take lock around bdrv_write implementations Kevin Wolf
2011-10-21 17:19 ` [Qemu-devel] [PATCH 18/19] block: change flush to co_flush Kevin Wolf
2011-10-21 17:19 ` [Qemu-devel] [PATCH 19/19] block: change discard to co_discard Kevin Wolf
2011-10-24 16:19 ` [Qemu-devel] [PULL 00/19] 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).