Am 12.11.2013 um 08:47 hat Hu Tao geschrieben: > 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)); > + }
bdrv_zero_init() is completely optional. It is only implemented for raw-posix and errors are not checked. You can't assume that after this point anything is preallocated. Kevin