26ba25
From 175dbc6a2217f7a8cf319d8da487fa80ff68eba4 Mon Sep 17 00:00:00 2001
26ba25
From: Kevin Wolf <kwolf@redhat.com>
26ba25
Date: Mon, 2 Jul 2018 15:40:07 +0200
26ba25
Subject: [PATCH 183/268] qcow2: Free allocated clusters on write error
26ba25
26ba25
RH-Author: Kevin Wolf <kwolf@redhat.com>
26ba25
Message-id: <20180702154008.15533-3-kwolf@redhat.com>
26ba25
Patchwork-id: 81185
26ba25
O-Subject: [RHV-7.6 qemu-kvm-rhev PATCH 2/3] qcow2: Free allocated clusters on write error
26ba25
Bugzilla: 1528541
26ba25
RH-Acked-by: Max Reitz <mreitz@redhat.com>
26ba25
RH-Acked-by: Fam Zheng <famz@redhat.com>
26ba25
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
26ba25
26ba25
If we managed to allocate the clusters, but then failed to write the
26ba25
data, there's a good chance that we'll still be able to free the
26ba25
clusters again in order to avoid cluster leaks (the refcounts are
26ba25
cached, so even if we can't write them out right now, we may be able to
26ba25
do so when the VM is resumed after a werror=stop/enospc pause).
26ba25
26ba25
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
26ba25
Reviewed-by: Max Reitz <mreitz@redhat.com>
26ba25
Reviewed-by: Eric Blake <eblake@redhat.com>
26ba25
Tested-by: Eric Blake <eblake@redhat.com>
26ba25
(cherry picked from commit 8b24cd141549b5b264baeddd4e72902cfb5de23b)
26ba25
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
26ba25
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
26ba25
---
26ba25
 block/qcow2-cluster.c | 11 +++++++++++
26ba25
 block/qcow2.c         |  2 ++
26ba25
 block/qcow2.h         |  1 +
26ba25
 3 files changed, 14 insertions(+)
26ba25
26ba25
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
26ba25
index 1aee726..c90e2ec 100644
26ba25
--- a/block/qcow2-cluster.c
26ba25
+++ b/block/qcow2-cluster.c
26ba25
@@ -994,6 +994,17 @@ err:
26ba25
     return ret;
26ba25
  }
26ba25
 
26ba25
+/**
26ba25
+ * Frees the allocated clusters because the request failed and they won't
26ba25
+ * actually be linked.
26ba25
+ */
26ba25
+void qcow2_alloc_cluster_abort(BlockDriverState *bs, QCowL2Meta *m)
26ba25
+{
26ba25
+    BDRVQcow2State *s = bs->opaque;
26ba25
+    qcow2_free_clusters(bs, m->alloc_offset, m->nb_clusters << s->cluster_bits,
26ba25
+                        QCOW2_DISCARD_NEVER);
26ba25
+}
26ba25
+
26ba25
 /*
26ba25
  * Returns the number of contiguous clusters that can be used for an allocating
26ba25
  * write, but require COW to be performed (this includes yet unallocated space,
26ba25
diff --git a/block/qcow2.c b/block/qcow2.c
26ba25
index 4404dc7..da74e2a 100644
26ba25
--- a/block/qcow2.c
26ba25
+++ b/block/qcow2.c
26ba25
@@ -1771,6 +1771,8 @@ static coroutine_fn int qcow2_handle_l2meta(BlockDriverState *bs,
26ba25
             if (ret) {
26ba25
                 goto out;
26ba25
             }
26ba25
+        } else {
26ba25
+            qcow2_alloc_cluster_abort(bs, l2meta);
26ba25
         }
26ba25
 
26ba25
         /* Take the request off the list of running requests */
26ba25
diff --git a/block/qcow2.h b/block/qcow2.h
26ba25
index adf5c39..b5e2aa3 100644
26ba25
--- a/block/qcow2.h
26ba25
+++ b/block/qcow2.h
26ba25
@@ -618,6 +618,7 @@ uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
26ba25
                                          int compressed_size);
26ba25
 
26ba25
 int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m);
26ba25
+void qcow2_alloc_cluster_abort(BlockDriverState *bs, QCowL2Meta *m);
26ba25
 int qcow2_cluster_discard(BlockDriverState *bs, uint64_t offset,
26ba25
                           uint64_t bytes, enum qcow2_discard_type type,
26ba25
                           bool full_discard);
26ba25
-- 
26ba25
1.8.3.1
26ba25