qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [RFC PATCH v4 4/4] qcow2: Add full image preallocation


From: Stefan Hajnoczi
Subject: Re: [Qemu-devel] [RFC PATCH v4 4/4] qcow2: Add full image preallocation option
Date: Fri, 17 Jan 2014 16:48:16 +0800
User-agent: Mutt/1.5.21 (2010-09-15)

On Fri, Dec 27, 2013 at 11:05:54AM +0800, Hu Tao wrote:

This approach seems okay but the calculation isn't quite right yet.

On Windows an error would be raised since we don't have preallocate=full
support.  That's okay.

> @@ -1477,16 +1478,53 @@ static int qcow2_create2(const char *filename, 
> int64_t total_size,
>      Error *local_err = NULL;
>      int ret;
>  
> +    if (prealloc == PREALLOC_MODE_FULL) {
> +        int64_t meta_size = 0;
> +        unsigned nrefe, nl2e;
> +        BlockDriver *drv;
> +
> +        drv = bdrv_find_protocol(filename, true);
> +        if (drv == NULL) {
> +            error_setg(errp, "Could not find protocol for file '%s'", 
> filename);
> +            return -ENOENT;
> +        }
> +
> +        alloc_options = append_option_parameters(alloc_options,
> +                                                 drv->create_options);
> +        alloc_options = append_option_parameters(alloc_options, options);
> +
> +        /* header: 1 cluster */
> +        meta_size += cluster_size;
> +        /* total size of refblocks */
> +        nrefe = (total_size / cluster_size);
> +        nrefe = align_offset(nrefe, cluster_size / sizeof(uint16_t));
> +        meta_size += nrefe * sizeof(uint16_t);

Every host cluster is reference-counted, including metadata (even
refcount blocks are recursively included).  This calculation is wrong
because it only considers data clusters.

> +        /* total size of reftables */
> +        meta_size += nrefe * sizeof(uint16_t) * sizeof(uint16_t) / 
> cluster_size;

I don't understand this calculation.  The refcount table consists of
contiguous clusters where each element is a 64-bit offset to a refcount
block.

> +        /* total size of L2 tables */
> +        nl2e = total_size / cluster_size;
> +        nl2e = align_offset(nl2e, cluster_size / sizeof(uint64_t));
> +        meta_size += nl2e * sizeof(uint64_t);
> +        /* total size of L1 tables */
> +        meta_size += nl2e * sizeof(uint64_t) * sizeof(uint64_t) / 
> cluster_size;

Another strange calculation.  The L1 table consists of contiguous
clusters where each element is a 64-bit offset to an L1 table.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]