aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKevin Wolf <kwolf@redhat.com>2017-06-09 13:29:36 +0200
committerMichael Roth <mdroth@linux.vnet.ibm.com>2017-08-24 16:53:45 -0500
commit1dd3ba38f6ebf5c11194b420c0539c05cfed1f51 (patch)
tree5ec730079e3cba4f9a5ce30232e65bbbfb1e9322
parentecc7a24c11e2ef0ea5965af36bc0aca833435141 (diff)
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> (cherry picked from commit 4f78a16fee462471416dc49b409d57b2071cf3d9) Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
-rw-r--r--block/commit.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/block/commit.c b/block/commit.c
index 3bae46e9dd..fba25e27a8 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);