+++ /dev/null
-From dc7588c1eb3008bda53dde1d6b890cd299758155 Mon Sep 17 00:00:00 2001
-From: Josh Durgin <josh.durgin@inktank.com>
-Date: Fri, 29 Mar 2013 13:03:23 -0700
-Subject: [PATCH] rbd: add an asynchronous flush
-
-The existing bdrv_co_flush_to_disk implementation uses rbd_flush(),
-which is sychronous and causes the main qemu thread to block until it
-is complete. This results in unresponsiveness and extra latency for
-the guest.
-
-Fix this by using an asynchronous version of flush. This was added to
-librbd with a special #define to indicate its presence, since it will
-be backported to stable versions. Thus, there is no need to check the
-version of librbd.
-
-Implement this as bdrv_aio_flush, since it matches other aio functions
-in the rbd block driver, and leave out bdrv_co_flush_to_disk when the
-asynchronous version is available.
-
-Reported-by: Oliver Francke <oliver@filoo.de>
-Signed-off-by: Josh Durgin <josh.durgin@inktank.com>
-Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
----
- block/rbd.c | 37 +++++++++++++++++++++++++++++++++----
- 1 files changed, 33 insertions(+), 4 deletions(-)
-
-diff --git a/block/rbd.c b/block/rbd.c
-index 1a8ea6d..141b488 100644
---- a/block/rbd.c
-+++ b/block/rbd.c
-@@ -63,7 +63,8 @@
- typedef enum {
- RBD_AIO_READ,
- RBD_AIO_WRITE,
-- RBD_AIO_DISCARD
-+ RBD_AIO_DISCARD,
-+ RBD_AIO_FLUSH
- } RBDAIOCmd;
-
- typedef struct RBDAIOCB {
-@@ -379,8 +380,7 @@ static void qemu_rbd_complete_aio(RADOSCB *rcb)
-
- r = rcb->ret;
-
-- if (acb->cmd == RBD_AIO_WRITE ||
-- acb->cmd == RBD_AIO_DISCARD) {
-+ if (acb->cmd != RBD_AIO_READ) {
- if (r < 0) {
- acb->ret = r;
- acb->error = 1;
-@@ -659,6 +659,16 @@ static int rbd_aio_discard_wrapper(rbd_image_t image,
- #endif
- }
-
-+static int rbd_aio_flush_wrapper(rbd_image_t image,
-+ rbd_completion_t comp)
-+{
-+#ifdef LIBRBD_SUPPORTS_AIO_FLUSH
-+ return rbd_aio_flush(image, comp);
-+#else
-+ return -ENOTSUP;
-+#endif
-+}
-+
- static BlockDriverAIOCB *rbd_start_aio(BlockDriverState *bs,
- int64_t sector_num,
- QEMUIOVector *qiov,
-@@ -679,7 +689,7 @@ static BlockDriverAIOCB *rbd_start_aio(BlockDriverState *bs,
- acb = qemu_aio_get(&rbd_aiocb_info, bs, cb, opaque);
- acb->cmd = cmd;
- acb->qiov = qiov;
-- if (cmd == RBD_AIO_DISCARD) {
-+ if (cmd == RBD_AIO_DISCARD || cmd == RBD_AIO_FLUSH) {
- acb->bounce = NULL;
- } else {
- acb->bounce = qemu_blockalign(bs, qiov->size);
-@@ -723,6 +733,9 @@ static BlockDriverAIOCB *rbd_start_aio(BlockDriverState *bs,
- case RBD_AIO_DISCARD:
- r = rbd_aio_discard_wrapper(s->image, off, size, c);
- break;
-+ case RBD_AIO_FLUSH:
-+ r = rbd_aio_flush_wrapper(s->image, c);
-+ break;
- default:
- r = -EINVAL;
- }
-@@ -762,6 +775,16 @@ static BlockDriverAIOCB *qemu_rbd_aio_writev(BlockDriverState *bs,
- RBD_AIO_WRITE);
- }
-
-+#ifdef LIBRBD_SUPPORTS_AIO_FLUSH
-+static BlockDriverAIOCB *qemu_rbd_aio_flush(BlockDriverState *bs,
-+ BlockDriverCompletionFunc *cb,
-+ void *opaque)
-+{
-+ return rbd_start_aio(bs, 0, NULL, 0, cb, opaque, RBD_AIO_FLUSH);
-+}
-+
-+#else
-+
- static int qemu_rbd_co_flush(BlockDriverState *bs)
- {
- #if LIBRBD_VERSION_CODE >= LIBRBD_VERSION(0, 1, 1)
-@@ -772,6 +795,7 @@ static int qemu_rbd_co_flush(BlockDriverState *bs)
- return 0;
- #endif
- }
-+#endif
-
- static int qemu_rbd_getinfo(BlockDriverState *bs, BlockDriverInfo *bdi)
- {
-@@ -949,7 +973,12 @@ static BlockDriver bdrv_rbd = {
-
- .bdrv_aio_readv = qemu_rbd_aio_readv,
- .bdrv_aio_writev = qemu_rbd_aio_writev,
-+
-+#ifdef LIBRBD_SUPPORTS_AIO_FLUSH
-+ .bdrv_aio_flush = qemu_rbd_aio_flush,
-+#else
- .bdrv_co_flush_to_disk = qemu_rbd_co_flush,
-+#endif
-
- #ifdef LIBRBD_SUPPORTS_DISCARD
- .bdrv_aio_discard = qemu_rbd_aio_discard,
---
-1.7.0.4
-