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);
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;
}
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;
*/
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.