summaryrefslogtreecommitdiff
path: root/block/commit.c
diff options
context:
space:
mode:
authorKevin Wolf <kwolf@redhat.com>2017-06-09 13:29:36 +0200
committerKevin Wolf <kwolf@redhat.com>2017-06-26 14:51:12 +0200
commit4f78a16fee462471416dc49b409d57b2071cf3d9 (patch)
tree9e9226fbfb4c5c92f20d6c44140f29f50208029e /block/commit.c
parent931892e8a691a8a4151cc5fe1e13c14294bb28fb (diff)
downloadqemu-4f78a16fee462471416dc49b409d57b2071cf3d9.tar.gz
commit: Fix completion with extra reference
commit_complete() can't assume that after its block_job_completed() the job is actually immediately freed; someone else may still be holding references. In this case, the op blockers on the intermediate nodes make the graph reconfiguration in the completion code fail. Call block_job_remove_all_bdrv() manually so that we know for sure that any blockers on intermediate nodes are given up. Cc: qemu-stable@nongnu.org Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com>
Diffstat (limited to 'block/commit.c')
-rw-r--r--block/commit.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/block/commit.c b/block/commit.c
index af6fa68cf3..8c09c3dbcd 100644
--- a/block/commit.c
+++ b/block/commit.c
@@ -119,6 +119,13 @@ static void commit_complete(BlockJob *job, void *opaque)
}
g_free(s->backing_file_str);
blk_unref(s->top);
+
+ /* If there is more than one reference to the job (e.g. if called from
+ * block_job_finish_sync()), block_job_completed() won't free it and
+ * therefore the blockers on the intermediate nodes remain. This would
+ * cause bdrv_set_backing_hd() to fail. */
+ block_job_remove_all_bdrv(job);
+
block_job_completed(&s->common, ret);
g_free(data);