+ job->busy = true;
+}
+
+BlockJobInfo *block_job_query(BlockJob *job)
+{
+ BlockJobInfo *info = g_new0(BlockJobInfo, 1);
+ info->type = g_strdup(job->job_type->job_type);
+ info->device = g_strdup(bdrv_get_device_name(job->bs));
+ info->len = job->len;
+ info->busy = job->busy;
+ info->paused = job->paused;
+ info->offset = job->offset;
+ info->speed = job->speed;
+ info->io_status = job->iostatus;
+ return info;
+}
+
+static void block_job_iostatus_set_err(BlockJob *job, int error)
+{
+ if (job->iostatus == BLOCK_DEVICE_IO_STATUS_OK) {
+ job->iostatus = error == ENOSPC ? BLOCK_DEVICE_IO_STATUS_NOSPACE :
+ BLOCK_DEVICE_IO_STATUS_FAILED;
+ }
+}
+
+
+QObject *qobject_from_block_job(BlockJob *job)
+{
+ return qobject_from_jsonf("{ 'type': %s,"
+ "'device': %s,"
+ "'len': %" PRId64 ","
+ "'offset': %" PRId64 ","
+ "'speed': %" PRId64 " }",
+ job->job_type->job_type,
+ bdrv_get_device_name(job->bs),
+ job->len,
+ job->offset,
+ job->speed);
+}
+
+void block_job_ready(BlockJob *job)
+{
+ QObject *data = qobject_from_block_job(job);
+ monitor_protocol_event(QEVENT_BLOCK_JOB_READY, data);
+ qobject_decref(data);
+}
+
+BlockErrorAction block_job_error_action(BlockJob *job, BlockDriverState *bs,
+ BlockdevOnError on_err,
+ int is_read, int error)
+{
+ BlockErrorAction action;
+
+ switch (on_err) {
+ case BLOCKDEV_ON_ERROR_ENOSPC:
+ action = (error == ENOSPC) ? BDRV_ACTION_STOP : BDRV_ACTION_REPORT;
+ break;
+ case BLOCKDEV_ON_ERROR_STOP:
+ action = BDRV_ACTION_STOP;
+ break;
+ case BLOCKDEV_ON_ERROR_REPORT:
+ action = BDRV_ACTION_REPORT;
+ break;
+ case BLOCKDEV_ON_ERROR_IGNORE:
+ action = BDRV_ACTION_IGNORE;
+ break;
+ default:
+ abort();
+ }
+ bdrv_emit_qmp_error_event(job->bs, QEVENT_BLOCK_JOB_ERROR, action, is_read);
+ if (action == BDRV_ACTION_STOP) {
+ block_job_pause(job);
+ block_job_iostatus_set_err(job, error);
+ if (bs != job->bs) {
+ bdrv_iostatus_set_err(bs, error);
+ }
+ }
+ return action;