The commit and the mirror block job must be able to drop their filter
node at any point. However, this will not be possible if any of the
BdrvChild links to them is frozen. Therefore, we need to prevent them
from ever becoming frozen.
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com>
Reviewed-by: Alberto Garcia <berto@igalia.com>
Message-id:
20190703172813.6868-2-mreitz@redhat.com
Signed-off-by: Max Reitz <mreitz@redhat.com>
return -EPERM;
}
+ for (i = bs; i != base; i = backing_bs(i)) {
+ if (i->backing && backing_bs(i)->never_freeze) {
+ error_setg(errp, "Cannot freeze '%s' link to '%s'",
+ i->backing->name, backing_bs(i)->node_name);
+ return -EPERM;
+ }
+ }
+
for (i = bs; i != base; i = backing_bs(i)) {
if (i->backing) {
i->backing->frozen = true;
if (!filter_node_name) {
commit_top_bs->implicit = true;
}
+
+ /* So that we can always drop this node */
+ commit_top_bs->never_freeze = true;
+
commit_top_bs->total_sectors = top->total_sectors;
bdrv_append(commit_top_bs, top, &local_err);
if (!filter_node_name) {
mirror_top_bs->implicit = true;
}
+
+ /* So that we can always drop this node */
+ mirror_top_bs->never_freeze = true;
+
mirror_top_bs->total_sectors = bs->total_sectors;
mirror_top_bs->supported_write_flags = BDRV_REQ_WRITE_UNCHANGED;
mirror_top_bs->supported_zero_flags = BDRV_REQ_WRITE_UNCHANGED |
/* Only read/written by whoever has set active_flush_req to true. */
unsigned int flushed_gen; /* Flushed write generation */
+
+ /* BdrvChild links to this node may never be frozen */
+ bool never_freeze;
};
struct BlockBackendRootState {