qcow2: Make image inaccessible after failed qcow2_invalidate_cache()
authorKevin Wolf <kwolf@redhat.com>
Tue, 22 Dec 2015 15:14:10 +0000 (16:14 +0100)
committerKevin Wolf <kwolf@redhat.com>
Wed, 20 Jan 2016 12:36:24 +0000 (13:36 +0100)
If qcow2_invalidate_cache() fails, we are in a state where qcow2_close()
has already been completed, but the image hasn't been reopened yet.
Calling into any qcow2 function for an image in this state will cause
crashes.

The real solution would be to get rid of the close/open pair and instead
do an atomic reset of the involved data structures, but this isn't
trivial, so let's just make the image inaccessible for now.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
block/qcow2.c

index 0f8c485c2cc30ce431eb739908a39e7ea09786b1..fd8436c5f8b13ab0e8c605147ce76e6b6a8e5f95 100644 (file)
@@ -1764,6 +1764,7 @@ static void qcow2_invalidate_cache(BlockDriverState *bs, Error **errp)
     bdrv_invalidate_cache(bs->file->bs, &local_err);
     if (local_err) {
         error_propagate(errp, local_err);
+        bs->drv = NULL;
         return;
     }
 
@@ -1776,9 +1777,11 @@ static void qcow2_invalidate_cache(BlockDriverState *bs, Error **errp)
     if (local_err) {
         error_propagate(errp, local_err);
         error_prepend(errp, "Could not reopen qcow2 layer: ");
+        bs->drv = NULL;
         return;
     } else if (ret < 0) {
         error_setg_errno(errp, -ret, "Could not reopen qcow2 layer");
+        bs->drv = NULL;
         return;
     }