ceph/rbd block driver for qemu-kvm (v3)
diff mbox

Message ID 4C1293B7.1060307@gmail.com
State New, archived
Headers show

Commit Message

Simone Gotti June 11, 2010, 7:51 p.m. UTC
None

Patch
diff mbox

diff --git a/block/rbd.c b/block/rbd.c
index 4d22069..83b7898 100644
--- a/block/rbd.c
+++ b/block/rbd.c
@@ -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;