/*
* Return true if at least one of the backing links between @bs and
* @base is frozen. @errp is set if that's the case.
+ * @base must be reachable from @bs, or NULL.
*/
bool bdrv_is_backing_chain_frozen(BlockDriverState *bs, BlockDriverState *base,
Error **errp)
{
BlockDriverState *i;
- for (i = bs; i != base && i->backing; i = backing_bs(i)) {
- if (i->backing->frozen) {
+ for (i = bs; i != base; i = backing_bs(i)) {
+ if (i->backing && i->backing->frozen) {
error_setg(errp, "Cannot change '%s' link from '%s' to '%s'",
i->backing->name, i->node_name,
backing_bs(i)->node_name);
* Freeze all backing links between @bs and @base.
* If any of the links is already frozen the operation is aborted and
* none of the links are modified.
+ * @base must be reachable from @bs, or NULL.
* Returns 0 on success. On failure returns < 0 and sets @errp.
*/
int bdrv_freeze_backing_chain(BlockDriverState *bs, BlockDriverState *base,
return -EPERM;
}
- for (i = bs; i != base && i->backing; i = backing_bs(i)) {
- i->backing->frozen = true;
+ for (i = bs; i != base; i = backing_bs(i)) {
+ if (i->backing) {
+ i->backing->frozen = true;
+ }
}
return 0;
/*
* Unfreeze all backing links between @bs and @base. The caller must
* ensure that all links are frozen before using this function.
+ * @base must be reachable from @bs, or NULL.
*/
void bdrv_unfreeze_backing_chain(BlockDriverState *bs, BlockDriverState *base)
{
BlockDriverState *i;
- for (i = bs; i != base && i->backing; i = backing_bs(i)) {
- assert(i->backing->frozen);
- i->backing->frozen = false;
+ for (i = bs; i != base; i = backing_bs(i)) {
+ if (i->backing) {
+ assert(i->backing->frozen);
+ i->backing->frozen = false;
+ }
}
}
QLIST_FOREACH_SAFE(c, &top->parents, next_parent, next) {
/* Check whether we are allowed to switch c from top to base */
GSList *ignore_children = g_slist_prepend(NULL, c);
- bdrv_check_update_perm(base, NULL, c->perm, c->shared_perm,
- ignore_children, &local_err);
+ ret = bdrv_check_update_perm(base, NULL, c->perm, c->shared_perm,
+ ignore_children, &local_err);
g_slist_free(ignore_children);
- if (local_err) {
- ret = -EPERM;
+ if (ret < 0) {
error_report_err(local_err);
goto exit;
}