aboutsummaryrefslogtreecommitdiff
path: root/blockjob.c
diff options
context:
space:
mode:
authorFam Zheng <famz@redhat.com>2015-11-05 18:13:11 -0500
committerKevin Wolf <kwolf@redhat.com>2015-11-12 16:22:43 +0100
commit18930ba3d17866fff6df52ae6d2e54ce5c5ca04b (patch)
treed2105745115882ec2d58cbb2c8c58c3011393cb6 /blockjob.c
parentb976ea3cf591ac994cc17dcf0fc550c9aa9c0f5d (diff)
blockjob: Introduce reference count and fix reference to job->bs
Add reference count to block job, meanwhile move the ownership of the reference to job->bs from the caller (which is released in two completion callbacks) to the block job itself. It is necessary for block_job_complete_sync to work, because block job shouldn't live longer than its bs, as asserted in bdrv_delete. Now block_job_complete_sync can be simplified. Signed-off-by: Fam Zheng <famz@redhat.com> Signed-off-by: John Snow <jsnow@redhat.com> Message-id: 1446765200-3054-6-git-send-email-jsnow@redhat.com Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Diffstat (limited to 'blockjob.c')
-rw-r--r--blockjob.c25
1 files changed, 16 insertions, 9 deletions
diff --git a/blockjob.c b/blockjob.c
index c02fe598b8..ae9c5b2925 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -60,6 +60,7 @@ void *block_job_create(const BlockJobDriver *driver, BlockDriverState *bs,
job->cb = cb;
job->opaque = opaque;
job->busy = true;
+ job->refcnt = 1;
bs->job = job;
/* Only set speed when necessary to avoid NotSupported error */
@@ -68,7 +69,7 @@ void *block_job_create(const BlockJobDriver *driver, BlockDriverState *bs,
block_job_set_speed(job, speed, &local_err);
if (local_err) {
- block_job_release(bs);
+ block_job_unref(job);
error_propagate(errp, local_err);
return NULL;
}
@@ -76,15 +77,21 @@ void *block_job_create(const BlockJobDriver *driver, BlockDriverState *bs,
return job;
}
-void block_job_release(BlockDriverState *bs)
+void block_job_ref(BlockJob *job)
{
- BlockJob *job = bs->job;
+ ++job->refcnt;
+}
- bs->job = NULL;
- bdrv_op_unblock_all(bs, job->blocker);
- error_free(job->blocker);
- g_free(job->id);
- g_free(job);
+void block_job_unref(BlockJob *job)
+{
+ if (--job->refcnt == 0) {
+ job->bs->job = NULL;
+ bdrv_op_unblock_all(job->bs, job->blocker);
+ bdrv_unref(job->bs);
+ error_free(job->blocker);
+ g_free(job->id);
+ g_free(job);
+ }
}
void block_job_completed(BlockJob *job, int ret)
@@ -93,7 +100,7 @@ void block_job_completed(BlockJob *job, int ret)
assert(bs->job == job);
job->cb(job->opaque, ret);
- block_job_release(bs);
+ block_job_unref(job);
}
void block_job_set_speed(BlockJob *job, int64_t speed, Error **errp)