qcow2: Put qcow2_upgrade() into its own function

This does not make sense right now, but it will make sense once we need
to do more than to just update s->qcow_version.

Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-id: 20191011152814.14791-7-mreitz@redhat.com
Signed-off-by: Max Reitz <mreitz@redhat.com>
This commit is contained in:
Max Reitz 2019-10-11 17:28:04 +02:00
parent e0314b56b2
commit 722efb0c7c
1 changed files with 38 additions and 5 deletions

View File

@ -4912,12 +4912,46 @@ static int qcow2_downgrade(BlockDriverState *bs, int target_version,
return 0;
}
/*
* Upgrades an image's version. While newer versions encompass all
* features of older versions, some things may have to be presented
* differently.
*/
static int qcow2_upgrade(BlockDriverState *bs, int target_version,
BlockDriverAmendStatusCB *status_cb, void *cb_opaque,
Error **errp)
{
BDRVQcow2State *s = bs->opaque;
int current_version = s->qcow_version;
int ret;
/* This is qcow2_upgrade(), not qcow2_downgrade() */
assert(target_version > current_version);
/* There are no other versions (yet) that you can upgrade to */
assert(target_version == 3);
status_cb(bs, 0, 1, cb_opaque);
s->qcow_version = target_version;
ret = qcow2_update_header(bs);
if (ret < 0) {
s->qcow_version = current_version;
error_setg_errno(errp, -ret, "Failed to update the image header");
return ret;
}
status_cb(bs, 1, 1, cb_opaque);
return 0;
}
typedef enum Qcow2AmendOperation {
/* This is the value Qcow2AmendHelperCBInfo::last_operation will be
* statically initialized to so that the helper CB can discern the first
* invocation from an operation change */
QCOW2_NO_OPERATION = 0,
QCOW2_UPGRADING,
QCOW2_CHANGING_REFCOUNT_ORDER,
QCOW2_DOWNGRADING,
} Qcow2AmendOperation;
@ -5100,17 +5134,16 @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts,
helper_cb_info = (Qcow2AmendHelperCBInfo){
.original_status_cb = status_cb,
.original_cb_opaque = cb_opaque,
.total_operations = (new_version < old_version)
.total_operations = (new_version != old_version)
+ (s->refcount_bits != refcount_bits)
};
/* Upgrade first (some features may require compat=1.1) */
if (new_version > old_version) {
s->qcow_version = new_version;
ret = qcow2_update_header(bs);
helper_cb_info.current_operation = QCOW2_UPGRADING;
ret = qcow2_upgrade(bs, new_version, &qcow2_amend_helper_cb,
&helper_cb_info, errp);
if (ret < 0) {
s->qcow_version = old_version;
error_setg_errno(errp, -ret, "Failed to update the image header");
return ret;
}
}