diff options
author | Kevin Wolf <kwolf@redhat.com> | 2017-06-09 13:29:36 +0200 |
---|---|---|
committer | Kevin Wolf <kwolf@redhat.com> | 2017-06-26 14:51:12 +0200 |
commit | 4f78a16fee462471416dc49b409d57b2071cf3d9 (patch) | |
tree | 9e9226fbfb4c5c92f20d6c44140f29f50208029e /block/commit.c | |
parent | 931892e8a691a8a4151cc5fe1e13c14294bb28fb (diff) | |
download | qemu-4f78a16fee462471416dc49b409d57b2071cf3d9.zip qemu-4f78a16fee462471416dc49b409d57b2071cf3d9.tar.gz qemu-4f78a16fee462471416dc49b409d57b2071cf3d9.tar.bz2 |
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.c | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/block/commit.c b/block/commit.c index af6fa68..8c09c3d 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); |