The `qemu-img info` results for mono flat image are no longer accurate, as the "disk size" was the length of bs->file, which is not the case for multi file images (such as vmdk images with multiple files). The new field disk_size in BlockDriverState can be used by block driver to tell the exact disk size of block image (only valid if the field is set to non-zero).
Signed-off-by: Fam Zheng <famc...@gmail.com> --- block/vmdk.c | 1 + block_int.h | 1 + qemu-img.c | 6 +++++- 3 files changed, 7 insertions(+), 1 deletions(-) diff --git a/block/vmdk.c b/block/vmdk.c index 43b47e2..39c553c 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -607,6 +607,7 @@ static int vmdk_open_desc_file(BlockDriverState *bs, int flags) extent = s->extents; vmdk_parse_extents(buf, s->extents, bs->file->filename); bs->total_sectors = extent->sectors; + bs->disk_size = bdrv_getlength(bs->file) + bdrv_getlength(extent->file); // try to open parent images, if exist if (vmdk_parent_open(bs) != 0) { diff --git a/block_int.h b/block_int.h index dd8f8cb..4c58d6d 100644 --- a/block_int.h +++ b/block_int.h @@ -144,6 +144,7 @@ struct BlockDriver { struct BlockDriverState { int64_t total_sectors; /* if we are reading a disk image, give its size in sectors */ + int64_t disk_size; /* if non-zero, holds the disk size of image */ int read_only; /* if true, the media is read only */ int keep_read_only; /* if true, the media was requested to stay read only */ int open_flags; /* flags used to open the file, re-used for re-open */ diff --git a/qemu-img.c b/qemu-img.c index 4f162d1..7ea8faf 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -1067,7 +1067,11 @@ static int img_info(int argc, char **argv) bdrv_get_format(bs, fmt_name, sizeof(fmt_name)); bdrv_get_geometry(bs, &total_sectors); get_human_readable_size(size_buf, sizeof(size_buf), total_sectors * 512); - allocated_size = get_allocated_file_size(filename); + if (bs->disk_size) { + allocated_size = bs->disk_size; + } else { + allocated_size = get_allocated_file_size(filename); + } if (allocated_size < 0) { snprintf(dsize_buf, sizeof(dsize_buf), "unavailable"); } else {