Message ID | 3b868557f35fbdbc9cc8d962c23be4d2daa9c2b2.1572125022.git.berto@igalia.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Add subcluster allocation to qcow2 | expand |
On 26.10.19 23:25, Alberto Garcia wrote: > Traditional qcow2 images don't allow preallocation if a backing file > is set. This is because once a cluster is allocated there is no way to > tell that its data should be read from the backing file. > > Extended L2 entries have individual allocation bits for each > subcluster, and therefore it is perfectly possible to have an > allocated cluster with all its subclusters unallocated. > > Signed-off-by: Alberto Garcia <berto@igalia.com> > --- > block/qcow2.c | 7 ++++--- > tests/qemu-iotests/206.out | 2 +- > 2 files changed, 5 insertions(+), 4 deletions(-) But it doesn’t work, because qcow2_alloc_cluster_offset() always allocates the whole cluster, so the backing file content isn’t visible: $ ./qemu-img create -f qcow2 base.qcow2 64M Formatting 'base.qcow2', fmt=qcow2 size=67108864 cluster_size=65536 lazy_refcounts=off extended_l2=off refcount_bits=16 $ ./qemu-io -c 'write -P 42 0 64M' base.qcow2 wrote 67108864/67108864 bytes at offset 0 64 MiB, 1 ops; 00.21 sec (307.344 MiB/sec and 4.8022 ops/sec) $ ./qemu-img create -f qcow2 -o preallocation=metadata,extended_l2=on \ top.qcow2 Formatting 'top.qcow2', fmt=qcow2 size=67108864 backing_file=base.qcow2 cluster_size=65536 preallocation=metadata lazy_refcounts=off extended_l2=on refcount_bits=16 $ ./qemu-io -c 'read -P 42 0 64M' top.qcow2 Pattern verification failed at offset 0, 67108864 bytes read 67108864/67108864 bytes at offset 0 64 MiB, 1 ops; 00.03 sec (2.498 GiB/sec and 39.9725 ops/sec) Max
diff --git a/block/qcow2.c b/block/qcow2.c index b1fa7ab5da..8cf51c5d64 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -3307,10 +3307,11 @@ qcow2_co_create(BlockdevCreateOptions *create_options, Error **errp) qcow2_opts->preallocation = PREALLOC_MODE_OFF; } if (qcow2_opts->has_backing_file && - qcow2_opts->preallocation != PREALLOC_MODE_OFF) + qcow2_opts->preallocation != PREALLOC_MODE_OFF && + !qcow2_opts->extended_l2) { - error_setg(errp, "Backing file and preallocation cannot be used at " - "the same time"); + error_setg(errp, "Backing file and preallocation can only be used at " + "the same time if extended_l2 is on"); ret = -EINVAL; goto out; } diff --git a/tests/qemu-iotests/206.out b/tests/qemu-iotests/206.out index d2efc0394a..cfddfbfaa4 100644 --- a/tests/qemu-iotests/206.out +++ b/tests/qemu-iotests/206.out @@ -198,7 +198,7 @@ Job failed: Different refcount widths than 16 bits require compatibility level 1 === Invalid backing file options === {"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"backing-file": "/dev/null", "driver": "qcow2", "file": "node0", "preallocation": "full", "size": 67108864}}} {"return": {}} -Job failed: Backing file and preallocation cannot be used at the same time +Job failed: Backing file and preallocation can only be used at the same time if extended_l2 is on {"execute": "job-dismiss", "arguments": {"id": "job0"}} {"return": {}}
Traditional qcow2 images don't allow preallocation if a backing file is set. This is because once a cluster is allocated there is no way to tell that its data should be read from the backing file. Extended L2 entries have individual allocation bits for each subcluster, and therefore it is perfectly possible to have an allocated cluster with all its subclusters unallocated. Signed-off-by: Alberto Garcia <berto@igalia.com> --- block/qcow2.c | 7 ++++--- tests/qemu-iotests/206.out | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-)