|
|
218e99 |
From 789d0334d894eaea6a5ca35538926bbb63a9cea3 Mon Sep 17 00:00:00 2001
|
|
|
218e99 |
From: Kevin Wolf <kwolf@redhat.com>
|
|
|
218e99 |
Date: Mon, 9 Sep 2013 14:28:01 +0200
|
|
|
218e99 |
Subject: [PATCH 10/38] qcow2: Options to enable discard for freed clusters
|
|
|
218e99 |
|
|
|
218e99 |
RH-Author: Kevin Wolf <kwolf@redhat.com>
|
|
|
218e99 |
Message-id: <1378736903-18489-11-git-send-email-kwolf@redhat.com>
|
|
|
218e99 |
Patchwork-id: 54195
|
|
|
218e99 |
O-Subject: [RHEL-7.0 qemu-kvm PATCH 10/32] qcow2: Options to enable discard for freed clusters
|
|
|
218e99 |
Bugzilla: 1005818
|
|
|
218e99 |
RH-Acked-by: Fam Zheng <famz@redhat.com>
|
|
|
218e99 |
RH-Acked-by: Max Reitz <mreitz@redhat.com>
|
|
|
218e99 |
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
218e99 |
|
|
|
218e99 |
Bugzilla: 1005818
|
|
|
218e99 |
|
|
|
218e99 |
Deleted snapshots are discarded in the image file by default, discard
|
|
|
218e99 |
requests take their default from the -drive discard=... option and other
|
|
|
218e99 |
places that free clusters must always be enabled explicitly.
|
|
|
218e99 |
|
|
|
218e99 |
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
|
|
218e99 |
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
|
|
218e99 |
(cherry picked from commit 67af674e478054086f972811dd0a11289afa39a9)
|
|
|
218e99 |
|
|
|
218e99 |
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
|
|
218e99 |
---
|
|
|
218e99 |
block/qcow2-refcount.c | 5 +++++
|
|
|
218e99 |
block/qcow2.c | 26 ++++++++++++++++++++++++++
|
|
|
218e99 |
block/qcow2.h | 5 +++++
|
|
|
218e99 |
3 files changed, 36 insertions(+)
|
|
|
218e99 |
|
|
|
218e99 |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
218e99 |
---
|
|
|
218e99 |
block/qcow2-refcount.c | 5 +++++
|
|
|
218e99 |
block/qcow2.c | 26 ++++++++++++++++++++++++++
|
|
|
218e99 |
block/qcow2.h | 5 +++++
|
|
|
218e99 |
3 files changed, 36 insertions(+), 0 deletions(-)
|
|
|
218e99 |
|
|
|
218e99 |
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
|
|
|
218e99 |
index 6d35e49..7488988 100644
|
|
|
218e99 |
--- a/block/qcow2-refcount.c
|
|
|
218e99 |
+++ b/block/qcow2-refcount.c
|
|
|
218e99 |
@@ -488,6 +488,11 @@ static int QEMU_WARN_UNUSED_RESULT update_refcount(BlockDriverState *bs,
|
|
|
218e99 |
s->free_cluster_index = cluster_index;
|
|
|
218e99 |
}
|
|
|
218e99 |
refcount_block[block_index] = cpu_to_be16(refcount);
|
|
|
218e99 |
+ if (refcount == 0 && s->discard_passthrough[type]) {
|
|
|
218e99 |
+ /* Try discarding, ignore errors */
|
|
|
218e99 |
+ /* FIXME Doing this cluster by cluster will be painfully slow */
|
|
|
218e99 |
+ bdrv_discard(bs->file, cluster_offset, 1);
|
|
|
218e99 |
+ }
|
|
|
218e99 |
}
|
|
|
218e99 |
|
|
|
218e99 |
ret = 0;
|
|
|
218e99 |
diff --git a/block/qcow2.c b/block/qcow2.c
|
|
|
218e99 |
index e28ea47..ef8a2ca 100644
|
|
|
218e99 |
--- a/block/qcow2.c
|
|
|
218e99 |
+++ b/block/qcow2.c
|
|
|
218e99 |
@@ -295,6 +295,22 @@ static QemuOptsList qcow2_runtime_opts = {
|
|
|
218e99 |
.type = QEMU_OPT_BOOL,
|
|
|
218e99 |
.help = "Postpone refcount updates",
|
|
|
218e99 |
},
|
|
|
218e99 |
+ {
|
|
|
218e99 |
+ .name = QCOW2_OPT_DISCARD_REQUEST,
|
|
|
218e99 |
+ .type = QEMU_OPT_BOOL,
|
|
|
218e99 |
+ .help = "Pass guest discard requests to the layer below",
|
|
|
218e99 |
+ },
|
|
|
218e99 |
+ {
|
|
|
218e99 |
+ .name = QCOW2_OPT_DISCARD_SNAPSHOT,
|
|
|
218e99 |
+ .type = QEMU_OPT_BOOL,
|
|
|
218e99 |
+ .help = "Generate discard requests when snapshot related space "
|
|
|
218e99 |
+ "is freed",
|
|
|
218e99 |
+ },
|
|
|
218e99 |
+ {
|
|
|
218e99 |
+ .name = QCOW2_OPT_DISCARD_OTHER,
|
|
|
218e99 |
+ .type = QEMU_OPT_BOOL,
|
|
|
218e99 |
+ .help = "Generate discard requests when other clusters are freed",
|
|
|
218e99 |
+ },
|
|
|
218e99 |
{ /* end of list */ }
|
|
|
218e99 |
},
|
|
|
218e99 |
};
|
|
|
218e99 |
@@ -532,6 +548,16 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags)
|
|
|
218e99 |
s->use_lazy_refcounts = qemu_opt_get_bool(opts, QCOW2_OPT_LAZY_REFCOUNTS,
|
|
|
218e99 |
(s->compatible_features & QCOW2_COMPAT_LAZY_REFCOUNTS));
|
|
|
218e99 |
|
|
|
218e99 |
+ s->discard_passthrough[QCOW2_DISCARD_NEVER] = false;
|
|
|
218e99 |
+ s->discard_passthrough[QCOW2_DISCARD_ALWAYS] = true;
|
|
|
218e99 |
+ s->discard_passthrough[QCOW2_DISCARD_REQUEST] =
|
|
|
218e99 |
+ qemu_opt_get_bool(opts, QCOW2_OPT_DISCARD_REQUEST,
|
|
|
218e99 |
+ flags & BDRV_O_UNMAP);
|
|
|
218e99 |
+ s->discard_passthrough[QCOW2_DISCARD_SNAPSHOT] =
|
|
|
218e99 |
+ qemu_opt_get_bool(opts, QCOW2_OPT_DISCARD_SNAPSHOT, true);
|
|
|
218e99 |
+ s->discard_passthrough[QCOW2_DISCARD_OTHER] =
|
|
|
218e99 |
+ qemu_opt_get_bool(opts, QCOW2_OPT_DISCARD_OTHER, false);
|
|
|
218e99 |
+
|
|
|
218e99 |
qemu_opts_del(opts);
|
|
|
218e99 |
|
|
|
218e99 |
if (s->use_lazy_refcounts && s->qcow_version < 3) {
|
|
|
218e99 |
diff --git a/block/qcow2.h b/block/qcow2.h
|
|
|
218e99 |
index 64a6479..6f91b9a 100644
|
|
|
218e99 |
--- a/block/qcow2.h
|
|
|
218e99 |
+++ b/block/qcow2.h
|
|
|
218e99 |
@@ -60,6 +60,9 @@
|
|
|
218e99 |
|
|
|
218e99 |
|
|
|
218e99 |
#define QCOW2_OPT_LAZY_REFCOUNTS "lazy_refcounts"
|
|
|
218e99 |
+#define QCOW2_OPT_DISCARD_REQUEST "pass_discard_request"
|
|
|
218e99 |
+#define QCOW2_OPT_DISCARD_SNAPSHOT "pass_discard_snapshot"
|
|
|
218e99 |
+#define QCOW2_OPT_DISCARD_OTHER "pass_discard_other"
|
|
|
218e99 |
|
|
|
218e99 |
typedef struct QCowHeader {
|
|
|
218e99 |
uint32_t magic;
|
|
|
218e99 |
@@ -187,6 +190,8 @@ typedef struct BDRVQcowState {
|
|
|
218e99 |
int qcow_version;
|
|
|
218e99 |
bool use_lazy_refcounts;
|
|
|
218e99 |
|
|
|
218e99 |
+ bool discard_passthrough[QCOW2_DISCARD_MAX];
|
|
|
218e99 |
+
|
|
|
218e99 |
uint64_t incompatible_features;
|
|
|
218e99 |
uint64_t compatible_features;
|
|
|
218e99 |
uint64_t autoclear_features;
|
|
|
218e99 |
--
|
|
|
218e99 |
1.7.1
|
|
|
218e99 |
|