On Fri, Nov 15, 2013 at 09:29:43AM +0800, Hu Tao wrote: > On Wed, Nov 13, 2013 at 07:03:03AM +0100, Peter Lieven wrote: > > What is your use case for this seris? QCOW2 creation or converting > > anything to QCOW2? For the later case you could use "qemu-img convert -S 0 > > ..." > > starting in 1.8. > > The former. Seems "qemu-img convert -S 0" do the same thing but at > converting time, maybe we can share some code. But let me dig the > code first.
The purpose is to using posix_fallocate() to preallocate space, other than writing zeros to do it. Because the latter is pretty slow. > > > > > Peter > > > > Hu Tao wrote: > > > This adds a preallocation=full mode to qcow2 image creation, which > > > creates a non-sparse image file. > > > > > > Signed-off-by: Hu Tao <hu...@cn.fujitsu.com> > > > --- > > > block/qcow2.c | 28 ++++++++++++++++++++++------ > > > 1 file changed, 22 insertions(+), 6 deletions(-) > > > > > > diff --git a/block/qcow2.c b/block/qcow2.c > > > index 359030f..d3ca6cf 100644 > > > --- a/block/qcow2.c > > > +++ b/block/qcow2.c > > > @@ -1385,7 +1385,13 @@ static int > > > qcow2_change_backing_file(BlockDriverState *bs, > > > return qcow2_update_header(bs); > > > } > > > > > > -static int preallocate(BlockDriverState *bs) > > > +enum prealloc_mode { > > > + PREALLOC_OFF = 0, > > > + PREALLOC_METADATA, > > > + PREALLOC_FULL, > > > +}; > > > + > > > +static int preallocate(BlockDriverState *bs, enum prealloc_mode mode) > > > { > > > uint64_t nb_sectors; > > > uint64_t offset; > > > @@ -1394,9 +1400,12 @@ static int preallocate(BlockDriverState *bs) > > > int ret; > > > QCowL2Meta *meta; > > > > > > + assert(mode != PREALLOC_OFF); > > > + > > > nb_sectors = bdrv_getlength(bs) >> 9; > > > offset = 0; > > > > > > + /* First allocate metadata in _really_ big chunks */ > > > while (nb_sectors) { > > > num = MIN(nb_sectors, INT_MAX >> 9); > > > ret = qcow2_alloc_cluster_offset(bs, offset, 0, num, &num, > > > @@ -1424,6 +1433,11 @@ static int preallocate(BlockDriverState *bs) > > > offset += num << 9; > > > } > > > > > > + /* Then write zeros to the cluster data, if requested */ > > > + if (mode == PREALLOC_FULL) { > > > + bdrv_zero_init(bs->file, offset, bdrv_getlength(bs)); > > > + } > > > + > > > /* > > > * It is expected that the image file is large enough to actually > > > contain > > > * all of the allocated clusters (otherwise we get failing reads > > > after > > > @@ -1572,11 +1586,11 @@ static int qcow2_create2(const char *filename, > > > int64_t total_size, > > > } > > > } > > > > > > - /* And if we're supposed to preallocate metadata, do that now */ > > > + /* And if we're supposed to preallocate data, do that now */ > > > if (prealloc) { > > > BDRVQcowState * > >