From: Olga Krishtal <okrish...@virtuozzo.com>

While opening image we save dirty state in header_unclean.
If the image was closed incorrectly we can retrieve this fact
using bdrv_is_opened_unclean callback.

This is necessary in case when we want to call brdv_check to
repair dirty image.

Signed-off-by: Olga Krishtal <okrish...@virtuozzo.com>
Signed-off-by: Denis V. Lunev <d...@openvz.org>
CC: Kevin Wolf <kw...@redhat.com>
CC: Max Reitz <mre...@redhat.com>
CC: Eric Blake <ebl...@redhat.com>
CC: Fam Zheng <f...@redhat.com>
---
 block/qcow2.c | 11 ++++++++++-
 block/qcow2.h |  1 +
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/block/qcow2.c b/block/qcow2.c
index 1789af4..de3b97f 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -817,6 +817,11 @@ static int qcow2_update_options(BlockDriverState *bs, 
QDict *options,
     return ret;
 }
 
+static bool qcow2_is_opened_unclean(BlockDriverState *bs)
+{
+    return ((BDRVQcow2State *)(bs->opaque))->header_unclean;
+}
+
 static int qcow2_open(BlockDriverState *bs, QDict *options, int flags,
                       Error **errp)
 {
@@ -1156,7 +1161,6 @@ static int qcow2_open(BlockDriverState *bs, QDict 
*options, int flags,
     if (!(flags & (BDRV_O_CHECK | BDRV_O_INCOMING)) && !bs->read_only &&
         (s->incompatible_features & QCOW2_INCOMPAT_DIRTY)) {
         BdrvCheckResult result = {0};
-
         ret = qcow2_check(bs, &result, BDRV_FIX_ERRORS | BDRV_FIX_LEAKS);
         if (ret < 0) {
             error_setg_errno(errp, -ret, "Could not repair dirty image");
@@ -1170,6 +1174,9 @@ static int qcow2_open(BlockDriverState *bs, QDict 
*options, int flags,
         qcow2_check_refcounts(bs, &result, 0);
     }
 #endif
+    if (flags & BDRV_O_RDWR) {
+        s->header_unclean = true;
+    }
     return ret;
 
  fail:
@@ -1691,6 +1698,7 @@ static void qcow2_close(BlockDriverState *bs)
     qemu_vfree(s->l1_table);
     /* else pre-write overlap checks in cache_destroy may crash */
     s->l1_table = NULL;
+    s->header_unclean = false;
 
     if (!(bs->open_flags & BDRV_O_INCOMING)) {
         int ret1, ret2;
@@ -3305,6 +3313,7 @@ BlockDriver bdrv_qcow2 = {
     .bdrv_co_get_block_status = qcow2_co_get_block_status,
     .bdrv_set_key       = qcow2_set_key,
 
+    .bdrv_is_opened_unclean  = qcow2_is_opened_unclean,
     .bdrv_co_readv          = qcow2_co_readv,
     .bdrv_co_writev         = qcow2_co_writev,
     .bdrv_co_flush_to_os    = qcow2_co_flush_to_os,
diff --git a/block/qcow2.h b/block/qcow2.h
index a063a3c..c743d66 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -278,6 +278,7 @@ typedef struct BDRVQcow2State {
     int overlap_check; /* bitmask of Qcow2MetadataOverlap values */
     bool signaled_corruption;
 
+    bool header_unclean;
     uint64_t incompatible_features;
     uint64_t compatible_features;
     uint64_t autoclear_features;
-- 
2.1.4


Reply via email to