--- block/qcow2-cluster.c | 8 ++++++-- block/qcow2-dedup.c | 7 +++++++ block/qcow2.h | 3 +++ 3 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c index dbcb6d2..ef91216 100644 --- a/block/qcow2-cluster.c +++ b/block/qcow2-cluster.c @@ -709,6 +709,7 @@ int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m) qcow2_cache_entry_mark_dirty(s->l2_table_cache, l2_table); for (i = 0; i < m->nb_clusters; i++) { + uint64_t flags = 0; /* if two concurrent writes happen to the same unallocated cluster * each write allocates separate cluster and writes data concurrently. * The first one to complete updates l2 table with pointer to its @@ -718,9 +719,11 @@ int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m) if(l2_table[l2_index + i] != 0) old_cluster[j++] = l2_table[l2_index + i]; + flags = m->oflag_copied ? QCOW_OFLAG_COPIED : 0; + flags |= m->to_deduplicate ? QCOW_OFLAG_TO_DEDUP : 0; + l2_table[l2_index + i] = cpu_to_be64((cluster_offset + - (i << s->cluster_bits)) | - (m->oflag_copied ? QCOW_OFLAG_COPIED : 0)); + (i << s->cluster_bits)) | flags); } @@ -1036,6 +1039,7 @@ again: .oflag_copied = true, .overwrite = false, + .to_deduplicate = qcow2_must_deduplicate(bs), }; qemu_co_queue_init(&(*m)->dependent_requests); QLIST_INSERT_HEAD(&s->cluster_allocs, *m, next_in_flight); diff --git a/block/qcow2-dedup.c b/block/qcow2-dedup.c index de6e3a3..3d512e5 100644 --- a/block/qcow2-dedup.c +++ b/block/qcow2-dedup.c @@ -37,6 +37,12 @@ static int qcow2_dedup_read_write_hash(BlockDriverState *bs, uint64_t physical_sect, bool write); +bool qcow2_must_deduplicate(BlockDriverState *bs) +{ + BDRVQcowState *s = bs->opaque; + return s->has_dedup && s->dedup_status != QCOW_DEDUP_STARTED; +} + /* * Save the dedup table information into the header extensions * @@ -310,6 +316,7 @@ static int qcow2_dedup_link_l2(BlockDriverState *bs, }, .oflag_copied = false, .overwrite = overwrite, + .to_deduplicate = false, }; return qcow2_alloc_cluster_link_l2(bs, &m); } diff --git a/block/qcow2.h b/block/qcow2.h index 359a50f..da7e57e 100644 --- a/block/qcow2.h +++ b/block/qcow2.h @@ -312,6 +312,8 @@ typedef struct QCowL2Meta bool oflag_copied; /* set to true if we are overwriting an L2 table entry */ bool overwrite; + /* set to true if the cluster must be tagged with QCOW_OFLAG_TO_DEDUP */ + bool to_deduplicate; /** * The COW Region between the start of the first allocated cluster and the @@ -466,6 +468,7 @@ int qcow2_cache_get_empty(BlockDriverState *bs, Qcow2Cache *c, uint64_t offset, int qcow2_cache_put(BlockDriverState *bs, Qcow2Cache *c, void **table); /* qcow2-dedup.c functions */ +bool qcow2_must_deduplicate(BlockDriverState *bs); int qcow2_dedup_read_missing_and_concatenate(BlockDriverState *bs, QEMUIOVector *qiov, uint64_t sector, -- 1.7.10.4