* THE SOFTWARE.
*/
-#include "config-host.h"
+#include "qemu/osdep.h"
#include "qemu-common.h"
#include "trace.h"
#include "block/block.h"
int refcnt;
};
+static QLIST_HEAD(, BlockJob) block_jobs = QLIST_HEAD_INITIALIZER(block_jobs);
+
+BlockJob *block_job_next(BlockJob *job)
+{
+ if (!job) {
+ return QLIST_FIRST(&block_jobs);
+ }
+ return QLIST_NEXT(job, job_list);
+}
+
void *block_job_create(const BlockJobDriver *driver, BlockDriverState *bs,
int64_t speed, BlockCompletionFunc *cb,
void *opaque, Error **errp)
job->refcnt = 1;
bs->job = job;
+ QLIST_INSERT_HEAD(&block_jobs, job, job_list);
+
/* Only set speed when necessary to avoid NotSupported error */
if (speed != 0) {
Error *local_err = NULL;
bdrv_unref(job->bs);
error_free(job->blocker);
g_free(job->id);
+ QLIST_REMOVE(job, job_list);
g_free(job);
}
}
}
}
-struct BlockFinishData {
- BlockJob *job;
- BlockCompletionFunc *cb;
- void *opaque;
- bool cancelled;
- int ret;
-};
-
static int block_job_finish_sync(BlockJob *job,
void (*finish)(BlockJob *, Error **errp),
Error **errp)
return -EBUSY;
}
while (!job->completed) {
- aio_poll(bdrv_get_aio_context(bs), true);
+ aio_poll(job->deferred_to_main_loop ? qemu_get_aio_context() :
+ bdrv_get_aio_context(bs),
+ true);
}
ret = (job->cancelled && job->ret == 0) ? -ECANCELED : job->ret;
block_job_unref(job);
job->speed, &error_abort);
}
-BlockErrorAction block_job_error_action(BlockJob *job, BlockDriverState *bs,
- BlockdevOnError on_err,
+BlockErrorAction block_job_error_action(BlockJob *job, BlockdevOnError on_err,
int is_read, int error)
{
BlockErrorAction action;
job->user_paused = true;
block_job_pause(job);
block_job_iostatus_set_err(job, error);
- if (bs->blk && bs != job->bs) {
- blk_iostatus_set_err(bs->blk, error);
- }
}
return action;
}
aio_context = bdrv_get_aio_context(data->job->bs);
aio_context_acquire(aio_context);
+ data->job->deferred_to_main_loop = false;
data->fn(data->job, data->opaque);
aio_context_release(aio_context);
data->aio_context = bdrv_get_aio_context(job->bs);
data->fn = fn;
data->opaque = opaque;
+ job->deferred_to_main_loop = true;
qemu_bh_schedule(data->bh);
}