[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v2] qcow2: Implement bdrv_truncate() for growing
From: |
Kevin Wolf |
Subject: |
Re: [Qemu-devel] [PATCH v2] qcow2: Implement bdrv_truncate() for growing images |
Date: |
Wed, 28 Apr 2010 12:15:58 +0200 |
User-agent: |
Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.1.9) Gecko/20100330 Fedora/3.0.4-1.fc12 Thunderbird/3.0.4 |
Am 28.04.2010 11:24, schrieb Stefan Hajnoczi:
> This patch adds the ability to grow qcow2 images in-place using
> bdrv_truncate(). This enables qemu-img resize command support for
> qcow2.
>
> Snapshots are not supported and bdrv_truncate() will return -ENOTSUP.
> The notion of resizing an image with snapshots could lead to confusion:
> users may expect snapshots to remain unchanged, but this is not possible
> with the current qcow2 on-disk format where the header.size field is
> global instead of per-snapshot. Others may expect snapshots to change
> size along with the current image data. I think it is safest to not
> support snapshots and perhaps add behavior later if there is a
> consensus.
>
> Backing images continue to work. If the image is now larger than its
> backing image, zeroes are read when accessing beyond the end of the
> backing image.
>
> Signed-off-by: Stefan Hajnoczi <address@hidden>
> ---
> v2:
> * Remove superfluous qcow2_grow_l1_table()-related changes
>
> block/qcow2.c | 45 +++++++++++++++++++++++++++++++++++++++++----
> block/qcow2.h | 6 ++++++
> 2 files changed, 47 insertions(+), 4 deletions(-)
>
> diff --git a/block/qcow2.c b/block/qcow2.c
> index 4fa3ff9..a65af41 100644
> --- a/block/qcow2.c
> +++ b/block/qcow2.c
> @@ -140,7 +140,7 @@ static int qcow_read_extensions(BlockDriverState *bs,
> uint64_t start_offset,
> static int qcow_open(BlockDriverState *bs, int flags)
> {
> BDRVQcowState *s = bs->opaque;
> - int len, i, shift;
> + int len, i;
> QCowHeader header;
> uint64_t ext_end;
>
> @@ -188,8 +188,7 @@ static int qcow_open(BlockDriverState *bs, int flags)
>
> /* read the level 1 table */
> s->l1_size = header.l1_size;
> - shift = s->cluster_bits + s->l2_bits;
> - s->l1_vm_state_index = (header.size + (1LL << shift) - 1) >> shift;
> + s->l1_vm_state_index = size_to_l1(s, header.size);
> /* the L1 table must contain at least enough entries to put
> header.size bytes */
> if (s->l1_size < s->l1_vm_state_index)
> @@ -851,6 +850,42 @@ static int qcow_make_empty(BlockDriverState *bs)
> return 0;
> }
>
> +static int qcow2_truncate(BlockDriverState *bs, int64_t offset)
> +{
> + BDRVQcowState *s = bs->opaque;
> + int ret, new_l1_size;
> +
> + if (offset & 511) {
> + return -EINVAL;
> + }
> +
> + /* cannot proceed if image has snapshots */
> + if (s->nb_snapshots) {
> + return -ENOTSUP;
> + }
> +
> + /* shrinking is currently not supported */
> + if (offset < bs->total_sectors * 512) {
> + return -ENOTSUP;
> + }
> +
> + new_l1_size = size_to_l1(s, offset);
> + ret = qcow2_grow_l1_table(bs, new_l1_size);
> + if (ret < 0) {
> + return ret;
> + }
> +
> + /* write updated header.size */
> + offset = cpu_to_be64(offset);
> + if (bdrv_pwrite(bs->file, offsetof(QCowHeader, size), &offset,
> + sizeof(uint64_t)) != sizeof(uint64_t)) {
> + return -EIO;
> + }
Please return the right error code here. Also, bdrv_pwrite doesn't
return short writes, so the code can look like this:
ret = bdrv_pwrite(...);
if (ret < 0) {
return ret;
}
Otherwise I like the patch. It has actually become simple and easy to
understand.
Kevin