From: Vladimir Sementsov-Ogievskiy <[email protected]>
Signed-off-by: Vladimir Sementsov-Ogievskiy <[email protected]>
---
block/qcow2-dirty-bitmap.c | 5 +++++
block/qcow2.c | 13 +++++++++++--
block/qcow2.h | 9 +++++++++
3 files changed, 25 insertions(+), 2 deletions(-)
diff --git a/block/qcow2-dirty-bitmap.c b/block/qcow2-dirty-bitmap.c
index db83112..686a121 100644
--- a/block/qcow2-dirty-bitmap.c
+++ b/block/qcow2-dirty-bitmap.c
@@ -188,6 +188,11 @@ static int qcow2_write_dirty_bitmaps(BlockDriverState *bs)
s->dirty_bitmaps_offset = dirty_bitmaps_offset;
s->dirty_bitmaps_size = dirty_bitmaps_size;
+ if (s->nb_dirty_bitmaps > 0) {
+ s->autoclear_features |= QCOW2_AUTOCLEAR_DIRTY_BITMAPS;
+ } else {
+ s->autoclear_features &= ~QCOW2_AUTOCLEAR_DIRTY_BITMAPS;
+ }
ret = qcow2_update_header(bs);
if (ret < 0) {
fprintf(stderr, "Could not update qcow2 header\n");
diff --git a/block/qcow2.c b/block/qcow2.c
index 406e55d..f85a55a 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -182,6 +182,14 @@ static int qcow2_read_extensions(BlockDriverState *bs,
uint64_t start_offset,
return ret;
}
+ if (!(s->autoclear_features & QCOW2_AUTOCLEAR_DIRTY_BITMAPS) &&
+ s->nb_dirty_bitmaps > 0) {
+ ret = qcow2_delete_all_dirty_bitmaps(bs, errp);
+ if (ret < 0) {
+ return ret;
+ }
+ }
+
#ifdef DEBUG_EXT
printf("Qcow2: Got dirty bitmaps extension:"
" offset=%" PRIu64 " nb_bitmaps=%" PRIu32 "\n",
@@ -928,8 +936,9 @@ static int qcow2_open(BlockDriverState *bs, QDict *options,
int flags,
}
/* Clear unknown autoclear feature bits */
- if (!bs->read_only && !(flags & BDRV_O_INCOMING) && s->autoclear_features)
{
- s->autoclear_features = 0;
+ if (!bs->read_only && !(flags & BDRV_O_INCOMING) &&
+ (s->autoclear_features & ~QCOW2_AUTOCLEAR_MASK)) {
+ s->autoclear_features |= QCOW2_AUTOCLEAR_MASK;
ret = qcow2_update_header(bs);
if (ret < 0) {
error_setg_errno(errp, -ret, "Could not update qcow2 header");
diff --git a/block/qcow2.h b/block/qcow2.h
index b5e576c..14bd6f9 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -215,6 +215,15 @@ enum {
QCOW2_COMPAT_FEAT_MASK = QCOW2_COMPAT_LAZY_REFCOUNTS,
};
+/* Autoclear feature bits */
+enum {
+ QCOW2_AUTOCLEAR_DIRTY_BITMAPS_BITNR = 0,
+ QCOW2_AUTOCLEAR_DIRTY_BITMAPS =
+ 1 << QCOW2_AUTOCLEAR_DIRTY_BITMAPS_BITNR,
+
+ QCOW2_AUTOCLEAR_MASK = QCOW2_AUTOCLEAR_DIRTY_BITMAPS,
+};
+
enum qcow2_discard_type {
QCOW2_DISCARD_NEVER = 0,
QCOW2_DISCARD_ALWAYS,
--
1.9.1