提交 ec6d8912 编写于 作者: K Kevin Wolf

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: NKevin Wolf <kwolf@redhat.com>
Reviewed-by: NEric Blake <eblake@redhat.com>
上级 76b1c7fe
......@@ -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,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册