blockjob: add block_job_release function
authorTing Wang <kathy.wangting@huawei.com>
Fri, 26 Jun 2015 09:37:35 +0000 (17:37 +0800)
committerStefan Hajnoczi <stefanha@redhat.com>
Tue, 7 Jul 2015 13:27:14 +0000 (14:27 +0100)
There is job resource leak in function mirror_start_job,
although bdrv_create_dirty_bitmap is unlikely failed.
Add block_job_release for each release when needed.

Signed-off-by: Ting Wang <kathy.wangting@huawei.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Message-id: 1435311455-56048-1-git-send-email-kathy.wangting@huawei.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
block/mirror.c
blockjob.c
include/block/blockjob.h

index 8888cea9521fd5fcbc300c054fc8936bdac4f47e..d409337c4a9020867f229d10cfe4be97ae2ebabe 100644 (file)
@@ -708,6 +708,8 @@ static void mirror_start_job(BlockDriverState *bs, BlockDriverState *target,
 
     s->dirty_bitmap = bdrv_create_dirty_bitmap(bs, granularity, NULL, errp);
     if (!s->dirty_bitmap) {
+        g_free(s->replaces);
+        block_job_release(bs);
         return;
     }
     bdrv_set_enable_write_cache(s->target, true);
index ec46fad2f11d73cd7f1cdbb0cbab4a26ea232113..62bb9066349345f05b764a1fd004f03dbaa84589 100644 (file)
@@ -66,10 +66,7 @@ void *block_job_create(const BlockJobDriver *driver, BlockDriverState *bs,
 
         block_job_set_speed(job, speed, &local_err);
         if (local_err) {
-            bs->job = NULL;
-            bdrv_op_unblock_all(bs, job->blocker);
-            error_free(job->blocker);
-            g_free(job);
+            block_job_release(bs);
             error_propagate(errp, local_err);
             return NULL;
         }
@@ -77,18 +74,25 @@ void *block_job_create(const BlockJobDriver *driver, BlockDriverState *bs,
     return job;
 }
 
-void block_job_completed(BlockJob *job, int ret)
+void block_job_release(BlockDriverState *bs)
 {
-    BlockDriverState *bs = job->bs;
+    BlockJob *job = bs->job;
 
-    assert(bs->job == job);
-    job->cb(job->opaque, ret);
     bs->job = NULL;
     bdrv_op_unblock_all(bs, job->blocker);
     error_free(job->blocker);
     g_free(job);
 }
 
+void block_job_completed(BlockJob *job, int ret)
+{
+    BlockDriverState *bs = job->bs;
+
+    assert(bs->job == job);
+    job->cb(job->opaque, ret);
+    block_job_release(bs);
+}
+
 void block_job_set_speed(BlockJob *job, int64_t speed, Error **errp)
 {
     Error *local_err = NULL;
index 57d8ef13e21bde3878062074e1dcdfc970301b5c..dd9d5e6aadd990ad7f1ec22a15ab541ad9c74472 100644 (file)
@@ -165,6 +165,14 @@ void block_job_sleep_ns(BlockJob *job, QEMUClockType type, int64_t ns);
  */
 void block_job_yield(BlockJob *job);
 
+/**
+ * block_job_release:
+ * @bs: The block device.
+ *
+ * Release job resources when an error occurred or job completed.
+ */
+void block_job_release(BlockDriverState *bs);
+
 /**
  * block_job_completed:
  * @job: The job being completed.