mirror of https://gitee.com/openkylin/qemu.git
block: Fix reopen flag inheritance
When reopening an image, the block layer already takes care to reopen bs->file as well with recalculated inherited flags. The same must happen for any other child (most notably missing before this patch: backing files). If bs->file (or any other child) didn't originally inherit from bs, e.g. because it was created separately and then only referenced, it must not inherit flags on reopen either, so check the inherited_from field before propagation the reopen down. VMDK already reopened its extents manually; this code can now be dropped. Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com>
This commit is contained in:
parent
bddcec3745
commit
67251a3113
13
block.c
13
block.c
|
@ -1615,6 +1615,8 @@ BlockReopenQueue *bdrv_reopen_queue(BlockReopenQueue *bs_queue,
|
|||
assert(bs != NULL);
|
||||
|
||||
BlockReopenQueueEntry *bs_entry;
|
||||
BdrvChild *child;
|
||||
|
||||
if (bs_queue == NULL) {
|
||||
bs_queue = g_new0(BlockReopenQueue, 1);
|
||||
QSIMPLEQ_INIT(bs_queue);
|
||||
|
@ -1623,8 +1625,15 @@ BlockReopenQueue *bdrv_reopen_queue(BlockReopenQueue *bs_queue,
|
|||
/* bdrv_open() masks this flag out */
|
||||
flags &= ~BDRV_O_PROTOCOL;
|
||||
|
||||
if (bs->file) {
|
||||
bdrv_reopen_queue(bs_queue, bs->file, bdrv_inherited_flags(flags));
|
||||
QLIST_FOREACH(child, &bs->children, next) {
|
||||
int child_flags;
|
||||
|
||||
if (child->bs->inherits_from != bs) {
|
||||
continue;
|
||||
}
|
||||
|
||||
child_flags = child->role->inherit_flags(flags);
|
||||
bdrv_reopen_queue(bs_queue, child->bs, child_flags);
|
||||
}
|
||||
|
||||
bs_entry = g_new0(BlockReopenQueueEntry, 1);
|
||||
|
|
28
block/vmdk.c
28
block/vmdk.c
|
@ -321,37 +321,13 @@ static int vmdk_is_cid_valid(BlockDriverState *bs)
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* Queue extents, if any, for reopen() */
|
||||
/* We have nothing to do for VMDK reopen, stubs just return success */
|
||||
static int vmdk_reopen_prepare(BDRVReopenState *state,
|
||||
BlockReopenQueue *queue, Error **errp)
|
||||
{
|
||||
BDRVVmdkState *s;
|
||||
int ret = -1;
|
||||
int i;
|
||||
VmdkExtent *e;
|
||||
|
||||
assert(state != NULL);
|
||||
assert(state->bs != NULL);
|
||||
|
||||
if (queue == NULL) {
|
||||
error_setg(errp, "No reopen queue for VMDK extents");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
s = state->bs->opaque;
|
||||
|
||||
assert(s != NULL);
|
||||
|
||||
for (i = 0; i < s->num_extents; i++) {
|
||||
e = &s->extents[i];
|
||||
if (e->file != state->bs->file) {
|
||||
bdrv_reopen_queue(queue, e->file, state->flags);
|
||||
}
|
||||
}
|
||||
ret = 0;
|
||||
|
||||
exit:
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vmdk_parent_open(BlockDriverState *bs)
|
||||
|
|
Loading…
Reference in New Issue