mirror of https://github.com/xemu-project/xemu.git
RBD: Add support readv,writev for rbd
Rbd can do readv and writev directly, so wo do not need to transform iov to buf or vice versa any more. Signed-off-by: tianqing <tianqing@unitedstack.com> Reviewed-by: Jeff Cody <jcody@redhat.com> Signed-off-by: Jeff Cody <jcody@redhat.com>
This commit is contained in:
parent
ef503a8417
commit
1d393bdeae
80
block/rbd.c
80
block/rbd.c
|
@ -62,6 +62,13 @@
|
||||||
#define RBD_MAX_SNAP_NAME_SIZE 128
|
#define RBD_MAX_SNAP_NAME_SIZE 128
|
||||||
#define RBD_MAX_SNAPS 100
|
#define RBD_MAX_SNAPS 100
|
||||||
|
|
||||||
|
/* The LIBRBD_SUPPORTS_IOVEC is defined in librbd.h */
|
||||||
|
#ifdef LIBRBD_SUPPORTS_IOVEC
|
||||||
|
#define LIBRBD_USE_IOVEC 1
|
||||||
|
#else
|
||||||
|
#define LIBRBD_USE_IOVEC 0
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
RBD_AIO_READ,
|
RBD_AIO_READ,
|
||||||
RBD_AIO_WRITE,
|
RBD_AIO_WRITE,
|
||||||
|
@ -310,6 +317,17 @@ static int qemu_rbd_set_conf(rados_t cluster, const char *conf,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void qemu_rbd_memset(RADOSCB *rcb, int64_t offs)
|
||||||
|
{
|
||||||
|
if (LIBRBD_USE_IOVEC) {
|
||||||
|
RBDAIOCB *acb = rcb->acb;
|
||||||
|
iov_memset(acb->qiov->iov, acb->qiov->niov, offs, 0,
|
||||||
|
acb->qiov->size - offs);
|
||||||
|
} else {
|
||||||
|
memset(rcb->buf + offs, 0, rcb->size - offs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int qemu_rbd_create(const char *filename, QemuOpts *opts, Error **errp)
|
static int qemu_rbd_create(const char *filename, QemuOpts *opts, Error **errp)
|
||||||
{
|
{
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
|
@ -426,11 +444,11 @@ static void qemu_rbd_complete_aio(RADOSCB *rcb)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
memset(rcb->buf, 0, rcb->size);
|
qemu_rbd_memset(rcb, 0);
|
||||||
acb->ret = r;
|
acb->ret = r;
|
||||||
acb->error = 1;
|
acb->error = 1;
|
||||||
} else if (r < rcb->size) {
|
} else if (r < rcb->size) {
|
||||||
memset(rcb->buf + r, 0, rcb->size - r);
|
qemu_rbd_memset(rcb, r);
|
||||||
if (!acb->error) {
|
if (!acb->error) {
|
||||||
acb->ret = rcb->size;
|
acb->ret = rcb->size;
|
||||||
}
|
}
|
||||||
|
@ -441,10 +459,13 @@ static void qemu_rbd_complete_aio(RADOSCB *rcb)
|
||||||
|
|
||||||
g_free(rcb);
|
g_free(rcb);
|
||||||
|
|
||||||
if (acb->cmd == RBD_AIO_READ) {
|
if (!LIBRBD_USE_IOVEC) {
|
||||||
qemu_iovec_from_buf(acb->qiov, 0, acb->bounce, acb->qiov->size);
|
if (acb->cmd == RBD_AIO_READ) {
|
||||||
|
qemu_iovec_from_buf(acb->qiov, 0, acb->bounce, acb->qiov->size);
|
||||||
|
}
|
||||||
|
qemu_vfree(acb->bounce);
|
||||||
}
|
}
|
||||||
qemu_vfree(acb->bounce);
|
|
||||||
acb->common.cb(acb->common.opaque, (acb->ret > 0 ? 0 : acb->ret));
|
acb->common.cb(acb->common.opaque, (acb->ret > 0 ? 0 : acb->ret));
|
||||||
|
|
||||||
qemu_aio_unref(acb);
|
qemu_aio_unref(acb);
|
||||||
|
@ -655,7 +676,6 @@ static BlockAIOCB *rbd_start_aio(BlockDriverState *bs,
|
||||||
RBDAIOCB *acb;
|
RBDAIOCB *acb;
|
||||||
RADOSCB *rcb = NULL;
|
RADOSCB *rcb = NULL;
|
||||||
rbd_completion_t c;
|
rbd_completion_t c;
|
||||||
char *buf;
|
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
BDRVRBDState *s = bs->opaque;
|
BDRVRBDState *s = bs->opaque;
|
||||||
|
@ -664,27 +684,29 @@ static BlockAIOCB *rbd_start_aio(BlockDriverState *bs,
|
||||||
acb->cmd = cmd;
|
acb->cmd = cmd;
|
||||||
acb->qiov = qiov;
|
acb->qiov = qiov;
|
||||||
assert(!qiov || qiov->size == size);
|
assert(!qiov || qiov->size == size);
|
||||||
if (cmd == RBD_AIO_DISCARD || cmd == RBD_AIO_FLUSH) {
|
|
||||||
acb->bounce = NULL;
|
rcb = g_new(RADOSCB, 1);
|
||||||
} else {
|
|
||||||
acb->bounce = qemu_try_blockalign(bs, qiov->size);
|
if (!LIBRBD_USE_IOVEC) {
|
||||||
if (acb->bounce == NULL) {
|
if (cmd == RBD_AIO_DISCARD || cmd == RBD_AIO_FLUSH) {
|
||||||
goto failed;
|
acb->bounce = NULL;
|
||||||
|
} else {
|
||||||
|
acb->bounce = qemu_try_blockalign(bs, qiov->size);
|
||||||
|
if (acb->bounce == NULL) {
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (cmd == RBD_AIO_WRITE) {
|
||||||
|
qemu_iovec_to_buf(acb->qiov, 0, acb->bounce, qiov->size);
|
||||||
|
}
|
||||||
|
rcb->buf = acb->bounce;
|
||||||
}
|
}
|
||||||
|
|
||||||
acb->ret = 0;
|
acb->ret = 0;
|
||||||
acb->error = 0;
|
acb->error = 0;
|
||||||
acb->s = s;
|
acb->s = s;
|
||||||
|
|
||||||
if (cmd == RBD_AIO_WRITE) {
|
|
||||||
qemu_iovec_to_buf(acb->qiov, 0, acb->bounce, qiov->size);
|
|
||||||
}
|
|
||||||
|
|
||||||
buf = acb->bounce;
|
|
||||||
|
|
||||||
rcb = g_new(RADOSCB, 1);
|
|
||||||
rcb->acb = acb;
|
rcb->acb = acb;
|
||||||
rcb->buf = buf;
|
|
||||||
rcb->s = acb->s;
|
rcb->s = acb->s;
|
||||||
rcb->size = size;
|
rcb->size = size;
|
||||||
r = rbd_aio_create_completion(rcb, (rbd_callback_t) rbd_finish_aiocb, &c);
|
r = rbd_aio_create_completion(rcb, (rbd_callback_t) rbd_finish_aiocb, &c);
|
||||||
|
@ -694,10 +716,18 @@ static BlockAIOCB *rbd_start_aio(BlockDriverState *bs,
|
||||||
|
|
||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case RBD_AIO_WRITE:
|
case RBD_AIO_WRITE:
|
||||||
r = rbd_aio_write(s->image, off, size, buf, c);
|
#ifdef LIBRBD_SUPPORTS_IOVEC
|
||||||
|
r = rbd_aio_writev(s->image, qiov->iov, qiov->niov, off, c);
|
||||||
|
#else
|
||||||
|
r = rbd_aio_write(s->image, off, size, rcb->buf, c);
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
case RBD_AIO_READ:
|
case RBD_AIO_READ:
|
||||||
r = rbd_aio_read(s->image, off, size, buf, c);
|
#ifdef LIBRBD_SUPPORTS_IOVEC
|
||||||
|
r = rbd_aio_readv(s->image, qiov->iov, qiov->niov, off, c);
|
||||||
|
#else
|
||||||
|
r = rbd_aio_read(s->image, off, size, rcb->buf, c);
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
case RBD_AIO_DISCARD:
|
case RBD_AIO_DISCARD:
|
||||||
r = rbd_aio_discard_wrapper(s->image, off, size, c);
|
r = rbd_aio_discard_wrapper(s->image, off, size, c);
|
||||||
|
@ -712,14 +742,16 @@ static BlockAIOCB *rbd_start_aio(BlockDriverState *bs,
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
goto failed_completion;
|
goto failed_completion;
|
||||||
}
|
}
|
||||||
|
|
||||||
return &acb->common;
|
return &acb->common;
|
||||||
|
|
||||||
failed_completion:
|
failed_completion:
|
||||||
rbd_aio_release(c);
|
rbd_aio_release(c);
|
||||||
failed:
|
failed:
|
||||||
g_free(rcb);
|
g_free(rcb);
|
||||||
qemu_vfree(acb->bounce);
|
if (!LIBRBD_USE_IOVEC) {
|
||||||
|
qemu_vfree(acb->bounce);
|
||||||
|
}
|
||||||
|
|
||||||
qemu_aio_unref(acb);
|
qemu_aio_unref(acb);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue