Commit 74c4510a authored by Kevin Wolf's avatar Kevin Wolf Committed by Stefan Hajnoczi
Browse files

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: default avatarKevin Wolf <kwolf@redhat.com>
Reviewed-by: default avatarEric Blake <eblake@redhat.com>
Reviewed-by: default avatarStefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: default avatarStefan Hajnoczi <stefanha@redhat.com>
parent 0006383e
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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)) {
+37 −0
Original line number Diff line number Diff line
@@ -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};
+1 −0
Original line number Diff line number Diff line
@@ -173,6 +173,7 @@ typedef struct BDRVQcowState {

    int flags;
    int qcow_version;
    bool use_lazy_refcounts;

    uint64_t incompatible_features;
    uint64_t compatible_features;