diff options
author | Kevin Wolf <kwolf@redhat.com> | 2013-03-15 10:35:08 +0100 |
---|---|---|
committer | Stefan Hajnoczi <stefanha@redhat.com> | 2013-03-15 16:07:49 +0100 |
commit | 74c4510a3cf7c369ee524c6f8fa8a87cf08ba608 (patch) | |
tree | 47513b79f00b7aba967176fed0cf2738c4a5ee62 | |
parent | 0006383e1549b6f9b264575d124c553efca19d62 (diff) |
qcow2: Allow lazy refcounts to be enabled on the command line
qcow2 images now accept a boolean lazy_refcounts options. Use it like
this:
-drive file=test.qcow2,lazy_refcounts=on
If the option is specified on the command line, it overrides the default
specified by the qcow2 header flags that were set when creating the
image.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
-rw-r--r-- | block/qcow2-cluster.c | 2 | ||||
-rw-r--r-- | block/qcow2.c | 37 | ||||
-rw-r--r-- | block/qcow2.h | 1 |
3 files changed, 39 insertions, 1 deletions
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c index 56fccf9487..ff9ae18e4a 100644 --- a/block/qcow2-cluster.c +++ b/block/qcow2-cluster.c @@ -668,7 +668,7 @@ int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m) } /* Update L2 table. */ - if (s->compatible_features & QCOW2_COMPAT_LAZY_REFCOUNTS) { + if (s->use_lazy_refcounts) { qcow2_mark_dirty(bs); } if (qcow2_need_accurate_refcounts(s)) { diff --git a/block/qcow2.c b/block/qcow2.c index f5e4269363..ad43a13cb0 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -285,11 +285,26 @@ static int qcow2_check(BlockDriverState *bs, BdrvCheckResult *result, return ret; } +static QemuOptsList qcow2_runtime_opts = { + .name = "qcow2", + .head = QTAILQ_HEAD_INITIALIZER(qcow2_runtime_opts.head), + .desc = { + { + .name = "lazy_refcounts", + .type = QEMU_OPT_BOOL, + .help = "Postpone refcount updates", + }, + { /* end of list */ } + }, +}; + static int qcow2_open(BlockDriverState *bs, QDict *options, int flags) { BDRVQcowState *s = bs->opaque; int len, i, ret = 0; QCowHeader header; + QemuOpts *opts; + Error *local_err = NULL; uint64_t ext_end; ret = bdrv_pread(bs->file, 0, &header, sizeof(header)); @@ -495,6 +510,28 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags) } } + /* Enable lazy_refcounts according to image and command line options */ + opts = qemu_opts_create_nofail(&qcow2_runtime_opts); + qemu_opts_absorb_qdict(opts, options, &local_err); + if (error_is_set(&local_err)) { + qerror_report_err(local_err); + error_free(local_err); + ret = -EINVAL; + goto fail; + } + + s->use_lazy_refcounts = qemu_opt_get_bool(opts, "lazy_refcounts", + (s->compatible_features & QCOW2_COMPAT_LAZY_REFCOUNTS)); + + qemu_opts_del(opts); + + if (s->use_lazy_refcounts && s->qcow_version < 3) { + qerror_report(ERROR_CLASS_GENERIC_ERROR, "Lazy refcounts require " + "a qcow2 image with at least qemu 1.1 compatibility level"); + ret = -EINVAL; + goto fail; + } + #ifdef DEBUG_ALLOC { BdrvCheckResult result = {0}; diff --git a/block/qcow2.h b/block/qcow2.h index 718b52baca..103abdb2c0 100644 --- a/block/qcow2.h +++ b/block/qcow2.h @@ -173,6 +173,7 @@ typedef struct BDRVQcowState { int flags; int qcow_version; + bool use_lazy_refcounts; uint64_t incompatible_features; uint64_t compatible_features; |