goto fail;
}
- if (is_active_l1) {
- /* get active L2 tables from cache */
- ret = qcow2_cache_get(bs, s->l2_table_cache, l2_offset,
- (void **)&l2_table);
- } else {
- /* load inactive L2 tables from disk */
- ret = bdrv_read(bs->file, l2_offset / BDRV_SECTOR_SIZE,
- (void *)l2_table, s->cluster_sectors);
- }
- if (ret < 0) {
- goto fail;
- }
-
- for (j = 0; j < s->l2_size; j++) {
- uint64_t l2_entry = be64_to_cpu(l2_table[j]);
- int64_t offset = l2_entry & L2E_OFFSET_MASK;
- QCow2ClusterType cluster_type = qcow2_get_cluster_type(l2_entry);
-
- if (cluster_type != QCOW2_CLUSTER_ZERO_PLAIN &&
- cluster_type != QCOW2_CLUSTER_ZERO_ALLOC) {
- continue;
+ {
+ if (is_active_l1) {
+ /* get active L2 tables from cache */
+ ret = qcow2_cache_get(bs, s->l2_table_cache, l2_offset,
+ (void **)&l2_table);
+ } else {
+ /* load inactive L2 tables from disk */
+ ret = bdrv_read(bs->file, l2_offset / BDRV_SECTOR_SIZE,
+ (void *)l2_table, s->cluster_sectors);
+ }
+ if (ret < 0) {
+ goto fail;
}
- if (cluster_type == QCOW2_CLUSTER_ZERO_PLAIN) {
- if (!bs->backing) {
- /* not backed; therefore we can simply deallocate the
- * cluster */
- l2_table[j] = 0;
- l2_dirty = true;
+ for (j = 0; j < s->l2_size; j++) {
+ uint64_t l2_entry = be64_to_cpu(l2_table[j]);
+ int64_t offset = l2_entry & L2E_OFFSET_MASK;
+ QCow2ClusterType cluster_type =
+ qcow2_get_cluster_type(l2_entry);
+
+ if (cluster_type != QCOW2_CLUSTER_ZERO_PLAIN &&
+ cluster_type != QCOW2_CLUSTER_ZERO_ALLOC) {
continue;
}
- offset = qcow2_alloc_clusters(bs, s->cluster_size);
- if (offset < 0) {
- ret = offset;
- goto fail;
- }
+ if (cluster_type == QCOW2_CLUSTER_ZERO_PLAIN) {
+ if (!bs->backing) {
+ /* not backed; therefore we can simply deallocate the
+ * cluster */
+ l2_table[j] = 0;
+ l2_dirty = true;
+ continue;
+ }
+
+ offset = qcow2_alloc_clusters(bs, s->cluster_size);
+ if (offset < 0) {
+ ret = offset;
+ goto fail;
+ }
- if (l2_refcount > 1) {
- /* For shared L2 tables, set the refcount accordingly (it is
- * already 1 and needs to be l2_refcount) */
- ret = qcow2_update_cluster_refcount(bs,
- offset >> s->cluster_bits,
+ if (l2_refcount > 1) {
+ /* For shared L2 tables, set the refcount accordingly
+ * (it is already 1 and needs to be l2_refcount) */
+ ret = qcow2_update_cluster_refcount(
+ bs, offset >> s->cluster_bits,
refcount_diff(1, l2_refcount), false,
QCOW2_DISCARD_OTHER);
- if (ret < 0) {
- qcow2_free_clusters(bs, offset, s->cluster_size,
- QCOW2_DISCARD_OTHER);
- goto fail;
+ if (ret < 0) {
+ qcow2_free_clusters(bs, offset, s->cluster_size,
+ QCOW2_DISCARD_OTHER);
+ goto fail;
+ }
}
}
- }
- 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);
- if (cluster_type == QCOW2_CLUSTER_ZERO_PLAIN) {
- qcow2_free_clusters(bs, offset, s->cluster_size,
- QCOW2_DISCARD_ALWAYS);
+ 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);
+ if (cluster_type == QCOW2_CLUSTER_ZERO_PLAIN) {
+ qcow2_free_clusters(bs, offset, s->cluster_size,
+ QCOW2_DISCARD_ALWAYS);
+ }
+ ret = -EIO;
+ goto fail;
}
- ret = -EIO;
- goto fail;
- }
- ret = qcow2_pre_write_overlap_check(bs, 0, offset, s->cluster_size);
- if (ret < 0) {
- if (cluster_type == QCOW2_CLUSTER_ZERO_PLAIN) {
- qcow2_free_clusters(bs, offset, s->cluster_size,
- QCOW2_DISCARD_ALWAYS);
+ ret = qcow2_pre_write_overlap_check(bs, 0, offset,
+ s->cluster_size);
+ if (ret < 0) {
+ if (cluster_type == QCOW2_CLUSTER_ZERO_PLAIN) {
+ qcow2_free_clusters(bs, offset, s->cluster_size,
+ QCOW2_DISCARD_ALWAYS);
+ }
+ goto fail;
}
- goto fail;
- }
- ret = bdrv_pwrite_zeroes(bs->file, offset, s->cluster_size, 0);
- if (ret < 0) {
- if (cluster_type == QCOW2_CLUSTER_ZERO_PLAIN) {
- qcow2_free_clusters(bs, offset, s->cluster_size,
- QCOW2_DISCARD_ALWAYS);
+ ret = bdrv_pwrite_zeroes(bs->file, offset, s->cluster_size, 0);
+ if (ret < 0) {
+ if (cluster_type == QCOW2_CLUSTER_ZERO_PLAIN) {
+ qcow2_free_clusters(bs, offset, s->cluster_size,
+ QCOW2_DISCARD_ALWAYS);
+ }
+ goto fail;
}
- goto fail;
- }
- if (l2_refcount == 1) {
- l2_table[j] = cpu_to_be64(offset | QCOW_OFLAG_COPIED);
- } else {
- l2_table[j] = cpu_to_be64(offset);
+ if (l2_refcount == 1) {
+ l2_table[j] = cpu_to_be64(offset | QCOW_OFLAG_COPIED);
+ } else {
+ l2_table[j] = cpu_to_be64(offset);
+ }
+ l2_dirty = true;
}
- l2_dirty = true;
- }
- if (is_active_l1) {
- if (l2_dirty) {
- qcow2_cache_entry_mark_dirty(s->l2_table_cache, l2_table);
- qcow2_cache_depends_on_flush(s->l2_table_cache);
- }
- qcow2_cache_put(s->l2_table_cache, (void **) &l2_table);
- } else {
- if (l2_dirty) {
- ret = qcow2_pre_write_overlap_check(bs,
- QCOW2_OL_INACTIVE_L2 | QCOW2_OL_ACTIVE_L2, l2_offset,
- s->cluster_size);
- if (ret < 0) {
- goto fail;
+ if (is_active_l1) {
+ if (l2_dirty) {
+ qcow2_cache_entry_mark_dirty(s->l2_table_cache, l2_table);
+ qcow2_cache_depends_on_flush(s->l2_table_cache);
}
+ qcow2_cache_put(s->l2_table_cache, (void **) &l2_table);
+ } else {
+ if (l2_dirty) {
+ ret = qcow2_pre_write_overlap_check(
+ bs, QCOW2_OL_INACTIVE_L2 | QCOW2_OL_ACTIVE_L2,
+ l2_offset, s->cluster_size);
+ if (ret < 0) {
+ goto fail;
+ }
- ret = bdrv_write(bs->file, l2_offset / BDRV_SECTOR_SIZE,
- (void *)l2_table, s->cluster_sectors);
- if (ret < 0) {
- goto fail;
+ ret = bdrv_write(bs->file, l2_offset / BDRV_SECTOR_SIZE,
+ (void *)l2_table, s->cluster_sectors);
+ if (ret < 0) {
+ goto fail;
+ }
}
}
}