diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c index 7d3fde5a8a..42f971b590 100644 --- a/block/qcow2-snapshot.c +++ b/block/qcow2-snapshot.c @@ -48,6 +48,7 @@ typedef struct QEMU_PACKED QCowSnapshotHeader { typedef struct QEMU_PACKED QCowSnapshotExtraData { uint64_t vm_state_size_large; + uint64_t disk_size; } QCowSnapshotExtraData; void qcow2_free_snapshots(BlockDriverState *bs) @@ -117,6 +118,12 @@ int qcow2_read_snapshots(BlockDriverState *bs) sn->vm_state_size = be64_to_cpu(extra.vm_state_size_large); } + if (extra_data_size >= 16) { + sn->disk_size = be64_to_cpu(extra.disk_size); + } else { + sn->disk_size = bs->total_sectors * BDRV_SECTOR_SIZE; + } + /* Read snapshot ID */ sn->id_str = g_malloc(id_str_size + 1); ret = bdrv_pread(bs->file, offset, sn->id_str, id_str_size); @@ -197,6 +204,7 @@ static int qcow2_write_snapshots(BlockDriverState *bs) memset(&extra, 0, sizeof(extra)); extra.vm_state_size_large = cpu_to_be64(sn->vm_state_size); + extra.disk_size = cpu_to_be64(sn->disk_size); id_str_size = strlen(sn->id_str); name_size = strlen(sn->name); @@ -330,6 +338,7 @@ int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info) sn->id_str = g_strdup(sn_info->id_str); sn->name = g_strdup(sn_info->name); + sn->disk_size = bs->total_sectors * BDRV_SECTOR_SIZE; sn->vm_state_size = sn_info->vm_state_size; sn->date_sec = sn_info->date_sec; sn->date_nsec = sn_info->date_nsec; @@ -426,6 +435,13 @@ int qcow2_snapshot_goto(BlockDriverState *bs, const char *snapshot_id) } sn = &s->snapshots[snapshot_index]; + if (sn->disk_size != bs->total_sectors * BDRV_SECTOR_SIZE) { + error_report("qcow2: Loading snapshots with different disk " + "size is not implemented"); + ret = -ENOTSUP; + goto fail; + } + /* * Make sure that the current L1 table is big enough to contain the whole * L1 table of the snapshot. If the snapshot L1 table is smaller, the diff --git a/block/qcow2.h b/block/qcow2.h index e4ac366cfc..ddb976a759 100644 --- a/block/qcow2.h +++ b/block/qcow2.h @@ -78,6 +78,7 @@ typedef struct QCowSnapshot { uint32_t l1_size; char *id_str; char *name; + uint64_t disk_size; uint64_t vm_state_size; uint32_t date_sec; uint32_t date_nsec;