@@ -58,6 +58,23 @@
#define DEFAULT_CLUSTER_SIZE 65536
+/* deduplication node */
+typedef struct {
+ uint8_t *hash; /* 32 bytes hash of a given cluster */
+ uint64_t offset; /* offset where the cluster is stored (sectors) */
+ uint64_t first_logical_offset;
+} QCowHashNode;
+
+/* Undedupable hashes that must be written later to disk */
+typedef struct QCowHashElement {
+ uint8_t *hash;
+ QTAILQ_ENTRY(QCowHashElement) next;
+} QCowHashElement;
+
+typedef struct UndedupableHashes {
+ QTAILQ_HEAD(, QCowHashElement) undedupable_hashes;
+} UndedupableHashes;
+
typedef struct QCowHeader {
uint32_t magic;
uint32_t version;
@@ -114,8 +131,10 @@ enum {
enum {
QCOW2_INCOMPAT_DIRTY_BITNR = 0,
QCOW2_INCOMPAT_DIRTY = 1 << QCOW2_INCOMPAT_DIRTY_BITNR,
+ QCOW2_INCOMPAT_DEDUP_BITNR = 1,
+ QCOW2_INCOMPAT_DEDUP = 1 << QCOW2_INCOMPAT_DEDUP_BITNR,
- QCOW2_INCOMPAT_MASK = QCOW2_INCOMPAT_DIRTY,
+ QCOW2_INCOMPAT_MASK = QCOW2_INCOMPAT_DIRTY | QCOW2_INCOMPAT_DEDUP,
};
/* Compatible feature bits */
@@ -148,6 +167,7 @@ typedef struct BDRVQcowState {
Qcow2Cache* l2_table_cache;
Qcow2Cache* refcount_block_cache;
+ Qcow2Cache *dedup_cluster_cache;
uint8_t *cluster_cache;
uint8_t *cluster_data;
@@ -160,6 +180,12 @@ typedef struct BDRVQcowState {
int64_t free_cluster_index;
int64_t free_byte_offset;
+ bool has_dedup;
+ uint64_t *dedup_table;
+ uint64_t dedup_table_offset;
+ int32_t dedup_table_size;
+ GTree *dedup_tree_by_hash;
+ GTree *dedup_tree_by_offset;
CoMutex lock;
uint32_t crypt_method; /* current crypt method, 0 if no key yet */
Signed-off-by: Benoit Canet <benoit@irqsave.net> --- block/qcow2.h | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-)