gluster: Implement .bdrv_co_write_zeroes for gluster
Support .bdrv_co_write_zeroes() from gluster driver by using GlusterFS API glfs_zerofill() that off-loads the writing of zeroes to GlusterFS server. Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
15744b0b8f
commit
7c815372f3
|
@ -236,6 +236,25 @@ static void qemu_gluster_complete_aio(void *opaque)
|
||||||
qemu_coroutine_enter(acb->coroutine, NULL);
|
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 */
|
/* TODO Convert to fine grained options */
|
||||||
static QemuOptsList runtime_opts = {
|
static QemuOptsList runtime_opts = {
|
||||||
.name = "gluster",
|
.name = "gluster",
|
||||||
|
@ -308,6 +327,35 @@ out:
|
||||||
return ret;
|
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,
|
static int qemu_gluster_create(const char *filename,
|
||||||
QEMUOptionParameter *options, Error **errp)
|
QEMUOptionParameter *options, Error **errp)
|
||||||
{
|
{
|
||||||
|
@ -350,25 +398,6 @@ out:
|
||||||
return ret;
|
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,
|
static coroutine_fn int qemu_gluster_co_rw(BlockDriverState *bs,
|
||||||
int64_t sector_num, int nb_sectors, QEMUIOVector *qiov, int write)
|
int64_t sector_num, int nb_sectors, QEMUIOVector *qiov, int write)
|
||||||
{
|
{
|
||||||
|
@ -551,6 +580,9 @@ static BlockDriver bdrv_gluster = {
|
||||||
.bdrv_has_zero_init = qemu_gluster_has_zero_init,
|
.bdrv_has_zero_init = qemu_gluster_has_zero_init,
|
||||||
#ifdef CONFIG_GLUSTERFS_DISCARD
|
#ifdef CONFIG_GLUSTERFS_DISCARD
|
||||||
.bdrv_co_discard = qemu_gluster_co_discard,
|
.bdrv_co_discard = qemu_gluster_co_discard,
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_GLUSTERFS_ZEROFILL
|
||||||
|
.bdrv_co_write_zeroes = qemu_gluster_co_write_zeroes,
|
||||||
#endif
|
#endif
|
||||||
.create_options = qemu_gluster_create_options,
|
.create_options = qemu_gluster_create_options,
|
||||||
};
|
};
|
||||||
|
@ -572,6 +604,9 @@ static BlockDriver bdrv_gluster_tcp = {
|
||||||
.bdrv_has_zero_init = qemu_gluster_has_zero_init,
|
.bdrv_has_zero_init = qemu_gluster_has_zero_init,
|
||||||
#ifdef CONFIG_GLUSTERFS_DISCARD
|
#ifdef CONFIG_GLUSTERFS_DISCARD
|
||||||
.bdrv_co_discard = qemu_gluster_co_discard,
|
.bdrv_co_discard = qemu_gluster_co_discard,
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_GLUSTERFS_ZEROFILL
|
||||||
|
.bdrv_co_write_zeroes = qemu_gluster_co_write_zeroes,
|
||||||
#endif
|
#endif
|
||||||
.create_options = qemu_gluster_create_options,
|
.create_options = qemu_gluster_create_options,
|
||||||
};
|
};
|
||||||
|
@ -593,6 +628,9 @@ static BlockDriver bdrv_gluster_unix = {
|
||||||
.bdrv_has_zero_init = qemu_gluster_has_zero_init,
|
.bdrv_has_zero_init = qemu_gluster_has_zero_init,
|
||||||
#ifdef CONFIG_GLUSTERFS_DISCARD
|
#ifdef CONFIG_GLUSTERFS_DISCARD
|
||||||
.bdrv_co_discard = qemu_gluster_co_discard,
|
.bdrv_co_discard = qemu_gluster_co_discard,
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_GLUSTERFS_ZEROFILL
|
||||||
|
.bdrv_co_write_zeroes = qemu_gluster_co_write_zeroes,
|
||||||
#endif
|
#endif
|
||||||
.create_options = qemu_gluster_create_options,
|
.create_options = qemu_gluster_create_options,
|
||||||
};
|
};
|
||||||
|
@ -614,6 +652,9 @@ static BlockDriver bdrv_gluster_rdma = {
|
||||||
.bdrv_has_zero_init = qemu_gluster_has_zero_init,
|
.bdrv_has_zero_init = qemu_gluster_has_zero_init,
|
||||||
#ifdef CONFIG_GLUSTERFS_DISCARD
|
#ifdef CONFIG_GLUSTERFS_DISCARD
|
||||||
.bdrv_co_discard = qemu_gluster_co_discard,
|
.bdrv_co_discard = qemu_gluster_co_discard,
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_GLUSTERFS_ZEROFILL
|
||||||
|
.bdrv_co_write_zeroes = qemu_gluster_co_write_zeroes,
|
||||||
#endif
|
#endif
|
||||||
.create_options = qemu_gluster_create_options,
|
.create_options = qemu_gluster_create_options,
|
||||||
};
|
};
|
||||||
|
|
|
@ -256,6 +256,7 @@ coroutine_pool=""
|
||||||
seccomp=""
|
seccomp=""
|
||||||
glusterfs=""
|
glusterfs=""
|
||||||
glusterfs_discard="no"
|
glusterfs_discard="no"
|
||||||
|
glusterfs_zerofill="no"
|
||||||
virtio_blk_data_plane=""
|
virtio_blk_data_plane=""
|
||||||
gtk=""
|
gtk=""
|
||||||
gtkabi="2.0"
|
gtkabi="2.0"
|
||||||
|
@ -2701,6 +2702,9 @@ if test "$glusterfs" != "no" ; then
|
||||||
if $pkg_config --atleast-version=5 glusterfs-api; then
|
if $pkg_config --atleast-version=5 glusterfs-api; then
|
||||||
glusterfs_discard="yes"
|
glusterfs_discard="yes"
|
||||||
fi
|
fi
|
||||||
|
if $pkg_config --atleast-version=6 glusterfs-api; then
|
||||||
|
glusterfs_zerofill="yes"
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
if test "$glusterfs" = "yes" ; then
|
if test "$glusterfs" = "yes" ; then
|
||||||
feature_not_found "GlusterFS backend support"
|
feature_not_found "GlusterFS backend support"
|
||||||
|
@ -4229,6 +4233,10 @@ if test "$glusterfs_discard" = "yes" ; then
|
||||||
echo "CONFIG_GLUSTERFS_DISCARD=y" >> $config_host_mak
|
echo "CONFIG_GLUSTERFS_DISCARD=y" >> $config_host_mak
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if test "$glusterfs_zerofill" = "yes" ; then
|
||||||
|
echo "CONFIG_GLUSTERFS_ZEROFILL=y" >> $config_host_mak
|
||||||
|
fi
|
||||||
|
|
||||||
if test "$libssh2" = "yes" ; then
|
if test "$libssh2" = "yes" ; then
|
||||||
echo "CONFIG_LIBSSH2=y" >> $config_host_mak
|
echo "CONFIG_LIBSSH2=y" >> $config_host_mak
|
||||||
fi
|
fi
|
||||||
|
|
Loading…
Reference in New Issue