-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1 iQIcBAABAgAGBQJXFlyRAAoJEL2+eyfA3jBXVSoP/iU/1FzrNeDTKtCkmUAXdzb4 ixhvEvwhAQJQ19SHIK31FTD+hfEZO7hV9XKIDlzOPG5Qy4K2dVQEEjrgruWp3eHs 2wrOVUqN366KVw2db2JFrd2aGMJq3d84nYHlGauYa/hTxAEoptGIuyHE0ACMrF76 Kv0APsYlAPwU1Qmkr0GnNz7Cbfrlec+gq7ZL7vxj4odOcdQCtc1JdUpvK3BmFunh k+hIooUEzK7/6EUjpgjEjlbNQELdXhm8fnLXAS7/RA32LML1heg7W696BS4EkFcI NospLIzwmQU+6HkSaq3TDK4rf7f84N3Cxf8aFFZB+aatmhfu37lacKYsGJXga10M GWkj7T6JNZMH9eB5J67Garv0lwYxVSGxK+VrNqH/EcHGkzFerGAQbTXzzfkfrr5J rGrcD+bctjLWk4HXU1MyZ0PLjgva9dRinYBCSIM5KK1v6yc4mwSAwuIuf4uQIlkL gDBvqtzd9BPHWwOjO20Txk+sinz+No+ZPOHdPw1yRU/zJR0gtFytFnxx1xvtOvfX k94/aOQq+BBFY/hx3bI2fWI5zz0uS8Yf8WQ21Da2oirCLTOQqbpRd+7ZprcyugCE MQzY2om4y5b6aIKvvnU2e5BZbiHkagOmlTdf8nBietixEi8anizJT4AGLCGPgMeE Ur+TxJYxnm5yavYnB5/e =QJoE -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/cody/tags/block-pull-request' into staging # gpg: Signature made Tue 19 Apr 2016 17:28:01 BST using RSA key ID C0DE3057 # gpg: Good signature from "Jeffrey Cody <jcody@redhat.com>" # gpg: aka "Jeffrey Cody <jeff@codyprime.org>" # gpg: aka "Jeffrey Cody <codyprime@gmail.com>" * remotes/cody/tags/block-pull-request: block/gluster: prevent data loss after i/o error block/gluster: code movement of qemu_gluster_close() block/gluster: return correct error value Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
fe98b18b6f
@ -247,7 +247,7 @@ static void gluster_finish_aiocb(struct glfs_fd *fd, ssize_t ret, void *arg)
|
|||||||
if (!ret || ret == acb->size) {
|
if (!ret || ret == acb->size) {
|
||||||
acb->ret = 0; /* Success */
|
acb->ret = 0; /* Success */
|
||||||
} else if (ret < 0) {
|
} else if (ret < 0) {
|
||||||
acb->ret = ret; /* Read/Write failed */
|
acb->ret = -errno; /* Read/Write failed */
|
||||||
} else {
|
} else {
|
||||||
acb->ret = -EIO; /* Partial read/write - fail it */
|
acb->ret = -EIO; /* Partial read/write - fail it */
|
||||||
}
|
}
|
||||||
@ -314,6 +314,23 @@ static int qemu_gluster_open(BlockDriverState *bs, QDict *options,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_GLUSTERFS_XLATOR_OPT
|
||||||
|
/* Without this, if fsync fails for a recoverable reason (for instance,
|
||||||
|
* ENOSPC), gluster will dump its cache, preventing retries. This means
|
||||||
|
* almost certain data loss. Not all gluster versions support the
|
||||||
|
* 'resync-failed-syncs-after-fsync' key value, but there is no way to
|
||||||
|
* discover during runtime if it is supported (this api returns success for
|
||||||
|
* unknown key/value pairs) */
|
||||||
|
ret = glfs_set_xlator_option(s->glfs, "*-write-behind",
|
||||||
|
"resync-failed-syncs-after-fsync",
|
||||||
|
"on");
|
||||||
|
if (ret < 0) {
|
||||||
|
error_setg_errno(errp, errno, "Unable to set xlator key/value pair");
|
||||||
|
ret = -errno;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
qemu_gluster_parse_flags(bdrv_flags, &open_flags);
|
qemu_gluster_parse_flags(bdrv_flags, &open_flags);
|
||||||
|
|
||||||
s->fd = glfs_open(s->glfs, gconf->image, open_flags);
|
s->fd = glfs_open(s->glfs, gconf->image, open_flags);
|
||||||
@ -366,6 +383,16 @@ static int qemu_gluster_reopen_prepare(BDRVReopenState *state,
|
|||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_GLUSTERFS_XLATOR_OPT
|
||||||
|
ret = glfs_set_xlator_option(reop_s->glfs, "*-write-behind",
|
||||||
|
"resync-failed-syncs-after-fsync", "on");
|
||||||
|
if (ret < 0) {
|
||||||
|
error_setg_errno(errp, errno, "Unable to set xlator key/value pair");
|
||||||
|
ret = -errno;
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
reop_s->fd = glfs_open(reop_s->glfs, gconf->image, open_flags);
|
reop_s->fd = glfs_open(reop_s->glfs, gconf->image, open_flags);
|
||||||
if (reop_s->fd == NULL) {
|
if (reop_s->fd == NULL) {
|
||||||
/* reops->glfs will be cleaned up in _abort */
|
/* reops->glfs will be cleaned up in _abort */
|
||||||
@ -589,6 +616,17 @@ static coroutine_fn int qemu_gluster_co_writev(BlockDriverState *bs,
|
|||||||
return qemu_gluster_co_rw(bs, sector_num, nb_sectors, qiov, 1);
|
return qemu_gluster_co_rw(bs, sector_num, nb_sectors, qiov, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void qemu_gluster_close(BlockDriverState *bs)
|
||||||
|
{
|
||||||
|
BDRVGlusterState *s = bs->opaque;
|
||||||
|
|
||||||
|
if (s->fd) {
|
||||||
|
glfs_close(s->fd);
|
||||||
|
s->fd = NULL;
|
||||||
|
}
|
||||||
|
glfs_fini(s->glfs);
|
||||||
|
}
|
||||||
|
|
||||||
static coroutine_fn int qemu_gluster_co_flush_to_disk(BlockDriverState *bs)
|
static coroutine_fn int qemu_gluster_co_flush_to_disk(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
@ -602,11 +640,35 @@ static coroutine_fn int qemu_gluster_co_flush_to_disk(BlockDriverState *bs)
|
|||||||
|
|
||||||
ret = glfs_fsync_async(s->fd, gluster_finish_aiocb, &acb);
|
ret = glfs_fsync_async(s->fd, gluster_finish_aiocb, &acb);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return -errno;
|
ret = -errno;
|
||||||
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
qemu_coroutine_yield();
|
qemu_coroutine_yield();
|
||||||
|
if (acb.ret < 0) {
|
||||||
|
ret = acb.ret;
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
return acb.ret;
|
return acb.ret;
|
||||||
|
|
||||||
|
error:
|
||||||
|
/* Some versions of Gluster (3.5.6 -> 3.5.8?) will not retain its cache
|
||||||
|
* after a fsync failure, so we have no way of allowing the guest to safely
|
||||||
|
* continue. Gluster versions prior to 3.5.6 don't retain the cache
|
||||||
|
* either, but will invalidate the fd on error, so this is again our only
|
||||||
|
* option.
|
||||||
|
*
|
||||||
|
* The 'resync-failed-syncs-after-fsync' xlator option for the
|
||||||
|
* write-behind cache will cause later gluster versions to retain its
|
||||||
|
* cache after error, so long as the fd remains open. However, we
|
||||||
|
* currently have no way of knowing if this option is supported.
|
||||||
|
*
|
||||||
|
* TODO: Once gluster provides a way for us to determine if the option
|
||||||
|
* is supported, bypass the closure and setting drv to NULL. */
|
||||||
|
qemu_gluster_close(bs);
|
||||||
|
bs->drv = NULL;
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_GLUSTERFS_DISCARD
|
#ifdef CONFIG_GLUSTERFS_DISCARD
|
||||||
@ -661,17 +723,6 @@ static int64_t qemu_gluster_allocated_file_size(BlockDriverState *bs)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void qemu_gluster_close(BlockDriverState *bs)
|
|
||||||
{
|
|
||||||
BDRVGlusterState *s = bs->opaque;
|
|
||||||
|
|
||||||
if (s->fd) {
|
|
||||||
glfs_close(s->fd);
|
|
||||||
s->fd = NULL;
|
|
||||||
}
|
|
||||||
glfs_fini(s->glfs);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int qemu_gluster_has_zero_init(BlockDriverState *bs)
|
static int qemu_gluster_has_zero_init(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
/* GlusterFS volume could be backed by a block device */
|
/* GlusterFS volume could be backed by a block device */
|
||||||
|
8
configure
vendored
8
configure
vendored
@ -298,6 +298,7 @@ coroutine=""
|
|||||||
coroutine_pool=""
|
coroutine_pool=""
|
||||||
seccomp=""
|
seccomp=""
|
||||||
glusterfs=""
|
glusterfs=""
|
||||||
|
glusterfs_xlator_opt="no"
|
||||||
glusterfs_discard="no"
|
glusterfs_discard="no"
|
||||||
glusterfs_zerofill="no"
|
glusterfs_zerofill="no"
|
||||||
archipelago="no"
|
archipelago="no"
|
||||||
@ -3400,6 +3401,9 @@ if test "$glusterfs" != "no" ; then
|
|||||||
glusterfs="yes"
|
glusterfs="yes"
|
||||||
glusterfs_cflags=`$pkg_config --cflags glusterfs-api`
|
glusterfs_cflags=`$pkg_config --cflags glusterfs-api`
|
||||||
glusterfs_libs=`$pkg_config --libs glusterfs-api`
|
glusterfs_libs=`$pkg_config --libs glusterfs-api`
|
||||||
|
if $pkg_config --atleast-version=4 glusterfs-api; then
|
||||||
|
glusterfs_xlator_opt="yes"
|
||||||
|
fi
|
||||||
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
|
||||||
@ -5342,6 +5346,10 @@ if test "$glusterfs" = "yes" ; then
|
|||||||
echo "GLUSTERFS_LIBS=$glusterfs_libs" >> $config_host_mak
|
echo "GLUSTERFS_LIBS=$glusterfs_libs" >> $config_host_mak
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if test "$glusterfs_xlator_opt" = "yes" ; then
|
||||||
|
echo "CONFIG_GLUSTERFS_XLATOR_OPT=y" >> $config_host_mak
|
||||||
|
fi
|
||||||
|
|
||||||
if test "$glusterfs_discard" = "yes" ; then
|
if test "$glusterfs_discard" = "yes" ; then
|
||||||
echo "CONFIG_GLUSTERFS_DISCARD=y" >> $config_host_mak
|
echo "CONFIG_GLUSTERFS_DISCARD=y" >> $config_host_mak
|
||||||
fi
|
fi
|
||||||
|
Loading…
Reference in New Issue
Block a user