[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v2 24/32] qcow2: Update qcow2_update_snapshot_refcou
From: |
Alberto Garcia |
Subject: |
[Qemu-devel] [PATCH v2 24/32] qcow2: Update qcow2_update_snapshot_refcount() to support L2 slices |
Date: |
Fri, 15 Dec 2017 13:53:52 +0100 |
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 <address@hidden>
---
block/qcow2-refcount.c | 150 ++++++++++++++++++++++++++-----------------------
1 file changed, 80 insertions(+), 70 deletions(-)
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index 51094fbcfb..45c7bb0ff6 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -1183,18 +1183,22 @@ 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_size, 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_size = s->l2_slice_size * sizeof(uint64_t);
+ n_slices = s->cluster_size / slice_size;
+
s->cache_discards = true;
/* WARNING: qcow2_snapshot_goto relies on this function not using the
@@ -1236,91 +1240,97 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
goto fail;
}
- ret = qcow2_cache_get(bs, s->l2_table_cache, l2_offset,
- (void**) &l2_table);
- if (ret < 0) {
- goto fail;
- }
+ for (slice = 0; slice < n_slices; slice++) {
+ ret = qcow2_cache_get(bs, s->l2_table_cache,
+ l2_offset + slice * slice_size,
+ (void **) &l2_slice);
+ if (ret < 0) {
+ goto fail;
+ }
- for (j = 0; j < s->l2_size; j++) {
- uint64_t cluster_index;
- uint64_t offset;
+ for (j = 0; j < s->l2_slice_size; j++) {
+ uint64_t cluster_index;
+ uint64_t offset;
- entry = be64_to_cpu(l2_table[j]);
- old_entry = entry;
- entry &= ~QCOW_OFLAG_COPIED;
- offset = entry & L2E_OFFSET_MASK;
+ entry = be64_to_cpu(l2_slice[j]);
+ old_entry = entry;
+ entry &= ~QCOW_OFLAG_COPIED;
+ offset = entry & L2E_OFFSET_MASK;
- switch (qcow2_get_cluster_type(entry)) {
- case QCOW2_CLUSTER_COMPRESSED:
- nb_csectors = ((entry >> s->csize_shift) &
- s->csize_mask) + 1;
- if (addend != 0) {
- ret = update_refcount(bs,
- (entry & s->cluster_offset_mask) & ~511,
+ switch (qcow2_get_cluster_type(entry)) {
+ case QCOW2_CLUSTER_COMPRESSED:
+ nb_csectors = ((entry >> s->csize_shift) &
+ s->csize_mask) + 1;
+ if (addend != 0) {
+ ret = update_refcount(
+ bs, (entry & s->cluster_offset_mask) & ~511,
nb_csectors * 512, abs(addend), addend < 0,
QCOW2_DISCARD_SNAPSHOT);
- if (ret < 0) {
+ if (ret < 0) {
+ goto fail;
+ }
+ }
+ /* compressed clusters are never modified */
+ refcount = 2;
+ break;
+
+ 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, l2_index);
+ ret = -EIO;
goto fail;
}
- }
- /* compressed clusters are never modified */
- refcount = 2;
- break;
- case QCOW2_CLUSTER_NORMAL:
- case QCOW2_CLUSTER_ZERO_ALLOC:
- if (offset_into_cluster(s, offset)) {
- qcow2_signal_corruption(bs, true, -1, -1, "Cluster "
- "allocation offset %#" PRIx64
- " unaligned (L2 offset: %#"
- PRIx64 ", L2 index: %#x)",
- offset, l2_offset, j);
- ret = -EIO;
- goto fail;
- }
+ cluster_index = offset >> s->cluster_bits;
+ assert(cluster_index);
+ if (addend != 0) {
+ ret = qcow2_update_cluster_refcount(
+ bs, cluster_index, abs(addend), addend < 0,
+ QCOW2_DISCARD_SNAPSHOT);
+ if (ret < 0) {
+ goto fail;
+ }
+ }
- cluster_index = offset >> s->cluster_bits;
- assert(cluster_index);
- if (addend != 0) {
- ret = qcow2_update_cluster_refcount(bs,
- cluster_index, abs(addend), addend < 0,
- QCOW2_DISCARD_SNAPSHOT);
+ ret = qcow2_get_refcount(bs, cluster_index, &refcount);
if (ret < 0) {
goto fail;
}
- }
+ break;
- ret = qcow2_get_refcount(bs, cluster_index, &refcount);
- if (ret < 0) {
- goto fail;
- }
- break;
+ case QCOW2_CLUSTER_ZERO_PLAIN:
+ case QCOW2_CLUSTER_UNALLOCATED:
+ refcount = 0;
+ break;
- case QCOW2_CLUSTER_ZERO_PLAIN:
- case QCOW2_CLUSTER_UNALLOCATED:
- refcount = 0;
- break;
-
- default:
- abort();
- }
+ default:
+ abort();
+ }
- if (refcount == 1) {
- entry |= QCOW_OFLAG_COPIED;
- }
- if (entry != old_entry) {
- if (addend > 0) {
- qcow2_cache_set_dependency(bs, s->l2_table_cache,
- s->refcount_block_cache);
+ if (refcount == 1) {
+ entry |= QCOW_OFLAG_COPIED;
+ }
+ if (entry != old_entry) {
+ if (addend > 0) {
+ qcow2_cache_set_dependency(bs, s->l2_table_cache,
+
s->refcount_block_cache);
+ }
+ l2_slice[j] = cpu_to_be64(entry);
+ qcow2_cache_entry_mark_dirty(s->l2_table_cache,
+ l2_slice);
}
- l2_table[j] = cpu_to_be64(entry);
- qcow2_cache_entry_mark_dirty(s->l2_table_cache, l2_table);
}
+
+ qcow2_cache_put(s->l2_table_cache, (void **) &l2_slice);
}
- qcow2_cache_put(s->l2_table_cache, (void **) &l2_table);
-
if (addend != 0) {
ret = qcow2_update_cluster_refcount(bs, l2_offset >>
s->cluster_bits,
@@ -1346,8 +1356,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
- [Qemu-devel] [PATCH v2 28/32] qcow2: Rename l2_table in count_contiguous_clusters(), (continued)
- [Qemu-devel] [PATCH v2 28/32] qcow2: Rename l2_table in count_contiguous_clusters(), Alberto Garcia, 2017/12/15
- [Qemu-devel] [PATCH v2 05/32] qcow2: Remove BDS parameter from qcow2_cache_table_release(), Alberto Garcia, 2017/12/15
- [Qemu-devel] [PATCH v2 21/32] qcow2: Update handle_alloc() to support L2 slices, Alberto Garcia, 2017/12/15
- [Qemu-devel] [PATCH v2 02/32] qcow2: Add table size field to Qcow2Cache, Alberto Garcia, 2017/12/15
- [Qemu-devel] [PATCH v2 06/32] qcow2: Remove BDS parameter from qcow2_cache_entry_mark_dirty(), Alberto Garcia, 2017/12/15
- [Qemu-devel] [PATCH v2 09/32] qcow2: Remove BDS parameter from qcow2_cache_clean_unused(), Alberto Garcia, 2017/12/15
- [Qemu-devel] [PATCH v2 27/32] qcow2: Rename l2_table in qcow2_alloc_compressed_cluster_offset(), Alberto Garcia, 2017/12/15
- [Qemu-devel] [PATCH v2 17/32] qcow2: Update get_cluster_table() to support L2 slices, Alberto Garcia, 2017/12/15
- [Qemu-devel] [PATCH v2 04/32] qcow2: Remove BDS parameter from qcow2_cache_get_table_idx(), Alberto Garcia, 2017/12/15
- [Qemu-devel] [PATCH v2 32/32] iotests: Add test for l2-cache-entry-size, Alberto Garcia, 2017/12/15
- [Qemu-devel] [PATCH v2 24/32] qcow2: Update qcow2_update_snapshot_refcount() to support L2 slices,
Alberto Garcia <=
- [Qemu-devel] [PATCH v2 31/32] qcow2: Allow configuring the L2 slice size, Alberto Garcia, 2017/12/15
- [Qemu-devel] [PATCH v2 07/32] qcow2: Remove BDS parameter from qcow2_cache_put(), Alberto Garcia, 2017/12/15
- [Qemu-devel] [PATCH v2 25/32] qcow2: Update expand_zero_clusters_in_l1() to support L2 slices, Alberto Garcia, 2017/12/15
- [Qemu-devel] [PATCH v2 10/32] qcow2: Remove BDS parameter from qcow2_cache_discard(), Alberto Garcia, 2017/12/15
- [Qemu-devel] [PATCH v2 18/32] qcow2: Update qcow2_get_cluster_offset() to support L2 slices, Alberto Garcia, 2017/12/15
- [Qemu-devel] [PATCH v2 20/32] qcow2: Update handle_copied() to support L2 slices, Alberto Garcia, 2017/12/15
- [Qemu-devel] [PATCH v2 16/32] qcow2: Update l2_allocate() to support L2 slices, Alberto Garcia, 2017/12/15
- [Qemu-devel] [PATCH v2 19/32] qcow2: Update qcow2_alloc_cluster_link_l2() to support L2 slices, Alberto Garcia, 2017/12/15
- [Qemu-devel] [PATCH v2 12/32] qcow2: Add offset_to_l1_index(), Alberto Garcia, 2017/12/15
- Re: [Qemu-devel] [PATCH v2 00/32] Allow configuring the qcow2 L2 cache entry size, no-reply, 2017/12/15