summaryrefslogtreecommitdiffstats
path: root/block/qcow2.c
diff options
context:
space:
mode:
Diffstat (limited to 'block/qcow2.c')
-rw-r--r--block/qcow2.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/block/qcow2.c b/block/qcow2.c
index 4d6666d3ff..a97f7b431a 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -5925,6 +5925,42 @@ void qcow2_signal_corruption(BlockDriverState *bs, bool fatal, int64_t offset,
s->signaled_corruption = true;
}
+#ifdef CONFIG_BDRV_CLUSTER_INFO
+int qcow2_get_cluster_info(BlockDriverState *bs, uint64_t offset)
+{
+ BDRVQcow2State *s = bs->opaque;
+ uint64_t host_offset;
+ uint64_t coffset;
+ unsigned int bytes;
+ QCow2SubclusterType type;
+ int ret = 0, csize, nb_csectors;
+
+ /* only get information for one byte */
+ bytes = 1;
+
+ ret = qcow2_get_host_offset(bs, offset, &bytes, &host_offset, &type);
+ if (ret < 0) {
+ return ret;
+ }
+
+ printf("cluster type: %s\n", qcow2_get_subcluster_name(type));
+ printf("cluster offset host: %ld\n", host_offset);
+ printf("cluster offset guest: %ld\n", offset);
+ printf("cluster offset in-cluster: %ld\n", offset_into_cluster(s, offset));
+
+ if (type == QCOW2_SUBCLUSTER_COMPRESSED) {
+ qcow2_parse_compressed_l2_entry(bs, host_offset, &coffset, &csize);
+ nb_csectors = ((host_offset >> s->csize_shift) & s->csize_mask) + 1;
+
+ printf("cluster compressed offset: %ld\n", coffset);
+ printf("cluster compressed sectors: %d\n", nb_csectors);
+ printf("cluster compressed size: %d\n", csize);
+ }
+
+ return ret;
+}
+#endif
+
#define QCOW_COMMON_OPTIONS \
{ \
.name = BLOCK_OPT_SIZE, \
@@ -6108,6 +6144,10 @@ BlockDriver bdrv_qcow2 = {
.bdrv_co_can_store_new_dirty_bitmap = qcow2_co_can_store_new_dirty_bitmap,
.bdrv_co_remove_persistent_dirty_bitmap =
qcow2_co_remove_persistent_dirty_bitmap,
+
+#ifdef CONFIG_BDRV_CLUSTER_INFO
+ .bdrv_get_cluster_info = qcow2_get_cluster_info,
+#endif
};
static void bdrv_qcow2_init(void)