aboutsummaryrefslogtreecommitdiff
path: root/block/qcow2-bitmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'block/qcow2-bitmap.c')
-rw-r--r--block/qcow2-bitmap.c76
1 files changed, 76 insertions, 0 deletions
diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
index b946301429..3ee524da4b 100644
--- a/block/qcow2-bitmap.c
+++ b/block/qcow2-bitmap.c
@@ -1006,6 +1006,82 @@ fail:
return false;
}
+
+static Qcow2BitmapInfoFlagsList *get_bitmap_info_flags(uint32_t flags)
+{
+ Qcow2BitmapInfoFlagsList *list = NULL;
+ Qcow2BitmapInfoFlagsList **plist = &list;
+ int i;
+
+ static const struct {
+ int bme; /* Bitmap directory entry flags */
+ int info; /* The flags to report to the user */
+ } map[] = {
+ { BME_FLAG_IN_USE, QCOW2_BITMAP_INFO_FLAGS_IN_USE },
+ { BME_FLAG_AUTO, QCOW2_BITMAP_INFO_FLAGS_AUTO },
+ };
+
+ int map_size = ARRAY_SIZE(map);
+
+ for (i = 0; i < map_size; ++i) {
+ if (flags & map[i].bme) {
+ Qcow2BitmapInfoFlagsList *entry =
+ g_new0(Qcow2BitmapInfoFlagsList, 1);
+ entry->value = map[i].info;
+ *plist = entry;
+ plist = &entry->next;
+ flags &= ~map[i].bme;
+ }
+ }
+ /* Check if the BME_* mapping above is complete */
+ assert(!flags);
+
+ return list;
+}
+
+/*
+ * qcow2_get_bitmap_info_list()
+ * Returns a list of QCOW2 bitmap details.
+ * In case of no bitmaps, the function returns NULL and
+ * the @errp parameter is not set.
+ * When bitmap information can not be obtained, the function returns
+ * NULL and the @errp parameter is set.
+ */
+Qcow2BitmapInfoList *qcow2_get_bitmap_info_list(BlockDriverState *bs,
+ Error **errp)
+{
+ BDRVQcow2State *s = bs->opaque;
+ Qcow2BitmapList *bm_list;
+ Qcow2Bitmap *bm;
+ Qcow2BitmapInfoList *list = NULL;
+ Qcow2BitmapInfoList **plist = &list;
+
+ if (s->nb_bitmaps == 0) {
+ return NULL;
+ }
+
+ bm_list = bitmap_list_load(bs, s->bitmap_directory_offset,
+ s->bitmap_directory_size, errp);
+ if (bm_list == NULL) {
+ return NULL;
+ }
+
+ QSIMPLEQ_FOREACH(bm, bm_list, entry) {
+ Qcow2BitmapInfo *info = g_new0(Qcow2BitmapInfo, 1);
+ Qcow2BitmapInfoList *obj = g_new0(Qcow2BitmapInfoList, 1);
+ info->granularity = 1U << bm->granularity_bits;
+ info->name = g_strdup(bm->name);
+ info->flags = get_bitmap_info_flags(bm->flags & ~BME_RESERVED_FLAGS);
+ obj->value = info;
+ *plist = obj;
+ plist = &obj->next;
+ }
+
+ bitmap_list_free(bm_list);
+
+ return list;
+}
+
int qcow2_reopen_bitmaps_rw_hint(BlockDriverState *bs, bool *header_updated,
Error **errp)
{