On 15.03.2017 10:29, Stefan Hajnoczi wrote: > Use qcow2_calc_prealloc_size() to get the required file size. > > Signed-off-by: Stefan Hajnoczi <stefa...@redhat.com> > --- > TODO: > * Query block status and only count allocated clusters if in_bs != NULL > * Exclude backing file clusters if in_bs != NULL and -o backing_file= > is given > --- > block/qcow2.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 53 insertions(+) > > diff --git a/block/qcow2.c b/block/qcow2.c > index 19be468..a4caf97 100644 > --- a/block/qcow2.c > +++ b/block/qcow2.c > @@ -2940,6 +2940,58 @@ static coroutine_fn int > qcow2_co_flush_to_os(BlockDriverState *bs) > return 0; > } > > +static void qcow2_measure(QemuOpts *opts, BlockDriverState *in_bs, > + BlockMeasureInfo *info, Error **errp) > +{ > + Error *local_err = NULL; > + uint64_t allocated_bytes = 0; > + uint64_t prealloc_size; > + uint64_t size; > + uint64_t refcount_bits; > + size_t cluster_size; > + int version; > + > + size = ROUND_UP(qemu_opt_get_size_del(opts, BLOCK_OPT_SIZE, 0), > + BDRV_SECTOR_SIZE); > + > + cluster_size = qcow2_opt_get_cluster_size_del(opts, &local_err); > + if (local_err) { > + goto err; > + } > + > + version = qcow2_opt_get_version_del(opts, &local_err); > + if (local_err) { > + goto err; > + } > + > + refcount_bits = qcow2_opt_get_refcount_bits_del(opts, version, > &local_err); > + if (local_err) { > + goto err; > + } > + > + if (in_bs) { > + int64_t ssize = bdrv_getlength(in_bs); > + if (ssize < 0) { > + error_setg_errno(errp, -ssize, "Unable to get image size"); > + return; > + } > + > + size = ssize; > + > + /* TODO How many clusters are allocated modulo backing file in opts? > */ > + } > + > + prealloc_size = qcow2_calc_prealloc_size(size, cluster_size, > + ctz32(refcount_bits)); > + info->required_bytes = prealloc_size - (align_offset(size, cluster_size) > - > + allocated_bytes);
But what if @opts contains a preallocation option? Max > + info->fully_allocated_bytes = prealloc_size; > + return; > + > +err: > + error_propagate(errp, local_err); > +} > + > static int qcow2_get_info(BlockDriverState *bs, BlockDriverInfo *bdi) > { > BDRVQcow2State *s = bs->opaque; > @@ -3487,6 +3539,7 @@ BlockDriver bdrv_qcow2 = { > .bdrv_snapshot_delete = qcow2_snapshot_delete, > .bdrv_snapshot_list = qcow2_snapshot_list, > .bdrv_snapshot_load_tmp = qcow2_snapshot_load_tmp, > + .bdrv_measure = qcow2_measure, > .bdrv_get_info = qcow2_get_info, > .bdrv_get_specific_info = qcow2_get_specific_info, > >
signature.asc
Description: OpenPGP digital signature