diff options
Diffstat (limited to 'block.c')
-rw-r--r-- | block.c | 53 |
1 files changed, 16 insertions, 37 deletions
@@ -4237,7 +4237,7 @@ static int bdrv_reopen_parse_backing(BDRVReopenState *reopen_state, Error **errp) { BlockDriverState *bs = reopen_state->bs; - BlockDriverState *overlay_bs, *below_bs, *new_backing_bs; + BlockDriverState *new_backing_bs; QObject *value; const char *str; @@ -4266,6 +4266,18 @@ static int bdrv_reopen_parse_backing(BDRVReopenState *reopen_state, g_assert_not_reached(); } + if (bs->backing) { + if (bdrv_skip_implicit_filters(bs->backing->bs) == new_backing_bs) { + return 0; + } + + if (bs->backing->bs->implicit) { + error_setg(errp, "Cannot change backing link if '%s' has " + "an implicit backing file", bs->node_name); + return -EPERM; + } + } + /* * Ensure that @bs can really handle backing files, because we are * about to give it one (or swap the existing one) @@ -4283,42 +4295,9 @@ static int bdrv_reopen_parse_backing(BDRVReopenState *reopen_state, return -EINVAL; } - /* - * Find the "actual" backing file by skipping all links that point - * to an implicit node, if any (e.g. a commit filter node). - * We cannot use any of the bdrv_skip_*() functions here because - * those return the first explicit node, while we are looking for - * its overlay here. - */ - overlay_bs = bs; - for (below_bs = bdrv_filter_or_cow_bs(overlay_bs); - below_bs && below_bs->implicit; - below_bs = bdrv_filter_or_cow_bs(overlay_bs)) - { - overlay_bs = below_bs; - } - - /* If we want to replace the backing file we need some extra checks */ - if (new_backing_bs != bdrv_filter_or_cow_bs(overlay_bs)) { - int ret; - - /* Check for implicit nodes between bs and its backing file */ - if (bs != overlay_bs) { - error_setg(errp, "Cannot change backing link if '%s' has " - "an implicit backing file", bs->node_name); - return -EPERM; - } - - reopen_state->replace_backing_bs = true; - reopen_state->old_backing_bs = bs->backing ? bs->backing->bs : NULL; - ret = bdrv_set_backing_noperm(bs, new_backing_bs, set_backings_tran, - errp); - if (ret < 0) { - return ret; - } - } - - return 0; + reopen_state->replace_backing_bs = true; + reopen_state->old_backing_bs = bs->backing ? bs->backing->bs : NULL; + return bdrv_set_backing_noperm(bs, new_backing_bs, set_backings_tran, errp); } /* |