qemu_coroutine_enter(acb->coroutine, NULL);
}
+/*
+ * AIO callback routine called from GlusterFS thread.
+ */
+static void gluster_finish_aiocb(struct glfs_fd *fd, ssize_t ret, void *arg)
+{
+ GlusterAIOCB *acb = (GlusterAIOCB *)arg;
+
+ if (!ret || ret == acb->size) {
+ acb->ret = 0; /* Success */
+ } else if (ret < 0) {
+ acb->ret = ret; /* Read/Write failed */
+ } else {
+ acb->ret = -EIO; /* Partial read/write - fail it */
+ }
+
+ acb->bh = qemu_bh_new(qemu_gluster_complete_aio, acb);
+ qemu_bh_schedule(acb->bh);
+}
+
/* TODO Convert to fine grained options */
static QemuOptsList runtime_opts = {
.name = "gluster",
return ret;
}
+#ifdef CONFIG_GLUSTERFS_ZEROFILL
+static coroutine_fn int qemu_gluster_co_write_zeroes(BlockDriverState *bs,
+ int64_t sector_num, int nb_sectors, BdrvRequestFlags flags)
+{
+ int ret;
+ GlusterAIOCB *acb = g_slice_new(GlusterAIOCB);
+ BDRVGlusterState *s = bs->opaque;
+ off_t size = nb_sectors * BDRV_SECTOR_SIZE;
+ off_t offset = sector_num * BDRV_SECTOR_SIZE;
+
+ acb->size = size;
+ acb->ret = 0;
+ acb->coroutine = qemu_coroutine_self();
+
+ ret = glfs_zerofill_async(s->fd, offset, size, &gluster_finish_aiocb, acb);
+ if (ret < 0) {
+ ret = -errno;
+ goto out;
+ }
+
+ qemu_coroutine_yield();
+ ret = acb->ret;
+
+out:
+ g_slice_free(GlusterAIOCB, acb);
+ return ret;
+}
+#endif
+
static int qemu_gluster_create(const char *filename,
QEMUOptionParameter *options, Error **errp)
{
return ret;
}
-/*
- * AIO callback routine called from GlusterFS thread.
- */
-static void gluster_finish_aiocb(struct glfs_fd *fd, ssize_t ret, void *arg)
-{
- GlusterAIOCB *acb = (GlusterAIOCB *)arg;
-
- if (!ret || ret == acb->size) {
- acb->ret = 0; /* Success */
- } else if (ret < 0) {
- acb->ret = ret; /* Read/Write failed */
- } else {
- acb->ret = -EIO; /* Partial read/write - fail it */
- }
-
- acb->bh = qemu_bh_new(qemu_gluster_complete_aio, acb);
- qemu_bh_schedule(acb->bh);
-}
-
static coroutine_fn int qemu_gluster_co_rw(BlockDriverState *bs,
int64_t sector_num, int nb_sectors, QEMUIOVector *qiov, int write)
{
#ifdef CONFIG_GLUSTERFS_DISCARD
.bdrv_co_discard = qemu_gluster_co_discard,
#endif
+#ifdef CONFIG_GLUSTERFS_ZEROFILL
+ .bdrv_co_write_zeroes = qemu_gluster_co_write_zeroes,
+#endif
.create_options = qemu_gluster_create_options,
};
#ifdef CONFIG_GLUSTERFS_DISCARD
.bdrv_co_discard = qemu_gluster_co_discard,
#endif
+#ifdef CONFIG_GLUSTERFS_ZEROFILL
+ .bdrv_co_write_zeroes = qemu_gluster_co_write_zeroes,
+#endif
.create_options = qemu_gluster_create_options,
};
#ifdef CONFIG_GLUSTERFS_DISCARD
.bdrv_co_discard = qemu_gluster_co_discard,
#endif
+#ifdef CONFIG_GLUSTERFS_ZEROFILL
+ .bdrv_co_write_zeroes = qemu_gluster_co_write_zeroes,
+#endif
.create_options = qemu_gluster_create_options,
};
#ifdef CONFIG_GLUSTERFS_DISCARD
.bdrv_co_discard = qemu_gluster_co_discard,
#endif
+#ifdef CONFIG_GLUSTERFS_ZEROFILL
+ .bdrv_co_write_zeroes = qemu_gluster_co_write_zeroes,
+#endif
.create_options = qemu_gluster_create_options,
};