diff mbox

[4/5] qcow2: implemented bdrv_is_opened_unclean

Message ID 1450856816-9816-5-git-send-email-den@openvz.org
State New
Headers show

Commit Message

Denis V. Lunev Dec. 23, 2015, 7:46 a.m. UTC
From: Olga Krishtal <okrishtal@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 <okrishtal@virtuozzo.com>
Signed-off-by: Denis V. Lunev <den@openvz.org>
CC: Kevin Wolf <kwolf@redhat.com>
CC: Max Reitz <mreitz@redhat.com>
CC: Eric Blake <eblake@redhat.com>
CC: Fam Zheng <famz@redhat.com>
---
 block/qcow2.c | 11 ++++++++++-
 block/qcow2.h |  1 +
 2 files changed, 11 insertions(+), 1 deletion(-)

Comments

Kevin Wolf Jan. 11, 2016, 5:37 p.m. UTC | #1
Am 23.12.2015 um 08:46 hat Denis V. Lunev geschrieben:
> From: Olga Krishtal <okrishtal@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 <okrishtal@virtuozzo.com>
> Signed-off-by: Denis V. Lunev <den@openvz.org>
> CC: Kevin Wolf <kwolf@redhat.com>
> CC: Max Reitz <mreitz@redhat.com>
> CC: Eric Blake <eblake@redhat.com>
> CC: Fam Zheng <famz@redhat.com>

What does this fix?

qcow2 isn't supposed to require a repair after an unclean shutdown. The
only exception is with lazy-refcounts=on, which already sets a dirty
flag in the header and triggers the repair in qcow2_open().

Kevin
diff mbox

Patch

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;