[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-block] [PULL 09/27] block: Handle permission errors in change_pare
From: |
Kevin Wolf |
Subject: |
[Qemu-block] [PULL 09/27] block: Handle permission errors in change_parent_backing_link() |
Date: |
Tue, 7 Mar 2017 16:40:33 +0100 |
Instead of just trying to change parents by parent over to reference @to
instead of @from, and abort()ing whenever the permissions don't allow
this, do proper permission checking beforehand and pass any error to the
callers.
Signed-off-by: Kevin Wolf <address@hidden>
Reviewed-by: Fam Zheng <address@hidden>
Reviewed-by: Eric Blake <address@hidden>
---
block.c | 50 ++++++++++++++++++++++++++++++++++++++++++++------
1 file changed, 44 insertions(+), 6 deletions(-)
diff --git a/block.c b/block.c
index a7b09d3..a310132 100644
--- a/block.c
+++ b/block.c
@@ -2933,21 +2933,53 @@ static bool should_update_child(BdrvChild *c,
BlockDriverState *to)
}
static void change_parent_backing_link(BlockDriverState *from,
- BlockDriverState *to)
+ BlockDriverState *to, Error **errp)
{
BdrvChild *c, *next;
+ GSList *list = NULL, *p;
+ uint64_t old_perm, old_shared;
+ uint64_t perm = 0, shared = BLK_PERM_ALL;
+ int ret;
+
+ /* Make sure that @from doesn't go away until we have successfully attached
+ * all of its parents to @to. */
+ bdrv_ref(from);
+ /* Put all parents into @list and calculate their cumulative permissions */
QLIST_FOREACH_SAFE(c, &from->parents, next_parent, next) {
if (!should_update_child(c, to)) {
continue;
}
+ list = g_slist_prepend(list, c);
+ perm |= c->perm;
+ shared &= c->shared_perm;
+ }
+
+ /* Check whether the required permissions can be granted on @to, ignoring
+ * all BdrvChild in @list so that they can't block themselves. */
+ ret = bdrv_check_update_perm(to, perm, shared, list, errp);
+ if (ret < 0) {
+ bdrv_abort_perm_update(to);
+ goto out;
+ }
+
+ /* Now actually perform the change. We performed the permission check for
+ * all elements of @list at once, so set the permissions all at once at the
+ * very end. */
+ for (p = list; p != NULL; p = p->next) {
+ c = p->data;
bdrv_ref(to);
- /* FIXME Are we sure that bdrv_replace_child() can't run into
- * &error_abort because of permissions? */
- bdrv_replace_child(c, to, true);
+ bdrv_replace_child_noperm(c, to);
bdrv_unref(from);
}
+
+ bdrv_get_cumulative_perm(to, &old_perm, &old_shared);
+ bdrv_set_perm(to, old_perm | perm, old_shared | shared);
+
+out:
+ g_slist_free(list);
+ bdrv_unref(from);
}
/*
@@ -2980,7 +3012,12 @@ void bdrv_append(BlockDriverState *bs_new,
BlockDriverState *bs_top,
goto out;
}
- change_parent_backing_link(bs_top, bs_new);
+ change_parent_backing_link(bs_top, bs_new, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ bdrv_set_backing_hd(bs_new, NULL, &error_abort);
+ goto out;
+ }
/* bs_new is now referenced by its new parents, we don't need the
* additional reference any more. */
@@ -2995,7 +3032,8 @@ void bdrv_replace_in_backing_chain(BlockDriverState *old,
BlockDriverState *new)
bdrv_ref(old);
- change_parent_backing_link(old, new);
+ /* FIXME Proper error handling */
+ change_parent_backing_link(old, new, &error_abort);
bdrv_unref(old);
}
--
1.8.3.1
- [Qemu-block] [PULL 00/27] Block layer fixes for 2.9.0-rc0, Kevin Wolf, 2017/03/07
- [Qemu-block] [PULL 03/27] mirror: Fix permissions for removing mirror_top_bs, Kevin Wolf, 2017/03/07
- [Qemu-block] [PULL 01/27] commit: Fix error handling, Kevin Wolf, 2017/03/07
- [Qemu-block] [PULL 02/27] mirror: Fix permission problem with 'replaces', Kevin Wolf, 2017/03/07
- [Qemu-block] [PULL 05/27] block: Fix blockdev-snapshot error handling, Kevin Wolf, 2017/03/07
- [Qemu-block] [PULL 04/27] mirror: Fix error path for dirty bitmap creation, Kevin Wolf, 2017/03/07
- [Qemu-block] [PULL 07/27] block: Factor out bdrv_replace_child_noperm(), Kevin Wolf, 2017/03/07
- [Qemu-block] [PULL 06/27] block: Factor out should_update_child(), Kevin Wolf, 2017/03/07
- [Qemu-block] [PULL 08/27] block: Ignore multiple children in bdrv_check_update_perm(), Kevin Wolf, 2017/03/07
- [Qemu-block] [PULL 11/27] sheepdog: Defuse time bomb in sd_open() error handling, Kevin Wolf, 2017/03/07
- [Qemu-block] [PULL 09/27] block: Handle permission errors in change_parent_backing_link(),
Kevin Wolf <=
- [Qemu-block] [PULL 10/27] block: Fix error handling in bdrv_replace_in_backing_chain(), Kevin Wolf, 2017/03/07
- [Qemu-block] [PULL 13/27] sheepdog: Fix error handling sd_create(), Kevin Wolf, 2017/03/07
- [Qemu-block] [PULL 14/27] sheepdog: Mark sd_snapshot_delete() lossage FIXME, Kevin Wolf, 2017/03/07
- [Qemu-block] [PULL 12/27] sheepdog: Fix error handling in sd_snapshot_delete(), Kevin Wolf, 2017/03/07
- [Qemu-block] [PULL 15/27] sheepdog: Fix snapshot ID parsing in _open(), _create, _goto(), Kevin Wolf, 2017/03/07
- [Qemu-block] [PULL 16/27] sheepdog: Don't truncate long VDI name in _open(), _create(), Kevin Wolf, 2017/03/07
- [Qemu-block] [PULL 19/27] sheepdog: Implement bdrv_parse_filename(), Kevin Wolf, 2017/03/07
- [Qemu-block] [PULL 17/27] sheepdog: Report errors in pseudo-filename more usefully, Kevin Wolf, 2017/03/07
- [Qemu-block] [PULL 18/27] sheepdog: Use SocketAddress and socket_connect(), Kevin Wolf, 2017/03/07
- [Qemu-block] [PULL 20/27] gluster: Drop assumptions on SocketTransport names, Kevin Wolf, 2017/03/07