diff mbox series

[v8,33/34] qcow2: Assert that expand_zero_clusters_in_l1() does not support subclusters

Message ID 19afb93b267b9698edf5e0253458c5db69ef91a2.1591801197.git.berto@igalia.com (mailing list archive)
State New, archived
Headers show
Series Add subcluster allocation to qcow2 | expand

Commit Message

Alberto Garcia June 10, 2020, 3:03 p.m. UTC
This function is only used by qcow2_expand_zero_clusters() to
downgrade a qcow2 image to a previous version. It is however not
possible to downgrade an image with extended L2 entries because older
versions of qcow2 do not have this feature.

Signed-off-by: Alberto Garcia <berto@igalia.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
---
 block/qcow2-cluster.c      | 8 +++++++-
 tests/qemu-iotests/061     | 6 ++++++
 tests/qemu-iotests/061.out | 5 +++++
 3 files changed, 18 insertions(+), 1 deletion(-)

Comments

Eric Blake June 10, 2020, 7:43 p.m. UTC | #1
On 6/10/20 10:03 AM, Alberto Garcia wrote:
> This function is only used by qcow2_expand_zero_clusters() to
> downgrade a qcow2 image to a previous version. It is however not
> possible to downgrade an image with extended L2 entries because older
> versions of qcow2 do not have this feature.

Well, it _is_ possible, but it would involve rewriting the entire L1/L2 
tables (including all internal snapshots), as well as causing I/O to COW 
every cluster where not all subclusters are allocated; and doing that 
conversion while remaining crash-consistent requires some thought and a 
temporary extra load on disk space (we can't discard the old table until 
the new one is completely written).

It would be more accurate to merely state that we are not prepared to 
implement it at this time.

> 
> Signed-off-by: Alberto Garcia <berto@igalia.com>
> Reviewed-by: Eric Blake <eblake@redhat.com>
> ---
>   block/qcow2-cluster.c      | 8 +++++++-
>   tests/qemu-iotests/061     | 6 ++++++
>   tests/qemu-iotests/061.out | 5 +++++
>   3 files changed, 18 insertions(+), 1 deletion(-)
> 

Whether or not we update the commit message, R-b stands for the code.
Alberto Garcia June 11, 2020, 1:24 p.m. UTC | #2
On Wed 10 Jun 2020 09:43:53 PM CEST, Eric Blake wrote:
> On 6/10/20 10:03 AM, Alberto Garcia wrote:
>> This function is only used by qcow2_expand_zero_clusters() to
>> downgrade a qcow2 image to a previous version. It is however not
>> possible to downgrade an image with extended L2 entries because older
>> versions of qcow2 do not have this feature.
>
> Well, it _is_ possible, but it would involve rewriting the entire
> L1/L2 tables (including all internal snapshots)

Right :-) Let's try this way:

    This function is only used by qcow2_expand_zero_clusters() to
    downgrade a qcow2 image to a previous version. This would require
    transforming all extended L2 entries into normal L2 entries but
    this is not a simple task and there are no plans to implement this
    at the moment.

Berto
Eric Blake June 11, 2020, 2:36 p.m. UTC | #3
On 6/11/20 8:24 AM, Alberto Garcia wrote:
> On Wed 10 Jun 2020 09:43:53 PM CEST, Eric Blake wrote:
>> On 6/10/20 10:03 AM, Alberto Garcia wrote:
>>> This function is only used by qcow2_expand_zero_clusters() to
>>> downgrade a qcow2 image to a previous version. It is however not
>>> possible to downgrade an image with extended L2 entries because older
>>> versions of qcow2 do not have this feature.
>>
>> Well, it _is_ possible, but it would involve rewriting the entire
>> L1/L2 tables (including all internal snapshots)
> 
> Right :-) Let's try this way:
> 
>      This function is only used by qcow2_expand_zero_clusters() to
>      downgrade a qcow2 image to a previous version. This would require
>      transforming all extended L2 entries into normal L2 entries but
>      this is not a simple task and there are no plans to implement this
>      at the moment.

Works for me.
diff mbox series

Patch

diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index c8217081f2..e8bb1f32f3 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -2157,6 +2157,9 @@  static int expand_zero_clusters_in_l1(BlockDriverState *bs, uint64_t *l1_table,
     int ret;
     int i, j;
 
+    /* qcow2_downgrade() is not allowed in images with subclusters */
+    assert(!has_subclusters(s));
+
     slice_size2 = s->l2_slice_size * l2_entry_size(s);
     n_slices = s->cluster_size / slice_size2;
 
@@ -2225,7 +2228,8 @@  static int expand_zero_clusters_in_l1(BlockDriverState *bs, uint64_t *l1_table,
                 if (cluster_type == QCOW2_CLUSTER_ZERO_PLAIN) {
                     if (!bs->backing) {
                         /* not backed; therefore we can simply deallocate the
-                         * cluster */
+                         * cluster. No need to call set_l2_bitmap(), this
+                         * function doesn't support images with subclusters. */
                         set_l2_entry(s, l2_slice, j, 0);
                         l2_dirty = true;
                         continue;
@@ -2296,6 +2300,8 @@  static int expand_zero_clusters_in_l1(BlockDriverState *bs, uint64_t *l1_table,
                 } else {
                     set_l2_entry(s, l2_slice, j, offset);
                 }
+                /* No need to call set_l2_bitmap() after set_l2_entry() because
+                 * this function doesn't support images with subclusters. */
                 l2_dirty = true;
             }
 
diff --git a/tests/qemu-iotests/061 b/tests/qemu-iotests/061
index 10eb243164..23add2dfe3 100755
--- a/tests/qemu-iotests/061
+++ b/tests/qemu-iotests/061
@@ -303,6 +303,12 @@  $QEMU_IMG amend -o "compat=0.10" "$TEST_IMG"
 _img_info --format-specific
 _check_test_img
 
+echo
+echo "=== Testing version downgrade with extended L2 entries ==="
+echo
+_make_test_img -o "compat=1.1,extended_l2=on" 64M
+$QEMU_IMG amend -o "compat=0.10" "$TEST_IMG"
+
 echo
 echo "=== Try changing the external data file ==="
 echo
diff --git a/tests/qemu-iotests/061.out b/tests/qemu-iotests/061.out
index 39812d8cf8..c1acdbd751 100644
--- a/tests/qemu-iotests/061.out
+++ b/tests/qemu-iotests/061.out
@@ -528,6 +528,11 @@  Format specific information:
     extended l2: false
 No errors were found on the image.
 
+=== Testing version downgrade with extended L2 entries ===
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
+qemu-img: Cannot downgrade an image with incompatible features 0x10 set
+
 === Try changing the external data file ===
 
 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864