diff options
author | Alberto Garcia <berto@igalia.com> | 2019-03-12 18:48:41 +0200 |
---|---|---|
committer | Kevin Wolf <kwolf@redhat.com> | 2019-03-12 20:30:14 +0100 |
commit | df827336abd072cf71aa6990a12ce13187b22861 (patch) | |
tree | 47a5e01e6cb450ae1b256cd2e4f8855f770dcebe /block/commit.c | |
parent | 2cad1ebe701eccfe3b5a6b1eb277c4f3c5055665 (diff) |
block: Freeze the backing chain for the duration of the commit job
Signed-off-by: Alberto Garcia <berto@igalia.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Diffstat (limited to 'block/commit.c')
-rw-r--r-- | block/commit.c | 16 |
1 files changed, 16 insertions, 0 deletions
diff --git a/block/commit.c b/block/commit.c index 3b46ca7f97..ba60fef58a 100644 --- a/block/commit.c +++ b/block/commit.c @@ -39,6 +39,7 @@ typedef struct CommitBlockJob { BlockDriverState *base_bs; BlockdevOnError on_error; bool base_read_only; + bool chain_frozen; char *backing_file_str; } CommitBlockJob; @@ -68,6 +69,9 @@ static int commit_prepare(Job *job) { CommitBlockJob *s = container_of(job, CommitBlockJob, common.job); + bdrv_unfreeze_backing_chain(s->commit_top_bs, s->base_bs); + s->chain_frozen = false; + /* Remove base node parent that still uses BLK_PERM_WRITE/RESIZE before * the normal backing chain can be restored. */ blk_unref(s->base); @@ -84,6 +88,10 @@ static void commit_abort(Job *job) CommitBlockJob *s = container_of(job, CommitBlockJob, common.job); BlockDriverState *top_bs = blk_bs(s->top); + if (s->chain_frozen) { + bdrv_unfreeze_backing_chain(s->commit_top_bs, s->base_bs); + } + /* Make sure commit_top_bs and top stay around until bdrv_replace_node() */ bdrv_ref(top_bs); bdrv_ref(s->commit_top_bs); @@ -330,6 +338,11 @@ void commit_start(const char *job_id, BlockDriverState *bs, } } + if (bdrv_freeze_backing_chain(commit_top_bs, base, errp) < 0) { + goto fail; + } + s->chain_frozen = true; + ret = block_job_add_bdrv(&s->common, "base", base, 0, BLK_PERM_ALL, errp); if (ret < 0) { goto fail; @@ -362,6 +375,9 @@ void commit_start(const char *job_id, BlockDriverState *bs, return; fail: + if (s->chain_frozen) { + bdrv_unfreeze_backing_chain(commit_top_bs, base); + } if (s->base) { blk_unref(s->base); } |