Re: [PATCH 03/10] qcow2: introduce qcow2_parse_compressed_l2_entry() helper

2021-05-04 Thread Eric Blake
On 5/4/21 10:20 AM, Vladimir Sementsov-Ogievskiy wrote:
> Add helper to parse compressed l2_entry and use it everywhere instead
> of opencoding.

open-coding

> 
> Note, that in most places we move to precise coffset/csize instead of
> sector-aligned. Still it should work good enough for updating
> refcounts.
> 
> Signed-off-by: Vladimir Sementsov-Ogievskiy 
> ---
>  block/qcow2.h  |  3 ++-
>  block/qcow2-cluster.c  | 15 +++
>  block/qcow2-refcount.c | 36 +---
>  block/qcow2.c  |  9 ++---
>  4 files changed, 36 insertions(+), 27 deletions(-)
> 

Reviewed-by: Eric Blake 

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




[PATCH 03/10] qcow2: introduce qcow2_parse_compressed_l2_entry() helper

2021-05-04 Thread Vladimir Sementsov-Ogievskiy
Add helper to parse compressed l2_entry and use it everywhere instead
of opencoding.

Note, that in most places we move to precise coffset/csize instead of
sector-aligned. Still it should work good enough for updating
refcounts.

Signed-off-by: Vladimir Sementsov-Ogievskiy 
---
 block/qcow2.h  |  3 ++-
 block/qcow2-cluster.c  | 15 +++
 block/qcow2-refcount.c | 36 +---
 block/qcow2.c  |  9 ++---
 4 files changed, 36 insertions(+), 27 deletions(-)

diff --git a/block/qcow2.h b/block/qcow2.h
index 42a0058ab7..c0e1e83796 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -110,7 +110,6 @@
 
 /* Defined in the qcow2 spec (compressed cluster descriptor) */
 #define QCOW2_COMPRESSED_SECTOR_SIZE 512U
-#define QCOW2_COMPRESSED_SECTOR_MASK (~(QCOW2_COMPRESSED_SECTOR_SIZE - 1ULL))
 
 /* Must be at least 2 to cover COW */
 #define MIN_L2_CACHE_SIZE 2 /* cache entries */
@@ -913,6 +912,8 @@ int qcow2_alloc_compressed_cluster_offset(BlockDriverState 
*bs,
   uint64_t offset,
   int compressed_size,
   uint64_t *host_offset);
+void qcow2_parse_compressed_l2_entry(BlockDriverState *bs, uint64_t l2_entry,
+ uint64_t *coffset, int *csize);
 
 int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m);
 void qcow2_alloc_cluster_abort(BlockDriverState *bs, QCowL2Meta *m);
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index 04735ee439..70d0570a33 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -2462,3 +2462,18 @@ fail:
 g_free(l1_table);
 return ret;
 }
+
+void qcow2_parse_compressed_l2_entry(BlockDriverState *bs, uint64_t l2_entry,
+ uint64_t *coffset, int *csize)
+{
+BDRVQcow2State *s = bs->opaque;
+int nb_csectors;
+
+assert(qcow2_get_cluster_type(bs, l2_entry) == QCOW2_CLUSTER_COMPRESSED);
+
+*coffset = l2_entry & s->cluster_offset_mask;
+
+nb_csectors = ((l2_entry >> s->csize_shift) & s->csize_mask) + 1;
+*csize = nb_csectors * QCOW2_COMPRESSED_SECTOR_SIZE -
+(*coffset & (QCOW2_COMPRESSED_SECTOR_SIZE - 1));
+}
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index 2734338625..66cbb94ef9 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -1177,11 +1177,11 @@ void qcow2_free_any_cluster(BlockDriverState *bs, 
uint64_t l2_entry,
 switch (ctype) {
 case QCOW2_CLUSTER_COMPRESSED:
 {
-int64_t offset = (l2_entry & s->cluster_offset_mask)
-& QCOW2_COMPRESSED_SECTOR_MASK;
-int size = QCOW2_COMPRESSED_SECTOR_SIZE *
-(((l2_entry >> s->csize_shift) & s->csize_mask) + 1);
-qcow2_free_clusters(bs, offset, size, type);
+uint64_t coffset;
+int csize;
+
+qcow2_parse_compressed_l2_entry(bs, l2_entry, , );
+qcow2_free_clusters(bs, coffset, csize, type);
 }
 break;
 case QCOW2_CLUSTER_NORMAL:
@@ -1247,7 +1247,7 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
 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 i, j, l1_modified = 0;
 int ret;
 
 assert(addend >= -1 && addend <= 1);
@@ -1318,14 +1318,14 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
 
 switch (qcow2_get_cluster_type(bs, entry)) {
 case QCOW2_CLUSTER_COMPRESSED:
-nb_csectors = ((entry >> s->csize_shift) &
-   s->csize_mask) + 1;
 if (addend != 0) {
-uint64_t coffset = (entry & s->cluster_offset_mask)
-& QCOW2_COMPRESSED_SECTOR_MASK;
+uint64_t coffset;
+int csize;
+
+qcow2_parse_compressed_l2_entry(bs, entry,
+, );
 ret = update_refcount(
-bs, coffset,
-nb_csectors * QCOW2_COMPRESSED_SECTOR_SIZE,
+bs, coffset, csize,
 abs(addend), addend < 0,
 QCOW2_DISCARD_SNAPSHOT);
 if (ret < 0) {
@@ -1603,7 +1603,7 @@ static int check_refcounts_l2(BlockDriverState *bs, 
BdrvCheckResult *res,
 BDRVQcow2State *s = bs->opaque;
 uint64_t l2_entry;
 uint64_t next_contiguous_offset = 0;
-int i, nb_csectors, ret;
+int i, ret;
 size_t l2_size_bytes = s->l2_size * l2_entry_size(s);
 g_autofree uint64_t *l2_table = g_malloc(l2_size_bytes);
 
@@ -1617,6 +1617,8 @@ static int