blob: f8492462ddaa6ed8f95a85cd289d85029577f9a5 [file] [log] [blame]
#ifndef KVM__QCOW_H
#define KVM__QCOW_H
#include "kvm/mutex.h"
#include <linux/types.h>
#include <stdbool.h>
#include <linux/rbtree.h>
#include <linux/list.h>
#define QCOW_MAGIC (('Q' << 24) | ('F' << 16) | ('I' << 8) | 0xfb)
#define QCOW1_VERSION 1
#define QCOW2_VERSION 2
#define QCOW1_OFLAG_COMPRESSED (1ULL << 63)
#define QCOW2_OFLAG_COPIED (1ULL << 63)
#define QCOW2_OFLAG_COMPRESSED (1ULL << 62)
#define QCOW2_OFLAGS_MASK (QCOW2_OFLAG_COPIED|QCOW2_OFLAG_COMPRESSED)
#define QCOW2_OFFSET_MASK (~QCOW2_OFLAGS_MASK)
#define MAX_CACHE_NODES 32
struct qcow_l2_table {
u64 offset;
struct rb_node node;
struct list_head list;
u8 dirty;
u64 table[];
};
struct qcow_l1_table {
u32 table_size;
u64 *l1_table;
/* Level2 caching data structures */
struct rb_root root;
struct list_head lru_list;
int nr_cached;
};
#define QCOW_REFCOUNT_BLOCK_SHIFT 1
struct qcow_refcount_block {
u64 offset;
struct rb_node node;
struct list_head list;
u64 size;
u8 dirty;
u16 entries[];
};
struct qcow_refcount_table {
u32 rf_size;
u64 *rf_table;
/* Refcount block caching data structures */
struct rb_root root;
struct list_head lru_list;
int nr_cached;
};
struct qcow_header {
u64 size; /* in bytes */
u64 l1_table_offset;
u32 l1_size;
u8 cluster_bits;
u8 l2_bits;
u64 refcount_table_offset;
u32 refcount_table_size;
};
struct qcow {
struct mutex mutex;
struct qcow_header *header;
struct qcow_l1_table table;
struct qcow_refcount_table refcount_table;
int fd;
int csize_shift;
int csize_mask;
u32 version;
u64 cluster_size;
u64 cluster_offset_mask;
u64 free_clust_idx;
void *cluster_cache;
void *cluster_data;
void *copy_buff;
};
struct qcow1_header_disk {
u32 magic;
u32 version;
u64 backing_file_offset;
u32 backing_file_size;
u32 mtime;
u64 size; /* in bytes */
u8 cluster_bits;
u8 l2_bits;
u32 crypt_method;
u64 l1_table_offset;
};
struct qcow2_header_disk {
u32 magic;
u32 version;
u64 backing_file_offset;
u32 backing_file_size;
u32 cluster_bits;
u64 size; /* in bytes */
u32 crypt_method;
u32 l1_size;
u64 l1_table_offset;
u64 refcount_table_offset;
u32 refcount_table_clusters;
u32 nb_snapshots;
u64 snapshots_offset;
};
struct disk_image *qcow_probe(int fd, bool readonly);
#endif /* KVM__QCOW_H */