@@ -25,6 +25,8 @@
#include <signal.h>
+#include <sys/eventfd.h>
+
/*
* When specifying the image filename use:
*
@@ -47,6 +49,15 @@
#define OBJ_MAX_SIZE (1UL << OBJ_DEFAULT_OBJ_ORDER)
+typedef struct BDRVRBDState {
+ int efd;
+ rados_pool_t pool;
+ char name[RBD_MAX_OBJ_NAME_SIZE];
+ uint64_t size;
+ uint64_t objsize;
+ int qemu_aio_count;
+} BDRVRBDState;
+
typedef struct RBDAIOCB {
BlockDriverAIOCB common;
QEMUBH *bh;
@@ -57,6 +68,7 @@ typedef struct RBDAIOCB {
int64_t sector_num;
int aiocnt;
int error;
+ BDRVRBDState *s;
} RBDAIOCB;
typedef struct RADOSCB {
@@ -67,12 +79,6 @@ typedef struct RADOSCB {
char *buf;
} RADOSCB;
-typedef struct BDRVRBDState {
- rados_pool_t pool;
- char name[RBD_MAX_OBJ_NAME_SIZE];
- uint64_t size;
- uint64_t objsize;
-} BDRVRBDState;
typedef struct rbd_obj_header_ondisk RbdHeader1;
@@ -255,6 +261,31 @@ done:
return ret;
}
+static void rbd_aio_completion_cb(void *opaque)
+{
+ BDRVRBDState *s = opaque;
+
+ uint64_t val;
+ ssize_t ret;
+
+ do {
+ if ((ret = read(s->efd, &val, sizeof(val))) > 0) {
+ s->qemu_aio_count -= val;
+ }
+ } while (ret == -1 && errno == EINTR);
+
+ return;
+}
+
+static int rbd_aio_flush_cb(void *opaque)
+{
+ BDRVRBDState *s = opaque;
+
+ return (s->qemu_aio_count > 0) ? 1 : 0;
+}
+
+
+
static int rbd_open(BlockDriverState *bs, const char *filename, int flags)
{
BDRVRBDState *s = bs->opaque;
@@ -303,6 +334,15 @@ static int rbd_open(BlockDriverState *bs, const
char *filename, int flags)
s->size = header->image_size;
s->objsize = 1 << header->options.order;
+ s->efd = eventfd(0, 0);
+ if (s->efd == -1) {
+ error_report("error opening eventfd");
+ goto failed;
+ }
+ fcntl(s->efd, F_SETFL, O_NONBLOCK);
+ qemu_aio_set_fd_handler(s->efd, rbd_aio_completion_cb, NULL,
+ rbd_aio_flush_cb, NULL, s);
+
return 0;