[Qemu-devel] [PATCH v3 27/39] qcow2: Update qcow2_update_snapshot_refcount() to support L2 slices

Alberto Garcia posted 39 patches 8 years ago
There is a newer version of this series
[Qemu-devel] [PATCH v3 27/39] qcow2: Update qcow2_update_snapshot_refcount() to support L2 slices
Posted by Alberto Garcia 8 years ago
qcow2_update_snapshot_refcount() increases the refcount of all
clusters of a given snapshot. In order to do that it needs to load all
its L2 tables and iterate over their entries. Since we'll be loading
L2 slices instead of full tables we need to add an extra loop that
iterates over all slices of each L2 table.

This function doesn't need any additional changes so apart from that
this patch simply updates the variable name from l2_table to l2_slice.

Signed-off-by: Alberto Garcia <berto@igalia.com>
---
 block/qcow2-refcount.c | 31 +++++++++++++++++--------------
 1 file changed, 17 insertions(+), 14 deletions(-)

diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index dfa28301c4..60b521cb89 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -1183,17 +1183,20 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
     int64_t l1_table_offset, int l1_size, int addend)
 {
     BDRVQcow2State *s = bs->opaque;
-    uint64_t *l1_table, *l2_table, l2_offset, entry, l1_size2, refcount;
+    uint64_t *l1_table, *l2_slice, l2_offset, entry, l1_size2, refcount;
     bool l1_allocated = false;
     int64_t old_entry, old_l2_offset;
+    unsigned slice, slice_size2, n_slices;
     int i, j, l1_modified = 0, nb_csectors;
     int ret;
 
     assert(addend >= -1 && addend <= 1);
 
-    l2_table = NULL;
+    l2_slice = NULL;
     l1_table = NULL;
     l1_size2 = l1_size * sizeof(uint64_t);
+    slice_size2 = s->l2_slice_size * sizeof(uint64_t);
+    n_slices = s->cluster_size / slice_size2;
 
     s->cache_discards = true;
 
@@ -1236,19 +1239,19 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
                 goto fail;
             }
 
-            {
+            for (slice = 0; slice < n_slices; slice++) {
                 ret = qcow2_cache_get(bs, s->l2_table_cache,
-                                      l2_offset,
-                                      (void **) &l2_table);
+                                      l2_offset + slice * slice_size2,
+                                      (void **) &l2_slice);
                 if (ret < 0) {
                     goto fail;
                 }
 
-                for (j = 0; j < s->l2_size; j++) {
+                for (j = 0; j < s->l2_slice_size; j++) {
                     uint64_t cluster_index;
                     uint64_t offset;
 
-                    entry = be64_to_cpu(l2_table[j]);
+                    entry = be64_to_cpu(l2_slice[j]);
                     old_entry = entry;
                     entry &= ~QCOW_OFLAG_COPIED;
                     offset = entry & L2E_OFFSET_MASK;
@@ -1273,12 +1276,13 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
                     case QCOW2_CLUSTER_NORMAL:
                     case QCOW2_CLUSTER_ZERO_ALLOC:
                         if (offset_into_cluster(s, offset)) {
+                            int l2_index = slice * s->l2_slice_size + j;
                             qcow2_signal_corruption(
                                 bs, true, -1, -1, "Cluster "
                                 "allocation offset %#" PRIx64
                                 " unaligned (L2 offset: %#"
                                 PRIx64 ", L2 index: %#x)",
-                                offset, l2_offset, j);
+                                offset, l2_offset, l2_index);
                             ret = -EIO;
                             goto fail;
                         }
@@ -1317,14 +1321,13 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
                             qcow2_cache_set_dependency(bs, s->l2_table_cache,
                                                        s->refcount_block_cache);
                         }
-                        l2_table[j] = cpu_to_be64(entry);
+                        l2_slice[j] = cpu_to_be64(entry);
                         qcow2_cache_entry_mark_dirty(s->l2_table_cache,
-                                                     l2_table);
+                                                     l2_slice);
                     }
                 }
 
