@@ -2327,6 +2327,24 @@ static void bdrv_child_abort_perm_update(BdrvChild *c)
bdrv_abort_perm_update(c->bs);
}
+static int bdrv_refresh_perms(BlockDriverState *bs, bool *tighten_restrictions,
+ Error **errp)
+{
+ int ret;
+ uint64_t perm, shared_perm;
+
+ bdrv_get_cumulative_perm(bs, &perm, &shared_perm);
+ ret = bdrv_check_perm(bs, NULL, perm, shared_perm, NULL,
+ tighten_restrictions, errp);
+ if (ret < 0) {
+ bdrv_abort_perm_update(bs);
+ return ret;
+ }
+ bdrv_set_perm(bs, perm, shared_perm);
+
+ return 0;
+}
+
int bdrv_child_try_set_perm(BdrvChild *c, uint64_t perm, uint64_t shared,
Error **errp)
{
@@ -2642,22 +2660,15 @@ static void bdrv_replace_child(BdrvChild *child, BlockDriverState *new_bs)
}
if (old_bs) {
- /* Update permissions for old node. This is guaranteed to succeed
- * because we're just taking a parent away, so we're loosening
- * restrictions. */
bool tighten_restrictions;
- int ret;
- bdrv_get_cumulative_perm(old_bs, &perm, &shared_perm);
- ret = bdrv_check_perm(old_bs, NULL, perm, shared_perm, NULL,
- &tighten_restrictions, NULL);
+ /*
+ * Update permissions for old node. We're just taking a parent away, so
+ * we're loosening restrictions. Errors of permission update are not
+ * fatal in this case, ignore them.
+ */
+ bdrv_refresh_perms(old_bs, &tighten_restrictions, NULL);
assert(tighten_restrictions == false);
- if (ret < 0) {
- /* We only tried to loosen restrictions, so errors are not fatal */
- bdrv_abort_perm_update(old_bs);
- } else {
- bdrv_set_perm(old_bs, perm, shared_perm);
- }
/* When the parent requiring a non-default AioContext is removed, the
* node moves back to the main AioContext */
@@ -5781,7 +5792,6 @@ void bdrv_init_with_whitelist(void)
int coroutine_fn bdrv_co_invalidate_cache(BlockDriverState *bs, Error **errp)
{
BdrvChild *child, *parent;
- uint64_t perm, shared_perm;
Error *local_err = NULL;
int ret;
BdrvDirtyBitmap *bm;
@@ -5813,14 +5823,11 @@ int coroutine_fn bdrv_co_invalidate_cache(BlockDriverState *bs, Error **errp)
*/
if (bs->open_flags & BDRV_O_INACTIVE) {
bs->open_flags &= ~BDRV_O_INACTIVE;
- bdrv_get_cumulative_perm(bs, &perm, &shared_perm);
- ret = bdrv_check_perm(bs, NULL, perm, shared_perm, NULL, NULL, errp);
+ ret = bdrv_refresh_perms(bs, NULL, errp);
if (ret < 0) {
- bdrv_abort_perm_update(bs);
bs->open_flags |= BDRV_O_INACTIVE;
return ret;
}
- bdrv_set_perm(bs, perm, shared_perm);
if (bs->drv->bdrv_co_invalidate_cache) {
bs->drv->bdrv_co_invalidate_cache(bs, &local_err);
@@ -5896,7 +5903,6 @@ static int bdrv_inactivate_recurse(BlockDriverState *bs)
{
BdrvChild *child, *parent;
bool tighten_restrictions;
- uint64_t perm, shared_perm;
int ret;
if (!bs->drv) {
@@ -5930,18 +5936,13 @@ static int bdrv_inactivate_recurse(BlockDriverState *bs)
bs->open_flags |= BDRV_O_INACTIVE;
- /* Update permissions, they may differ for inactive nodes */
- bdrv_get_cumulative_perm(bs, &perm, &shared_perm);
- ret = bdrv_check_perm(bs, NULL, perm, shared_perm, NULL,
- &tighten_restrictions, NULL);
+ /*
+ * Update permissions, they may differ for inactive nodes.
+ * We only tried to loosen restrictions, so errors are not fatal, ignore
+ * them.
+ */
+ bdrv_refresh_perms(bs, &tighten_restrictions, NULL);
assert(tighten_restrictions == false);
- if (ret < 0) {
- /* We only tried to loosen restrictions, so errors are not fatal */
- bdrv_abort_perm_update(bs);
- } else {
- bdrv_set_perm(bs, perm, shared_perm);
- }
-
/* Recursively inactivate children */
QLIST_FOREACH(child, &bs->children, next) {