typedef enum {
RBD_AIO_READ,
RBD_AIO_WRITE,
- RBD_AIO_DISCARD
+ RBD_AIO_DISCARD,
+ RBD_AIO_FLUSH
} RBDAIOCmd;
typedef struct RBDAIOCB {
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;
#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,
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);
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;
}
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)
return 0;
#endif
}
+#endif
static int qemu_rbd_getinfo(BlockDriverState *bs, BlockDriverInfo *bdi)
{
.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,