Commit ec6d8912 authored by Kevin Wolf's avatar Kevin Wolf
Browse files

qcow2: Implement .bdrv_inactivate



The callback has to ensure that closing or flushing the image afterwards
wouldn't cause a write access to the image files. This means that just
the caches have to be written out, which is part of the existing
.bdrv_close implementation.

Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
Reviewed-by: default avatarEric Blake <eblake@redhat.com>
parent 76b1c7fe
Loading
Loading
Loading
Loading
+28 −17
Original line number Diff line number Diff line
@@ -1686,31 +1686,41 @@ fail:
    return ret;
}

static void qcow2_close(BlockDriverState *bs)
static int qcow2_inactivate(BlockDriverState *bs)
{
    BDRVQcow2State *s = bs->opaque;
    qemu_vfree(s->l1_table);
    /* else pre-write overlap checks in cache_destroy may crash */
    s->l1_table = NULL;

    if (!(bs->open_flags & BDRV_O_INACTIVE)) {
        int ret1, ret2;
    int ret, result = 0;

        ret1 = qcow2_cache_flush(bs, s->l2_table_cache);
        ret2 = qcow2_cache_flush(bs, s->refcount_block_cache);

        if (ret1) {
    ret = qcow2_cache_flush(bs, s->l2_table_cache);
    if (ret) {
        result = ret;
        error_report("Failed to flush the L2 table cache: %s",
                         strerror(-ret1));
                     strerror(-ret));
    }
        if (ret2) {

    ret = qcow2_cache_flush(bs, s->refcount_block_cache);
    if (ret) {
        result = ret;
        error_report("Failed to flush the refcount block cache: %s",
                         strerror(-ret2));
                     strerror(-ret));
    }

        if (!ret1 && !ret2) {
    if (result == 0) {
        qcow2_mark_clean(bs);
    }

    return result;
}

static void qcow2_close(BlockDriverState *bs)
{
    BDRVQcow2State *s = bs->opaque;
    qemu_vfree(s->l1_table);
    /* else pre-write overlap checks in cache_destroy may crash */
    s->l1_table = NULL;

    if (!(bs->open_flags & BDRV_O_INACTIVE)) {
        qcow2_inactivate(bs);
    }

    cache_clean_timer_del(bs);
@@ -3340,6 +3350,7 @@ BlockDriver bdrv_qcow2 = {

    .bdrv_refresh_limits        = qcow2_refresh_limits,
    .bdrv_invalidate_cache      = qcow2_invalidate_cache,
    .bdrv_inactivate            = qcow2_inactivate,

    .create_opts         = &qcow2_create_opts,
    .bdrv_check          = qcow2_check,