typedef struct RBDAIOCB {
BlockAIOCB common;
- QEMUBH *bh;
int64_t ret;
QEMUIOVector *qiov;
char *bounce;
rados_conf_read_file(cluster, NULL);
} else if (conf[0] != '\0' &&
qemu_rbd_set_conf(cluster, conf, true, &local_err) < 0) {
- rados_shutdown(cluster);
error_propagate(errp, local_err);
- return -EIO;
+ ret = -EIO;
+ goto shutdown;
}
if (conf[0] != '\0' &&
qemu_rbd_set_conf(cluster, conf, false, &local_err) < 0) {
- rados_shutdown(cluster);
error_propagate(errp, local_err);
- return -EIO;
+ ret = -EIO;
+ goto shutdown;
}
if (qemu_rbd_set_auth(cluster, secretid, errp) < 0) {
- rados_shutdown(cluster);
- return -EIO;
+ ret = -EIO;
+ goto shutdown;
}
ret = rados_connect(cluster);
if (ret < 0) {
error_setg_errno(errp, -ret, "error connecting");
- rados_shutdown(cluster);
- return ret;
+ goto shutdown;
}
ret = rados_ioctx_create(cluster, pool, &io_ctx);
if (ret < 0) {
error_setg_errno(errp, -ret, "error opening pool %s", pool);
- rados_shutdown(cluster);
- return ret;
+ goto shutdown;
}
ret = rbd_create(io_ctx, name, bytes, &obj_order);
- rados_ioctx_destroy(io_ctx);
- rados_shutdown(cluster);
if (ret < 0) {
error_setg_errno(errp, -ret, "error rbd create");
- return ret;
}
+ rados_ioctx_destroy(io_ctx);
+
+shutdown:
+ rados_shutdown(cluster);
return ret;
}
static void rbd_finish_bh(void *opaque)
{
RADOSCB *rcb = opaque;
- qemu_bh_delete(rcb->acb->bh);
qemu_rbd_complete_aio(rcb);
}
rcb->ret = rbd_aio_get_return_value(c);
rbd_aio_release(c);
- acb->bh = aio_bh_new(bdrv_get_aio_context(acb->common.bs),
- rbd_finish_bh, rcb);
- qemu_bh_schedule(acb->bh);
+ aio_bh_schedule_oneshot(bdrv_get_aio_context(acb->common.bs),
+ rbd_finish_bh, rcb);
}
static int rbd_aio_discard_wrapper(rbd_image_t image,
}
static BlockAIOCB *rbd_start_aio(BlockDriverState *bs,
- int64_t sector_num,
+ int64_t off,
QEMUIOVector *qiov,
- int nb_sectors,
+ int64_t size,
BlockCompletionFunc *cb,
void *opaque,
RBDAIOCmd cmd)
RBDAIOCB *acb;
RADOSCB *rcb = NULL;
rbd_completion_t c;
- int64_t off, size;
char *buf;
int r;
acb = qemu_aio_get(&rbd_aiocb_info, bs, cb, opaque);
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->ret = 0;
acb->error = 0;
acb->s = s;
- acb->bh = NULL;
if (cmd == RBD_AIO_WRITE) {
qemu_iovec_to_buf(acb->qiov, 0, acb->bounce, qiov->size);
buf = acb->bounce;
- off = sector_num * BDRV_SECTOR_SIZE;
- size = nb_sectors * BDRV_SECTOR_SIZE;
-
rcb = g_new(RADOSCB, 1);
rcb->acb = acb;
rcb->buf = buf;
BlockCompletionFunc *cb,
void *opaque)
{
- return rbd_start_aio(bs, sector_num, qiov, nb_sectors, cb, opaque,
+ return rbd_start_aio(bs, sector_num << BDRV_SECTOR_BITS, qiov,
+ (int64_t) nb_sectors << BDRV_SECTOR_BITS, cb, opaque,
RBD_AIO_READ);
}
BlockCompletionFunc *cb,
void *opaque)
{
- return rbd_start_aio(bs, sector_num, qiov, nb_sectors, cb, opaque,
+ return rbd_start_aio(bs, sector_num << BDRV_SECTOR_BITS, qiov,
+ (int64_t) nb_sectors << BDRV_SECTOR_BITS, cb, opaque,
RBD_AIO_WRITE);
}
}
#ifdef LIBRBD_SUPPORTS_DISCARD
-static BlockAIOCB* qemu_rbd_aio_discard(BlockDriverState *bs,
- int64_t sector_num,
- int nb_sectors,
- BlockCompletionFunc *cb,
- void *opaque)
+static BlockAIOCB *qemu_rbd_aio_pdiscard(BlockDriverState *bs,
+ int64_t offset,
+ int count,
+ BlockCompletionFunc *cb,
+ void *opaque)
{
- return rbd_start_aio(bs, sector_num, NULL, nb_sectors, cb, opaque,
+ return rbd_start_aio(bs, offset, NULL, count, cb, opaque,
RBD_AIO_DISCARD);
}
#endif
#endif
#ifdef LIBRBD_SUPPORTS_DISCARD
- .bdrv_aio_discard = qemu_rbd_aio_discard,
+ .bdrv_aio_pdiscard = qemu_rbd_aio_pdiscard,
#endif
.bdrv_snapshot_create = qemu_rbd_snap_create,