void *block_job_create(const BlockJobType *job_type, BlockDriverState *bs, int64_t speed, BlockDriverCompletionFunc *cb, void *opaque, Error **errp) { BlockJob *job; if (bs->job || bdrv_in_use(bs)) { error_set(errp, QERR_DEVICE_IN_USE, bdrv_get_device_name(bs)); return NULL; } bdrv_set_in_use(bs, 1); job = g_malloc0(job_type->instance_size); job->job_type = job_type; job->bs = bs; job->cb = cb; job->opaque = opaque; job->busy = true; bs->job = job; /* Only set speed when necessary to avoid NotSupported error */ if (speed != 0) { Error *local_err = NULL; block_job_set_speed(job, speed, &local_err); if (error_is_set(&local_err)) { bs->job = NULL; g_free(job); bdrv_set_in_use(bs, 0); error_propagate(errp, local_err); return NULL; } } return job; }
void block_job_completed(BlockJob *job, int ret) { BlockDriverState *bs = job->bs; assert(bs->job == job); job->cb(job->opaque, ret); bs->job = NULL; g_free(job); bdrv_set_in_use(bs, 0); }