diff options
author | Alberto Garcia <berto@igalia.com> | 2020-06-17 16:00:36 +0200 |
---|---|---|
committer | Max Reitz <mreitz@redhat.com> | 2020-07-06 08:33:06 +0200 |
commit | a5675f390116a927e320984f02f473a6affc9fcd (patch) | |
tree | 33283366384bc7c3703cf36c497761c4afd7c018 /tests/qemu-iotests/125 | |
parent | e8de7ba9ea086c427cd36a10bc3506ac20aa4895 (diff) | |
download | qemu-a5675f390116a927e320984f02f473a6affc9fcd.zip qemu-a5675f390116a927e320984f02f473a6affc9fcd.tar.gz qemu-a5675f390116a927e320984f02f473a6affc9fcd.tar.bz2 |
qcow2: Fix preallocation on images with unaligned sizes
When resizing an image with qcow2_co_truncate() using the falloc or
full preallocation modes the code assumes that both the old and new
sizes are cluster-aligned.
There are two problems with this:
1) The calculation of how many clusters are involved does not always
get the right result.
Example: creating a 60KB image and resizing it (with
preallocation=full) to 80KB won't allocate the second cluster.
2) No copy-on-write is performed, so in the previous example if
there is a backing file then the first 60KB of the first cluster
won't be filled with data from the backing file.
This patch fixes both issues.
Signed-off-by: Alberto Garcia <berto@igalia.com>
Message-Id: <20200617140036.20311-1-berto@igalia.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
Diffstat (limited to 'tests/qemu-iotests/125')
-rwxr-xr-x | tests/qemu-iotests/125 | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/tests/qemu-iotests/125 b/tests/qemu-iotests/125 index d510984..7cb1c19 100755 --- a/tests/qemu-iotests/125 +++ b/tests/qemu-iotests/125 @@ -164,6 +164,30 @@ for GROWTH_SIZE in 16 48 80; do done done +# Test image resizing using preallocation and unaligned offsets +$QEMU_IMG create -f raw "$TEST_IMG.base" 128k | _filter_img_create +$QEMU_IO -c 'write -q -P 1 0 128k' -f raw "$TEST_IMG.base" +for orig_size in 31k 33k; do + echo "--- Resizing image from $orig_size to 96k ---" + _make_test_img -F raw -b "$TEST_IMG.base" -o cluster_size=64k "$orig_size" + $QEMU_IMG resize -f "$IMGFMT" --preallocation=full "$TEST_IMG" 96k + # The first part of the image should contain data from the backing file + $QEMU_IO -c "read -q -P 1 0 ${orig_size}" "$TEST_IMG" + # The resized part of the image should contain zeroes + $QEMU_IO -c "read -q -P 0 ${orig_size} 63k" "$TEST_IMG" + # If the image does not have an external data file we can also verify its + # actual size. The resized image should have 7 clusters: + # header, L1 table, L2 table, refcount table, refcount block, 2 data clusters + if ! _get_data_file "$TEST_IMG" > /dev/null; then + expected_file_length=$((65536 * 7)) + file_length=$(stat -c '%s' "$TEST_IMG_FILE") + if [ "$file_length" != "$expected_file_length" ]; then + echo "ERROR: file length $file_length (expected $expected_file_length)" + fi + fi + echo +done + # success, all done echo '*** done' rm -f $seq.full |