Commit 72706ea4 authored by Jeff Cody's avatar Jeff Cody Committed by Kevin Wolf

block: resize backing file image during offline commit, if necessary

Currently, if an image file is logically larger than its backing file,
committing it via 'qemu-img commit' will fail.

For instance, if we have a base image with a virtual size 10G, and a
snapshot image of size 20G, then committing the snapshot offline with
'qemu-img commit' will likely fail.

This will automatically attempt to resize the base image, if the
snapshot image to be committed is larger.
Signed-off-by: default avatarJeff Cody <>
Reviewed-by: default avatarFam Zheng <>
Reviewed-by: default avatarEric Blake <>
Reviewed-by: default avatarBenoit Canet <>
Signed-off-by: default avatarKevin Wolf <>
parent 031fd1be
......@@ -2030,10 +2030,10 @@ int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res, BdrvCheckMode fix)
int bdrv_commit(BlockDriverState *bs)
BlockDriver *drv = bs->drv;
int64_t sector, total_sectors;
int64_t sector, total_sectors, length, backing_length;
int n, ro, open_flags;
int ret = 0;
uint8_t *buf;
uint8_t *buf = NULL;
char filename[PATH_MAX];
if (!drv)
......@@ -2058,7 +2058,29 @@ int bdrv_commit(BlockDriverState *bs)
total_sectors = bdrv_getlength(bs) >> BDRV_SECTOR_BITS;
length = bdrv_getlength(bs);
if (length < 0) {
ret = length;
goto ro_cleanup;
backing_length = bdrv_getlength(bs->backing_hd);
if (backing_length < 0) {
ret = backing_length;
goto ro_cleanup;
/* If our top snapshot is larger than the backing file image,
* grow the backing file image if possible. If not possible,
* we must return an error */
if (length > backing_length) {
ret = bdrv_truncate(bs->backing_hd, length);
if (ret < 0) {
goto ro_cleanup;
total_sectors = length >> BDRV_SECTOR_BITS;
for (sector = 0; sector < total_sectors; sector += n) {
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment