diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2017-02-26 11:47:00 +0000 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2017-02-26 11:47:00 +0000 |
commit | 6528a4c1f20c1ba5a22ab84bec6788a574ac04c8 (patch) | |
tree | e5f61f2dd338d8937374dfe9ef459fbf1516fa89 | |
parent | 6d3f4c6d1d8eb1187dc13713c49e3986eab39e7a (diff) | |
parent | 1d393bdeae22fde2cb83c1ea719675747c85c40e (diff) | |
download | qemu-6528a4c1f20c1ba5a22ab84bec6788a574ac04c8.zip qemu-6528a4c1f20c1ba5a22ab84bec6788a574ac04c8.tar.gz qemu-6528a4c1f20c1ba5a22ab84bec6788a574ac04c8.tar.bz2 |
Merge remote-tracking branch 'remotes/cody/tags/block-pull-request' into staging
# gpg: Signature made Fri 24 Feb 2017 17:45:53 GMT
# gpg: using RSA key 0xBDBE7B27C0DE3057
# gpg: Good signature from "Jeffrey Cody <jcody@redhat.com>"
# gpg: aka "Jeffrey Cody <jeff@codyprime.org>"
# gpg: aka "Jeffrey Cody <codyprime@gmail.com>"
# Primary key fingerprint: 9957 4B4D 3474 90E7 9D98 D624 BDBE 7B27 C0DE 3057
* remotes/cody/tags/block-pull-request:
RBD: Add support readv,writev for rbd
block/nfs: try to avoid the bounce buffer in pwritev
block/nfs: convert to preadv / pwritev
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r-- | block/nfs.c | 50 | ||||
-rw-r--r-- | block/rbd.c | 80 |
2 files changed, 84 insertions, 46 deletions
diff --git a/block/nfs.c b/block/nfs.c index 0cf115e..ffb54be 100644 --- a/block/nfs.c +++ b/block/nfs.c @@ -263,9 +263,9 @@ nfs_co_generic_cb(int ret, struct nfs_context *nfs, void *data, nfs_co_generic_bh_cb, task); } -static int coroutine_fn nfs_co_readv(BlockDriverState *bs, - int64_t sector_num, int nb_sectors, - QEMUIOVector *iov) +static int coroutine_fn nfs_co_preadv(BlockDriverState *bs, uint64_t offset, + uint64_t bytes, QEMUIOVector *iov, + int flags) { NFSClient *client = bs->opaque; NFSRPC task; @@ -274,9 +274,7 @@ static int coroutine_fn nfs_co_readv(BlockDriverState *bs, task.iov = iov; if (nfs_pread_async(client->context, client->fh, - sector_num * BDRV_SECTOR_SIZE, - nb_sectors * BDRV_SECTOR_SIZE, - nfs_co_generic_cb, &task) != 0) { + offset, bytes, nfs_co_generic_cb, &task) != 0) { return -ENOMEM; } @@ -297,28 +295,34 @@ static int coroutine_fn nfs_co_readv(BlockDriverState *bs, return 0; } -static int coroutine_fn nfs_co_writev(BlockDriverState *bs, - int64_t sector_num, int nb_sectors, - QEMUIOVector *iov) +static int coroutine_fn nfs_co_pwritev(BlockDriverState *bs, uint64_t offset, + uint64_t bytes, QEMUIOVector *iov, + int flags) { NFSClient *client = bs->opaque; NFSRPC task; char *buf = NULL; + bool my_buffer = false; nfs_co_init_task(bs, &task); - buf = g_try_malloc(nb_sectors * BDRV_SECTOR_SIZE); - if (nb_sectors && buf == NULL) { - return -ENOMEM; + if (iov->niov != 1) { + buf = g_try_malloc(bytes); + if (bytes && buf == NULL) { + return -ENOMEM; + } + qemu_iovec_to_buf(iov, 0, buf, bytes); + my_buffer = true; + } else { + buf = iov->iov[0].iov_base; } - qemu_iovec_to_buf(iov, 0, buf, nb_sectors * BDRV_SECTOR_SIZE); - if (nfs_pwrite_async(client->context, client->fh, - sector_num * BDRV_SECTOR_SIZE, - nb_sectors * BDRV_SECTOR_SIZE, - buf, nfs_co_generic_cb, &task) != 0) { - g_free(buf); + offset, bytes, buf, + nfs_co_generic_cb, &task) != 0) { + if (my_buffer) { + g_free(buf); + } return -ENOMEM; } @@ -327,9 +331,11 @@ static int coroutine_fn nfs_co_writev(BlockDriverState *bs, qemu_coroutine_yield(); } - g_free(buf); + if (my_buffer) { + g_free(buf); + } - if (task.ret != nb_sectors * BDRV_SECTOR_SIZE) { + if (task.ret != bytes) { return task.ret < 0 ? task.ret : -EIO; } @@ -861,8 +867,8 @@ static BlockDriver bdrv_nfs = { .bdrv_create = nfs_file_create, .bdrv_reopen_prepare = nfs_reopen_prepare, - .bdrv_co_readv = nfs_co_readv, - .bdrv_co_writev = nfs_co_writev, + .bdrv_co_preadv = nfs_co_preadv, + .bdrv_co_pwritev = nfs_co_pwritev, .bdrv_co_flush_to_disk = nfs_co_flush, .bdrv_detach_aio_context = nfs_detach_aio_context, diff --git a/block/rbd.c b/block/rbd.c index a57b3e3..22e8e69 100644 --- a/block/rbd.c +++ b/block/rbd.c @@ -62,6 +62,13 @@ #define RBD_MAX_SNAP_NAME_SIZE 128 #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 { RBD_AIO_READ, RBD_AIO_WRITE, @@ -310,6 +317,17 @@ static int qemu_rbd_set_conf(rados_t cluster, const char *conf, 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) { Error *local_err = NULL; @@ -426,11 +444,11 @@ static void qemu_rbd_complete_aio(RADOSCB *rcb) } } else { if (r < 0) { - memset(rcb->buf, 0, rcb->size); + qemu_rbd_memset(rcb, 0); acb->ret = r; acb->error = 1; } else if (r < rcb->size) { - memset(rcb->buf + r, 0, rcb->size - r); + qemu_rbd_memset(rcb, r); if (!acb->error) { acb->ret = rcb->size; } @@ -441,10 +459,13 @@ static void qemu_rbd_complete_aio(RADOSCB *rcb) g_free(rcb); - if (acb->cmd == RBD_AIO_READ) { - qemu_iovec_from_buf(acb->qiov, 0, acb->bounce, acb->qiov->size); + if (!LIBRBD_USE_IOVEC) { + 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)); qemu_aio_unref(acb); @@ -655,7 +676,6 @@ static BlockAIOCB *rbd_start_aio(BlockDriverState *bs, RBDAIOCB *acb; RADOSCB *rcb = NULL; rbd_completion_t c; - char *buf; int r; BDRVRBDState *s = bs->opaque; @@ -664,27 +684,29 @@ static BlockAIOCB *rbd_start_aio(BlockDriverState *bs, acb->cmd = cmd; acb->qiov = qiov; assert(!qiov || qiov->size == size); - if (cmd == RBD_AIO_DISCARD || cmd == RBD_AIO_FLUSH) { - acb->bounce = NULL; - } else { - acb->bounce = qemu_try_blockalign(bs, qiov->size); - if (acb->bounce == NULL) { - goto failed; + + rcb = g_new(RADOSCB, 1); + + if (!LIBRBD_USE_IOVEC) { + if (cmd == RBD_AIO_DISCARD || cmd == RBD_AIO_FLUSH) { + 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->error = 0; 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->buf = buf; rcb->s = acb->s; rcb->size = size; 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) { 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; 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; case RBD_AIO_DISCARD: r = rbd_aio_discard_wrapper(s->image, off, size, c); @@ -712,14 +742,16 @@ static BlockAIOCB *rbd_start_aio(BlockDriverState *bs, if (r < 0) { goto failed_completion; } - return &acb->common; failed_completion: rbd_aio_release(c); failed: g_free(rcb); - qemu_vfree(acb->bounce); + if (!LIBRBD_USE_IOVEC) { + qemu_vfree(acb->bounce); + } + qemu_aio_unref(acb); return NULL; } |