|
@@ -105,8 +105,8 @@ int qcow2_refcount_init(BlockDriverState *bs)
|
|
s->get_refcount = get_refcount_funcs[s->refcount_order];
|
|
s->get_refcount = get_refcount_funcs[s->refcount_order];
|
|
s->set_refcount = set_refcount_funcs[s->refcount_order];
|
|
s->set_refcount = set_refcount_funcs[s->refcount_order];
|
|
|
|
|
|
- assert(s->refcount_table_size <= INT_MAX / sizeof(uint64_t));
|
|
|
|
- refcount_table_size2 = s->refcount_table_size * sizeof(uint64_t);
|
|
|
|
|
|
+ assert(s->refcount_table_size <= INT_MAX / REFTABLE_ENTRY_SIZE);
|
|
|
|
+ refcount_table_size2 = s->refcount_table_size * REFTABLE_ENTRY_SIZE;
|
|
s->refcount_table = g_try_malloc(refcount_table_size2);
|
|
s->refcount_table = g_try_malloc(refcount_table_size2);
|
|
|
|
|
|
if (s->refcount_table_size > 0) {
|
|
if (s->refcount_table_size > 0) {
|
|
@@ -434,8 +434,8 @@ static int alloc_refcount_block(BlockDriverState *bs,
|
|
if (refcount_table_index < s->refcount_table_size) {
|
|
if (refcount_table_index < s->refcount_table_size) {
|
|
uint64_t data64 = cpu_to_be64(new_block);
|
|
uint64_t data64 = cpu_to_be64(new_block);
|
|
BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_HOOKUP);
|
|
BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_HOOKUP);
|
|
- ret = bdrv_pwrite_sync(bs->file,
|
|
|
|
- s->refcount_table_offset + refcount_table_index * sizeof(uint64_t),
|
|
|
|
|
|
+ ret = bdrv_pwrite_sync(bs->file, s->refcount_table_offset +
|
|
|
|
+ refcount_table_index * REFTABLE_ENTRY_SIZE,
|
|
&data64, sizeof(data64));
|
|
&data64, sizeof(data64));
|
|
if (ret < 0) {
|
|
if (ret < 0) {
|
|
goto fail;
|
|
goto fail;
|
|
@@ -562,8 +562,8 @@ int64_t qcow2_refcount_area(BlockDriverState *bs, uint64_t start_offset,
|
|
DIV_ROUND_UP(total_refblock_count, 2);
|
|
DIV_ROUND_UP(total_refblock_count, 2);
|
|
}
|
|
}
|
|
/* The qcow2 file can only store the reftable size in number of clusters */
|
|
/* The qcow2 file can only store the reftable size in number of clusters */
|
|
- table_size = ROUND_UP(table_size, s->cluster_size / sizeof(uint64_t));
|
|
|
|
- table_clusters = (table_size * sizeof(uint64_t)) / s->cluster_size;
|
|
|
|
|
|
+ table_size = ROUND_UP(table_size, s->cluster_size / REFTABLE_ENTRY_SIZE);
|
|
|
|
+ table_clusters = (table_size * REFTABLE_ENTRY_SIZE) / s->cluster_size;
|
|
|
|
|
|
if (table_size > QCOW_MAX_REFTABLE_SIZE) {
|
|
if (table_size > QCOW_MAX_REFTABLE_SIZE) {
|
|
return -EFBIG;
|
|
return -EFBIG;
|
|
@@ -581,13 +581,13 @@ int64_t qcow2_refcount_area(BlockDriverState *bs, uint64_t start_offset,
|
|
if (table_size > s->max_refcount_table_index) {
|
|
if (table_size > s->max_refcount_table_index) {
|
|
/* We're actually growing the reftable */
|
|
/* We're actually growing the reftable */
|
|
memcpy(new_table, s->refcount_table,
|
|
memcpy(new_table, s->refcount_table,
|
|
- (s->max_refcount_table_index + 1) * sizeof(uint64_t));
|
|
|
|
|
|
+ (s->max_refcount_table_index + 1) * REFTABLE_ENTRY_SIZE);
|
|
} else {
|
|
} else {
|
|
/* Improbable case: We're shrinking the reftable. However, the caller
|
|
/* Improbable case: We're shrinking the reftable. However, the caller
|
|
* has assured us that there is only empty space beyond @start_offset,
|
|
* has assured us that there is only empty space beyond @start_offset,
|
|
* so we can simply drop all of the refblocks that won't fit into the
|
|
* so we can simply drop all of the refblocks that won't fit into the
|
|
* new reftable. */
|
|
* new reftable. */
|
|
- memcpy(new_table, s->refcount_table, table_size * sizeof(uint64_t));
|
|
|
|
|
|
+ memcpy(new_table, s->refcount_table, table_size * REFTABLE_ENTRY_SIZE);
|
|
}
|
|
}
|
|
|
|
|
|
if (new_refblock_offset) {
|
|
if (new_refblock_offset) {
|
|
@@ -682,7 +682,7 @@ int64_t qcow2_refcount_area(BlockDriverState *bs, uint64_t start_offset,
|
|
|
|
|
|
BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_WRITE_TABLE);
|
|
BLKDBG_EVENT(bs->file, BLKDBG_REFBLOCK_ALLOC_WRITE_TABLE);
|
|
ret = bdrv_pwrite_sync(bs->file, table_offset, new_table,
|
|
ret = bdrv_pwrite_sync(bs->file, table_offset, new_table,
|
|
- table_size * sizeof(uint64_t));
|
|
|
|
|
|
+ table_size * REFTABLE_ENTRY_SIZE);
|
|
if (ret < 0) {
|
|
if (ret < 0) {
|
|
goto fail;
|
|
goto fail;
|
|
}
|
|
}
|
|
@@ -717,7 +717,8 @@ int64_t qcow2_refcount_area(BlockDriverState *bs, uint64_t start_offset,
|
|
update_max_refcount_table_index(s);
|
|
update_max_refcount_table_index(s);
|
|
|
|
|
|
/* Free old table. */
|
|
/* Free old table. */
|
|
- qcow2_free_clusters(bs, old_table_offset, old_table_size * sizeof(uint64_t),
|
|
|
|
|
|
+ qcow2_free_clusters(bs, old_table_offset,
|
|
|
|
+ old_table_size * REFTABLE_ENTRY_SIZE,
|
|
QCOW2_DISCARD_OTHER);
|
|
QCOW2_DISCARD_OTHER);
|
|
|
|
|
|
return end_offset;
|
|
return end_offset;
|
|
@@ -1253,7 +1254,7 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
|
|
|
|
|
|
l2_slice = NULL;
|
|
l2_slice = NULL;
|
|
l1_table = NULL;
|
|
l1_table = NULL;
|
|
- l1_size2 = l1_size * sizeof(uint64_t);
|
|
|
|
|
|
+ l1_size2 = l1_size * L1E_SIZE;
|
|
slice_size2 = s->l2_slice_size * l2_entry_size(s);
|
|
slice_size2 = s->l2_slice_size * l2_entry_size(s);
|
|
n_slices = s->cluster_size / slice_size2;
|
|
n_slices = s->cluster_size / slice_size2;
|
|
|
|
|
|
@@ -1784,7 +1785,7 @@ static int check_refcounts_l1(BlockDriverState *bs,
|
|
uint64_t *l1_table = NULL, l2_offset, l1_size2;
|
|
uint64_t *l1_table = NULL, l2_offset, l1_size2;
|
|
int i, ret;
|
|
int i, ret;
|
|
|
|
|
|
- l1_size2 = l1_size * sizeof(uint64_t);
|
|
|
|
|
|
+ l1_size2 = l1_size * L1E_SIZE;
|
|
|
|
|
|
/* Mark L1 table as used */
|
|
/* Mark L1 table as used */
|
|
ret = qcow2_inc_refcounts_imrt(bs, res, refcount_table, refcount_table_size,
|
|
ret = qcow2_inc_refcounts_imrt(bs, res, refcount_table, refcount_table_size,
|
|
@@ -2146,7 +2147,7 @@ static int calculate_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
|
|
res->corruptions++;
|
|
res->corruptions++;
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
- if (sn->l1_size > QCOW_MAX_L1_SIZE / sizeof(uint64_t)) {
|
|
|
|
|
|
+ if (sn->l1_size > QCOW_MAX_L1_SIZE / L1E_SIZE) {
|
|
fprintf(stderr, "ERROR snapshot %s (%s) l1_size=%#" PRIx32 ": "
|
|
fprintf(stderr, "ERROR snapshot %s (%s) l1_size=%#" PRIx32 ": "
|
|
"L1 table is too large; snapshot table entry corrupted\n",
|
|
"L1 table is too large; snapshot table entry corrupted\n",
|
|
sn->id_str, sn->name, sn->l1_size);
|
|
sn->id_str, sn->name, sn->l1_size);
|
|
@@ -2169,7 +2170,8 @@ static int calculate_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
|
|
/* refcount data */
|
|
/* refcount data */
|
|
ret = qcow2_inc_refcounts_imrt(bs, res, refcount_table, nb_clusters,
|
|
ret = qcow2_inc_refcounts_imrt(bs, res, refcount_table, nb_clusters,
|
|
s->refcount_table_offset,
|
|
s->refcount_table_offset,
|
|
- s->refcount_table_size * sizeof(uint64_t));
|
|
|
|
|
|
+ s->refcount_table_size *
|
|
|
|
+ REFTABLE_ENTRY_SIZE);
|
|
if (ret < 0) {
|
|
if (ret < 0) {
|
|
return ret;
|
|
return ret;
|
|
}
|
|
}
|
|
@@ -2390,11 +2392,11 @@ write_refblocks:
|
|
uint32_t old_reftable_size = reftable_size;
|
|
uint32_t old_reftable_size = reftable_size;
|
|
uint64_t *new_on_disk_reftable;
|
|
uint64_t *new_on_disk_reftable;
|
|
|
|
|
|
- reftable_size = ROUND_UP((refblock_index + 1) * sizeof(uint64_t),
|
|
|
|
- s->cluster_size) / sizeof(uint64_t);
|
|
|
|
|
|
+ reftable_size = ROUND_UP((refblock_index + 1) * REFTABLE_ENTRY_SIZE,
|
|
|
|
+ s->cluster_size) / REFTABLE_ENTRY_SIZE;
|
|
new_on_disk_reftable = g_try_realloc(on_disk_reftable,
|
|
new_on_disk_reftable = g_try_realloc(on_disk_reftable,
|
|
reftable_size *
|
|
reftable_size *
|
|
- sizeof(uint64_t));
|
|
|
|
|
|
+ REFTABLE_ENTRY_SIZE);
|
|
if (!new_on_disk_reftable) {
|
|
if (!new_on_disk_reftable) {
|
|
res->check_errors++;
|
|
res->check_errors++;
|
|
ret = -ENOMEM;
|
|
ret = -ENOMEM;
|
|
@@ -2403,7 +2405,7 @@ write_refblocks:
|
|
on_disk_reftable = new_on_disk_reftable;
|
|
on_disk_reftable = new_on_disk_reftable;
|
|
|
|
|
|
memset(on_disk_reftable + old_reftable_size, 0,
|
|
memset(on_disk_reftable + old_reftable_size, 0,
|
|
- (reftable_size - old_reftable_size) * sizeof(uint64_t));
|
|
|
|
|
|
+ (reftable_size - old_reftable_size) * REFTABLE_ENTRY_SIZE);
|
|
|
|
|
|
/* The offset we have for the reftable is now no longer valid;
|
|
/* The offset we have for the reftable is now no longer valid;
|
|
* this will leak that range, but we can easily fix that by running
|
|
* this will leak that range, but we can easily fix that by running
|
|
@@ -2420,7 +2422,7 @@ write_refblocks:
|
|
reftable_offset < 0)
|
|
reftable_offset < 0)
|
|
{
|
|
{
|
|
uint64_t reftable_clusters = size_to_clusters(s, reftable_size *
|
|
uint64_t reftable_clusters = size_to_clusters(s, reftable_size *
|
|
- sizeof(uint64_t));
|
|
|
|
|
|
+ REFTABLE_ENTRY_SIZE);
|
|
reftable_offset = alloc_clusters_imrt(bs, reftable_clusters,
|
|
reftable_offset = alloc_clusters_imrt(bs, reftable_clusters,
|
|
refcount_table, nb_clusters,
|
|
refcount_table, nb_clusters,
|
|
&first_free_cluster);
|
|
&first_free_cluster);
|
|
@@ -2460,8 +2462,8 @@ write_refblocks:
|
|
uint64_t post_refblock_start, reftable_clusters;
|
|
uint64_t post_refblock_start, reftable_clusters;
|
|
|
|
|
|
post_refblock_start = ROUND_UP(*nb_clusters, s->refcount_block_size);
|
|
post_refblock_start = ROUND_UP(*nb_clusters, s->refcount_block_size);
|
|
- reftable_clusters = size_to_clusters(s,
|
|
|
|
- reftable_size * sizeof(uint64_t));
|
|
|
|
|
|
+ reftable_clusters =
|
|
|
|
+ size_to_clusters(s, reftable_size * REFTABLE_ENTRY_SIZE);
|
|
/* Not pretty but simple */
|
|
/* Not pretty but simple */
|
|
if (first_free_cluster < post_refblock_start) {
|
|
if (first_free_cluster < post_refblock_start) {
|
|
first_free_cluster = post_refblock_start;
|
|
first_free_cluster = post_refblock_start;
|
|
@@ -2485,16 +2487,16 @@ write_refblocks:
|
|
}
|
|
}
|
|
|
|
|
|
ret = qcow2_pre_write_overlap_check(bs, 0, reftable_offset,
|
|
ret = qcow2_pre_write_overlap_check(bs, 0, reftable_offset,
|
|
- reftable_size * sizeof(uint64_t),
|
|
|
|
|
|
+ reftable_size * REFTABLE_ENTRY_SIZE,
|
|
false);
|
|
false);
|
|
if (ret < 0) {
|
|
if (ret < 0) {
|
|
fprintf(stderr, "ERROR writing reftable: %s\n", strerror(-ret));
|
|
fprintf(stderr, "ERROR writing reftable: %s\n", strerror(-ret));
|
|
goto fail;
|
|
goto fail;
|
|
}
|
|
}
|
|
|
|
|
|
- assert(reftable_size < INT_MAX / sizeof(uint64_t));
|
|
|
|
|
|
+ assert(reftable_size < INT_MAX / REFTABLE_ENTRY_SIZE);
|
|
ret = bdrv_pwrite(bs->file, reftable_offset, on_disk_reftable,
|
|
ret = bdrv_pwrite(bs->file, reftable_offset, on_disk_reftable,
|
|
- reftable_size * sizeof(uint64_t));
|
|
|
|
|
|
+ reftable_size * REFTABLE_ENTRY_SIZE);
|
|
if (ret < 0) {
|
|
if (ret < 0) {
|
|
fprintf(stderr, "ERROR writing reftable: %s\n", strerror(-ret));
|
|
fprintf(stderr, "ERROR writing reftable: %s\n", strerror(-ret));
|
|
goto fail;
|
|
goto fail;
|
|
@@ -2503,7 +2505,7 @@ write_refblocks:
|
|
/* Enter new reftable into the image header */
|
|
/* Enter new reftable into the image header */
|
|
reftable_offset_and_clusters.reftable_offset = cpu_to_be64(reftable_offset);
|
|
reftable_offset_and_clusters.reftable_offset = cpu_to_be64(reftable_offset);
|
|
reftable_offset_and_clusters.reftable_clusters =
|
|
reftable_offset_and_clusters.reftable_clusters =
|
|
- cpu_to_be32(size_to_clusters(s, reftable_size * sizeof(uint64_t)));
|
|
|
|
|
|
+ cpu_to_be32(size_to_clusters(s, reftable_size * REFTABLE_ENTRY_SIZE));
|
|
ret = bdrv_pwrite_sync(bs->file,
|
|
ret = bdrv_pwrite_sync(bs->file,
|
|
offsetof(QCowHeader, refcount_table_offset),
|
|
offsetof(QCowHeader, refcount_table_offset),
|
|
&reftable_offset_and_clusters,
|
|
&reftable_offset_and_clusters,
|
|
@@ -2693,14 +2695,14 @@ int qcow2_check_metadata_overlap(BlockDriverState *bs, int ign, int64_t offset,
|
|
offset = start_of_cluster(s, offset);
|
|
offset = start_of_cluster(s, offset);
|
|
|
|
|
|
if ((chk & QCOW2_OL_ACTIVE_L1) && s->l1_size) {
|
|
if ((chk & QCOW2_OL_ACTIVE_L1) && s->l1_size) {
|
|
- if (overlaps_with(s->l1_table_offset, s->l1_size * sizeof(uint64_t))) {
|
|
|
|
|
|
+ if (overlaps_with(s->l1_table_offset, s->l1_size * L1E_SIZE)) {
|
|
return QCOW2_OL_ACTIVE_L1;
|
|
return QCOW2_OL_ACTIVE_L1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
if ((chk & QCOW2_OL_REFCOUNT_TABLE) && s->refcount_table_size) {
|
|
if ((chk & QCOW2_OL_REFCOUNT_TABLE) && s->refcount_table_size) {
|
|
if (overlaps_with(s->refcount_table_offset,
|
|
if (overlaps_with(s->refcount_table_offset,
|
|
- s->refcount_table_size * sizeof(uint64_t))) {
|
|
|
|
|
|
+ s->refcount_table_size * REFTABLE_ENTRY_SIZE)) {
|
|
return QCOW2_OL_REFCOUNT_TABLE;
|
|
return QCOW2_OL_REFCOUNT_TABLE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -2715,7 +2717,7 @@ int qcow2_check_metadata_overlap(BlockDriverState *bs, int ign, int64_t offset,
|
|
for (i = 0; i < s->nb_snapshots; i++) {
|
|
for (i = 0; i < s->nb_snapshots; i++) {
|
|
if (s->snapshots[i].l1_size &&
|
|
if (s->snapshots[i].l1_size &&
|
|
overlaps_with(s->snapshots[i].l1_table_offset,
|
|
overlaps_with(s->snapshots[i].l1_table_offset,
|
|
- s->snapshots[i].l1_size * sizeof(uint64_t))) {
|
|
|
|
|
|
+ s->snapshots[i].l1_size * L1E_SIZE)) {
|
|
return QCOW2_OL_INACTIVE_L1;
|
|
return QCOW2_OL_INACTIVE_L1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -2749,11 +2751,11 @@ int qcow2_check_metadata_overlap(BlockDriverState *bs, int ign, int64_t offset,
|
|
for (i = 0; i < s->nb_snapshots; i++) {
|
|
for (i = 0; i < s->nb_snapshots; i++) {
|
|
uint64_t l1_ofs = s->snapshots[i].l1_table_offset;
|
|
uint64_t l1_ofs = s->snapshots[i].l1_table_offset;
|
|
uint32_t l1_sz = s->snapshots[i].l1_size;
|
|
uint32_t l1_sz = s->snapshots[i].l1_size;
|
|
- uint64_t l1_sz2 = l1_sz * sizeof(uint64_t);
|
|
|
|
|
|
+ uint64_t l1_sz2 = l1_sz * L1E_SIZE;
|
|
uint64_t *l1;
|
|
uint64_t *l1;
|
|
int ret;
|
|
int ret;
|
|
|
|
|
|
- ret = qcow2_validate_table(bs, l1_ofs, l1_sz, sizeof(uint64_t),
|
|
|
|
|
|
+ ret = qcow2_validate_table(bs, l1_ofs, l1_sz, L1E_SIZE,
|
|
QCOW_MAX_L1_SIZE, "", NULL);
|
|
QCOW_MAX_L1_SIZE, "", NULL);
|
|
if (ret < 0) {
|
|
if (ret < 0) {
|
|
return ret;
|
|
return ret;
|
|
@@ -2877,8 +2879,8 @@ static int alloc_refblock(BlockDriverState *bs, uint64_t **reftable,
|
|
uint64_t new_reftable_size;
|
|
uint64_t new_reftable_size;
|
|
|
|
|
|
new_reftable_size = ROUND_UP(reftable_index + 1,
|
|
new_reftable_size = ROUND_UP(reftable_index + 1,
|
|
- s->cluster_size / sizeof(uint64_t));
|
|
|
|
- if (new_reftable_size > QCOW_MAX_REFTABLE_SIZE / sizeof(uint64_t)) {
|
|
|
|
|
|
+ s->cluster_size / REFTABLE_ENTRY_SIZE);
|
|
|
|
+ if (new_reftable_size > QCOW_MAX_REFTABLE_SIZE / REFTABLE_ENTRY_SIZE) {
|
|
error_setg(errp,
|
|
error_setg(errp,
|
|
"This operation would make the refcount table grow "
|
|
"This operation would make the refcount table grow "
|
|
"beyond the maximum size supported by QEMU, aborting");
|
|
"beyond the maximum size supported by QEMU, aborting");
|
|
@@ -2886,14 +2888,14 @@ static int alloc_refblock(BlockDriverState *bs, uint64_t **reftable,
|
|
}
|
|
}
|
|
|
|
|
|
new_reftable = g_try_realloc(*reftable, new_reftable_size *
|
|
new_reftable = g_try_realloc(*reftable, new_reftable_size *
|
|
- sizeof(uint64_t));
|
|
|
|
|
|
+ REFTABLE_ENTRY_SIZE);
|
|
if (!new_reftable) {
|
|
if (!new_reftable) {
|
|
error_setg(errp, "Failed to increase reftable buffer size");
|
|
error_setg(errp, "Failed to increase reftable buffer size");
|
|
return -ENOMEM;
|
|
return -ENOMEM;
|
|
}
|
|
}
|
|
|
|
|
|
memset(new_reftable + *reftable_size, 0,
|
|
memset(new_reftable + *reftable_size, 0,
|
|
- (new_reftable_size - *reftable_size) * sizeof(uint64_t));
|
|
|
|
|
|
+ (new_reftable_size - *reftable_size) * REFTABLE_ENTRY_SIZE);
|
|
|
|
|
|
*reftable = new_reftable;
|
|
*reftable = new_reftable;
|
|
*reftable_size = new_reftable_size;
|
|
*reftable_size = new_reftable_size;
|
|
@@ -3164,13 +3166,14 @@ int qcow2_change_refcount_order(BlockDriverState *bs, int refcount_order,
|
|
|
|
|
|
if (new_allocation) {
|
|
if (new_allocation) {
|
|
if (new_reftable_offset) {
|
|
if (new_reftable_offset) {
|
|
- qcow2_free_clusters(bs, new_reftable_offset,
|
|
|
|
- allocated_reftable_size * sizeof(uint64_t),
|
|
|
|
- QCOW2_DISCARD_NEVER);
|
|
|
|
|
|
+ qcow2_free_clusters(
|
|
|
|
+ bs, new_reftable_offset,
|
|
|
|
+ allocated_reftable_size * REFTABLE_ENTRY_SIZE,
|
|
|
|
+ QCOW2_DISCARD_NEVER);
|
|
}
|
|
}
|
|
|
|
|
|
new_reftable_offset = qcow2_alloc_clusters(bs, new_reftable_size *
|
|
new_reftable_offset = qcow2_alloc_clusters(bs, new_reftable_size *
|
|
- sizeof(uint64_t));
|
|
|
|
|
|
+ REFTABLE_ENTRY_SIZE);
|
|
if (new_reftable_offset < 0) {
|
|
if (new_reftable_offset < 0) {
|
|
error_setg_errno(errp, -new_reftable_offset,
|
|
error_setg_errno(errp, -new_reftable_offset,
|
|
"Failed to allocate the new reftable");
|
|
"Failed to allocate the new reftable");
|
|
@@ -3196,7 +3199,7 @@ int qcow2_change_refcount_order(BlockDriverState *bs, int refcount_order,
|
|
|
|
|
|
/* Write the new reftable */
|
|
/* Write the new reftable */
|
|
ret = qcow2_pre_write_overlap_check(bs, 0, new_reftable_offset,
|
|
ret = qcow2_pre_write_overlap_check(bs, 0, new_reftable_offset,
|
|
- new_reftable_size * sizeof(uint64_t),
|
|
|
|
|
|
+ new_reftable_size * REFTABLE_ENTRY_SIZE,
|
|
false);
|
|
false);
|
|
if (ret < 0) {
|
|
if (ret < 0) {
|
|
error_setg_errno(errp, -ret, "Overlap check failed");
|
|
error_setg_errno(errp, -ret, "Overlap check failed");
|
|
@@ -3208,7 +3211,7 @@ int qcow2_change_refcount_order(BlockDriverState *bs, int refcount_order,
|
|
}
|
|
}
|
|
|
|
|
|
ret = bdrv_pwrite(bs->file, new_reftable_offset, new_reftable,
|
|
ret = bdrv_pwrite(bs->file, new_reftable_offset, new_reftable,
|
|
- new_reftable_size * sizeof(uint64_t));
|
|
|
|
|
|
+ new_reftable_size * REFTABLE_ENTRY_SIZE);
|
|
|
|
|
|
for (i = 0; i < new_reftable_size; i++) {
|
|
for (i = 0; i < new_reftable_size; i++) {
|
|
be64_to_cpus(&new_reftable[i]);
|
|
be64_to_cpus(&new_reftable[i]);
|
|
@@ -3285,7 +3288,7 @@ done:
|
|
|
|
|
|
if (new_reftable_offset > 0) {
|
|
if (new_reftable_offset > 0) {
|
|
qcow2_free_clusters(bs, new_reftable_offset,
|
|
qcow2_free_clusters(bs, new_reftable_offset,
|
|
- new_reftable_size * sizeof(uint64_t),
|
|
|
|
|
|
+ new_reftable_size * REFTABLE_ENTRY_SIZE,
|
|
QCOW2_DISCARD_OTHER);
|
|
QCOW2_DISCARD_OTHER);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -3374,7 +3377,7 @@ int qcow2_shrink_reftable(BlockDriverState *bs)
|
|
{
|
|
{
|
|
BDRVQcow2State *s = bs->opaque;
|
|
BDRVQcow2State *s = bs->opaque;
|
|
uint64_t *reftable_tmp =
|
|
uint64_t *reftable_tmp =
|
|
- g_malloc(s->refcount_table_size * sizeof(uint64_t));
|
|
|
|
|
|
+ g_malloc(s->refcount_table_size * REFTABLE_ENTRY_SIZE);
|
|
int i, ret;
|
|
int i, ret;
|
|
|
|
|
|
for (i = 0; i < s->refcount_table_size; i++) {
|
|
for (i = 0; i < s->refcount_table_size; i++) {
|
|
@@ -3412,7 +3415,7 @@ int qcow2_shrink_reftable(BlockDriverState *bs)
|
|
}
|
|
}
|
|
|
|
|
|
ret = bdrv_pwrite_sync(bs->file, s->refcount_table_offset, reftable_tmp,
|
|
ret = bdrv_pwrite_sync(bs->file, s->refcount_table_offset, reftable_tmp,
|
|
- s->refcount_table_size * sizeof(uint64_t));
|
|
|
|
|
|
+ s->refcount_table_size * REFTABLE_ENTRY_SIZE);
|
|
/*
|
|
/*
|
|
* If the write in the reftable failed the image may contain a partially
|
|
* If the write in the reftable failed the image may contain a partially
|
|
* overwritten reftable. In this case it would be better to clear the
|
|
* overwritten reftable. In this case it would be better to clear the
|