diff options
author | Kevin Wolf <kwolf@redhat.com> | 2017-06-09 13:29:36 +0200 |
---|---|---|
committer | Michael Roth <mdroth@linux.vnet.ibm.com> | 2017-08-24 16:53:45 -0500 |
commit | 1dd3ba38f6ebf5c11194b420c0539c05cfed1f51 (patch) | |
tree | 5ec730079e3cba4f9a5ce30232e65bbbfb1e9322 | |
parent | ecc7a24c11e2ef0ea5965af36bc0aca833435141 (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.c | 7 |
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); |