qcow2: extract preallocation calculation function
Calculating the preallocated image size will be needed to implement .bdrv_measure(). Extract the code out into a separate function. Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> Reviewed-by: Alberto Garcia <berto@igalia.com> Message-id: 20170705125738.8777-4-stefanha@redhat.com Signed-off-by: Max Reitz <mreitz@redhat.com>
This commit is contained in:
parent
a843a22a82
commit
95c67e3bd7
@ -2537,44 +2537,19 @@ static int preallocate(BlockDriverState *bs)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int qcow2_create2(const char *filename, int64_t total_size,
|
||||
const char *backing_file, const char *backing_format,
|
||||
int flags, size_t cluster_size, PreallocMode prealloc,
|
||||
QemuOpts *opts, int version, int refcount_order,
|
||||
const char *encryptfmt, Error **errp)
|
||||
{
|
||||
int cluster_bits;
|
||||
QDict *options;
|
||||
|
||||
/* Calculate cluster_bits */
|
||||
cluster_bits = ctz32(cluster_size);
|
||||
if (cluster_bits < MIN_CLUSTER_BITS || cluster_bits > MAX_CLUSTER_BITS ||
|
||||
(1 << cluster_bits) != cluster_size)
|
||||
{
|
||||
error_setg(errp, "Cluster size must be a power of two between %d and "
|
||||
"%dk", 1 << MIN_CLUSTER_BITS, 1 << (MAX_CLUSTER_BITS - 10));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Open the image file and write a minimal qcow2 header.
|
||||
/**
|
||||
* qcow2_calc_prealloc_size:
|
||||
* @total_size: virtual disk size in bytes
|
||||
* @cluster_size: cluster size in bytes
|
||||
* @refcount_order: refcount bits power-of-2 exponent
|
||||
*
|
||||
* We keep things simple and start with a zero-sized image. We also
|
||||
* do without refcount blocks or a L1 table for now. We'll fix the
|
||||
* inconsistency later.
|
||||
*
|
||||
* We do need a refcount table because growing the refcount table means
|
||||
* allocating two new refcount blocks - the seconds of which would be at
|
||||
* 2 GB for 64k clusters, and we don't want to have a 2 GB initial file
|
||||
* size for any qcow2 image.
|
||||
* Returns: Total number of bytes required for the fully allocated image
|
||||
* (including metadata).
|
||||
*/
|
||||
BlockBackend *blk;
|
||||
QCowHeader *header;
|
||||
uint64_t* refcount_table;
|
||||
Error *local_err = NULL;
|
||||
int ret;
|
||||
|
||||
if (prealloc == PREALLOC_MODE_FULL || prealloc == PREALLOC_MODE_FALLOC) {
|
||||
static int64_t qcow2_calc_prealloc_size(int64_t total_size,
|
||||
size_t cluster_size,
|
||||
int refcount_order)
|
||||
{
|
||||
/* Note: The following calculation does not need to be exact; if it is a
|
||||
* bit off, either some bytes will be "leaked" (which is fine) or we
|
||||
* will need to increase the file size by some bytes (which is fine,
|
||||
@ -2583,6 +2558,7 @@ static int qcow2_create2(const char *filename, int64_t total_size,
|
||||
int64_t meta_size = 0;
|
||||
uint64_t nreftablee, nrefblocke, nl1e, nl2e, refblock_count;
|
||||
int64_t aligned_total_size = align_offset(total_size, cluster_size);
|
||||
int cluster_bits = ctz32(cluster_size);
|
||||
int refblock_bits, refblock_size;
|
||||
/* refcount entry size in bytes */
|
||||
double rces = (1 << refcount_order) / 8.;
|
||||
@ -2632,8 +2608,50 @@ static int qcow2_create2(const char *filename, int64_t total_size,
|
||||
cluster_size / sizeof(uint64_t));
|
||||
meta_size += nreftablee * sizeof(uint64_t);
|
||||
|
||||
qemu_opt_set_number(opts, BLOCK_OPT_SIZE,
|
||||
aligned_total_size + meta_size, &error_abort);
|
||||
return meta_size + aligned_total_size;
|
||||
}
|
||||
|
||||
static int qcow2_create2(const char *filename, int64_t total_size,
|
||||
const char *backing_file, const char *backing_format,
|
||||
int flags, size_t cluster_size, PreallocMode prealloc,
|
||||
QemuOpts *opts, int version, int refcount_order,
|
||||
const char *encryptfmt, Error **errp)
|
||||
{
|
||||
int cluster_bits;
|
||||
QDict *options;
|
||||
|
||||
/* Calculate cluster_bits */
|
||||
cluster_bits = ctz32(cluster_size);
|
||||
if (cluster_bits < MIN_CLUSTER_BITS || cluster_bits > MAX_CLUSTER_BITS ||
|
||||
(1 << cluster_bits) != cluster_size)
|
||||
{
|
||||
error_setg(errp, "Cluster size must be a power of two between %d and "
|
||||
"%dk", 1 << MIN_CLUSTER_BITS, 1 << (MAX_CLUSTER_BITS - 10));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Open the image file and write a minimal qcow2 header.
|
||||
*
|
||||
* We keep things simple and start with a zero-sized image. We also
|
||||
* do without refcount blocks or a L1 table for now. We'll fix the
|
||||
* inconsistency later.
|
||||
*
|
||||
* We do need a refcount table because growing the refcount table means
|
||||
* allocating two new refcount blocks - the seconds of which would be at
|
||||
* 2 GB for 64k clusters, and we don't want to have a 2 GB initial file
|
||||
* size for any qcow2 image.
|
||||
*/
|
||||
BlockBackend *blk;
|
||||
QCowHeader *header;
|
||||
uint64_t* refcount_table;
|
||||
Error *local_err = NULL;
|
||||
int ret;
|
||||
|
||||
if (prealloc == PREALLOC_MODE_FULL || prealloc == PREALLOC_MODE_FALLOC) {
|
||||
int64_t prealloc_size =
|
||||
qcow2_calc_prealloc_size(total_size, cluster_size, refcount_order);
|
||||
qemu_opt_set_number(opts, BLOCK_OPT_SIZE, prealloc_size, &error_abort);
|
||||
qemu_opt_set(opts, BLOCK_OPT_PREALLOC, PreallocMode_lookup[prealloc],
|
||||
&error_abort);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user