-                qcow2_cache_put(s->l2_table_cache, (void **) &l2_table);
-
+                qcow2_cache_put(s->l2_table_cache, (void **) &l2_slice);
             }
 
             if (addend != 0) {
@@ -1352,8 +1355,8 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
 
     ret = bdrv_flush(bs);
 fail:
-    if (l2_table) {
-        qcow2_cache_put(s->l2_table_cache, (void **) &l2_table);
+    if (l2_slice) {
+        qcow2_cache_put(s->l2_table_cache, (void **) &l2_slice);
     }
 
     s->cache_discards = false;
-- 
2.11.0


Re: [Qemu-devel] [PATCH v3 27/39] qcow2: Update qcow2_update_snapshot_refcount() to support L2 slices
Posted by Eric Blake 8 years ago
On 01/26/2018 08:59 AM, Alberto Garcia wrote:
> qcow2_update_snapshot_refcount() increases the refcount of all
> clusters of a given snapshot. In order to do that it needs to load all
> its L2 tables and iterate over their entries. Since we'll be loading
> L2 slices instead of full tables we need to add an extra loop that
> iterates over all slices of each L2 table.
> 
> This function doesn't need any additional changes so apart from that
> this patch simply updates the variable name from l2_table to l2_slice.
> 
> Signed-off-by: Alberto Garcia <berto@igalia.com>
> ---
>  block/qcow2-refcount.c | 31 +++++++++++++++++--------------
>  1 file changed, 17 insertions(+), 14 deletions(-)
> 

Reviewed-by: Eric Blake <eblake@redhat.com>

-- 
Eric Blake, Principal Software Engineer
Red Hat, Inc.           +1-919-301-3266
Virtualization:  qemu.org | libvirt.org

Re: [Qemu-devel] [PATCH v3 27/39] qcow2: Update qcow2_update_snapshot_refcount() to support L2 slices
Posted by Max Reitz 8 years ago
On 2018-01-26 15:59, Alberto Garcia wrote:
> qcow2_update_snapshot_refcount() increases the refcount of all
> clusters of a given snapshot. In order to do that it needs to load all
> its L2 tables and iterate over their entries. Since we'll be loading
> L2 slices instead of full tables we need to add an extra loop that
> iterates over all slices of each L2 table.
> 
> This function doesn't need any additional changes so apart from that
> this patch simply updates the variable name from l2_table to l2_slice.
> 
> Signed-off-by: Alberto Garcia <berto@igalia.com>
> ---
>  block/qcow2-refcount.c | 31 +++++++++++++++++--------------
>  1 file changed, 17 insertions(+), 14 deletions(-)
> 
> diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
> index dfa28301c4..60b521cb89 100644
> --- a/block/qcow2-refcount.c
> +++ b/block/qcow2-refcount.c
> @@ -1183,17 +1183,20 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
>      int64_t l1_table_offset, int l1_size, int addend)
>  {
>      BDRVQcow2State *s = bs->opaque;
> -    uint64_t *l1_table, *l2_table, l2_offset, entry, l1_size2, refcount;
> +    uint64_t *l1_table, *l2_slice, l2_offset, entry, l1_size2, refcount;
>      bool l1_allocated = false;
>      int64_t old_entry, old_l2_offset;
> +    unsigned slice, slice_size2, n_slices;

Hm, well. Hm.

>      int i, j, l1_modified = 0, nb_csectors;
>      int ret;
>  
>      assert(addend >= -1 && addend <= 1);
>  
> -    l2_table = NULL;
> +    l2_slice = NULL;
>      l1_table = NULL;
>      l1_size2 = l1_size * sizeof(uint64_t);
> +    slice_size2 = s->l2_slice_size * sizeof(uint64_t);
> +    n_slices = s->cluster_size / slice_size2;
>  
>      s->cache_discards = true;
>  

[...]

> @@ -1273,12 +1276,13 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
>                      case QCOW2_CLUSTER_NORMAL:
>                      case QCOW2_CLUSTER_ZERO_ALLOC:
>                          if (offset_into_cluster(s, offset)) {
> +                            int l2_index = slice * s->l2_slice_size + j;
>                              qcow2_signal_corruption(
>                                  bs, true, -1, -1, "Cluster "
>                                  "allocation offset %#" PRIx64
>                                  " unaligned (L2 offset: %#"
>                                  PRIx64 ", L2 index: %#x)",
> -                                offset, l2_offset, j);
> +                                offset, l2_offset, l2_index);

This makes it a bit weird that in other patches l2_index is now
generally the L2 slice index...

Oh well.

Reviewed-by: Max Reitz <mreitz@redhat.com>

>                              ret = -EIO;
>                              goto fail;
>                          }

Re: [Qemu-devel] [PATCH v3 27/39] qcow2: Update qcow2_update_snapshot_refcount() to support L2 slices
Posted by Alberto Garcia 8 years ago
On Thu 01 Feb 2018 08:26:26 PM CET, Max Reitz <mreitz@redhat.com> wrote:
>> @@ -1273,12 +1276,13 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
>>                      case QCOW2_CLUSTER_NORMAL:
>>                      case QCOW2_CLUSTER_ZERO_ALLOC:
>>                          if (offset_into_cluster(s, offset)) {
>> +                            int l2_index = slice * s->l2_slice_size + j;
>>                              qcow2_signal_corruption(
>>                                  bs, true, -1, -1, "Cluster "
>>                                  "allocation offset %#" PRIx64
>>                                  " unaligned (L2 offset: %#"
>>                                  PRIx64 ", L2 index: %#x)",
>> -                                offset, l2_offset, j);
>> +                                offset, l2_offset, l2_index);
>
> This makes it a bit weird that in other patches l2_index is now
> generally the L2 slice index...

You're right, I can call it l2_table_index, I think this is the only
case where it does not refer to the slice index.

Berto