mirror of
https://github.com/mii443/qemu.git
synced 2025-12-03 11:08:25 +00:00
mirror: Deal with filters
This includes some permission limiting (for example, we only need to take the RESIZE permission for active commits where the base is smaller than the top). base_overlay is introduced so we can query bdrv_is_allocated_above() on it - we cannot do that with base itself, because a filter's block_status is the same as its child node, so if there are filters on base, bdrv_is_allocated_above() on base would return information including base. Use this opportunity to rename qmp_drive_mirror()'s "source" BDS to "target_backing_bs", because that is what it really refers to. Signed-off-by: Max Reitz <mreitz@redhat.com>
This commit is contained in:
32
blockdev.c
32
blockdev.c
@@ -2899,6 +2899,7 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
|
||||
bool has_auto_dismiss, bool auto_dismiss,
|
||||
Error **errp)
|
||||
{
|
||||
BlockDriverState *unfiltered_bs;
|
||||
int job_flags = JOB_DEFAULT;
|
||||
|
||||
if (!has_speed) {
|
||||
@@ -2950,10 +2951,19 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
|
||||
return;
|
||||
}
|
||||
|
||||
if (!bs->backing && sync == MIRROR_SYNC_MODE_TOP) {
|
||||
if (!bdrv_backing_chain_next(bs) && sync == MIRROR_SYNC_MODE_TOP) {
|
||||
sync = MIRROR_SYNC_MODE_FULL;
|
||||
}
|
||||
|
||||
if (!has_replaces) {
|
||||
/* We want to mirror from @bs, but keep implicit filters on top */
|
||||
unfiltered_bs = bdrv_skip_implicit_filters(bs);
|
||||
if (unfiltered_bs != bs) {
|
||||
replaces = unfiltered_bs->node_name;
|
||||
has_replaces = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (has_replaces) {
|
||||
BlockDriverState *to_replace_bs;
|
||||
AioContext *replace_aio_context;
|
||||
@@ -3000,7 +3010,7 @@ static void blockdev_mirror_common(const char *job_id, BlockDriverState *bs,
|
||||
void qmp_drive_mirror(DriveMirror *arg, Error **errp)
|
||||
{
|
||||
BlockDriverState *bs;
|
||||
BlockDriverState *source, *target_bs;
|
||||
BlockDriverState *target_backing_bs, *target_bs;
|
||||
AioContext *aio_context;
|
||||
AioContext *old_context;
|
||||
BlockMirrorBackingMode backing_mode;
|
||||
@@ -3035,12 +3045,12 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp)
|
||||
}
|
||||
|
||||
flags = bs->open_flags | BDRV_O_RDWR;
|
||||
source = backing_bs(bs);
|
||||
if (!source && arg->sync == MIRROR_SYNC_MODE_TOP) {
|
||||
target_backing_bs = bdrv_cow_bs(bdrv_skip_filters(bs));
|
||||
if (!target_backing_bs && arg->sync == MIRROR_SYNC_MODE_TOP) {
|
||||
arg->sync = MIRROR_SYNC_MODE_FULL;
|
||||
}
|
||||
if (arg->sync == MIRROR_SYNC_MODE_NONE) {
|
||||
source = bs;
|
||||
target_backing_bs = bs;
|
||||
}
|
||||
|
||||
size = bdrv_getlength(bs);
|
||||
@@ -3066,7 +3076,7 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp)
|
||||
/* Don't open backing image in create() */
|
||||
flags |= BDRV_O_NO_BACKING;
|
||||
|
||||
if ((arg->sync == MIRROR_SYNC_MODE_FULL || !source)
|
||||
if ((arg->sync == MIRROR_SYNC_MODE_FULL || !target_backing_bs)
|
||||
&& arg->mode != NEW_IMAGE_MODE_EXISTING)
|
||||
{
|
||||
/* create new image w/o backing file */
|
||||
@@ -3074,15 +3084,19 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp)
|
||||
bdrv_img_create(arg->target, format,
|
||||
NULL, NULL, NULL, size, flags, false, &local_err);
|
||||
} else {
|
||||
/* Implicit filters should not appear in the filename */
|
||||
BlockDriverState *explicit_backing =
|
||||
bdrv_skip_implicit_filters(target_backing_bs);
|
||||
|
||||
switch (arg->mode) {
|
||||
case NEW_IMAGE_MODE_EXISTING:
|
||||
break;
|
||||
case NEW_IMAGE_MODE_ABSOLUTE_PATHS:
|
||||
/* create new image with backing file */
|
||||
bdrv_refresh_filename(source);
|
||||
bdrv_refresh_filename(explicit_backing);
|
||||
bdrv_img_create(arg->target, format,
|
||||
source->filename,
|
||||
source->drv->format_name,
|
||||
explicit_backing->filename,
|
||||
explicit_backing->drv->format_name,
|
||||
NULL, size, flags, false, &local_err);
|
||||
break;
|
||||
default:
|
||||
|
||||
Reference in New Issue
Block a user