aboutsummaryrefslogtreecommitdiff
path: root/blockjob.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2016-07-14 11:48:46 +0100
committerPeter Maydell <peter.maydell@linaro.org>2016-07-14 11:48:46 +0100
commit9358450e98ed4a5350df4754863d116ff2e6186c (patch)
treec151c42717ff86db6b01c9b596eda9d9c9703ac2 /blockjob.c
parent5bb2399f9b08198b6c03db10dd46e5a88caa2968 (diff)
parent543d7a42baf39c09db754ba9eca1d386e5958110 (diff)
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging
Block layer patches # gpg: Signature made Wed 13 Jul 2016 12:46:17 BST # gpg: using RSA key 0x7F09B272C88F2FD6 # gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>" # Primary key fingerprint: DC3D EB15 9A9A F95D 3D74 56FE 7F09 B272 C88F 2FD6 * remotes/kevin/tags/for-upstream: (34 commits) iotests: Make 157 actually format-agnostic vvfat: Fix qcow write target driver specification hmp: show all of snapshot info on every block dev in output of 'info snapshots' hmp: use snapshot name to determine whether a snapshot is 'fully available' qemu-iotests: Test naming of throttling groups blockdev: Fix regression with the default naming of throttling groups vmdk: fix metadata write regression Improve block job rate limiting for small bandwidth values qcow2: Fix qcow2_get_cluster_offset() qemu-io: Use correct range limitations qcow2: Avoid making the L1 table too big qemu-img: Use strerror() for generic resize error block: Remove BB options from blockdev-add qemu-iotests: Test setting WCE with qdev block/qdev: Allow configuring rerror/werror with qdev properties commit: Fix use of error handling policy block/qdev: Allow configuring WCE with qdev properties block/qdev: Allow node name for drive properties coroutine: move entry argument to qemu_coroutine_create test-coroutine: prepare for the next patch ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'blockjob.c')
-rw-r--r--blockjob.c42
1 files changed, 36 insertions, 6 deletions
diff --git a/blockjob.c b/blockjob.c
index 205da9df4e..a5ba3bee52 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -33,6 +33,7 @@
#include "qapi/qmp/qerror.h"
#include "qapi/qmp/qjson.h"
#include "qemu/coroutine.h"
+#include "qemu/id.h"
#include "qmp-commands.h"
#include "qemu/timer.h"
#include "qapi-event.h"
@@ -60,6 +61,19 @@ BlockJob *block_job_next(BlockJob *job)
return QLIST_NEXT(job, job_list);
}
+BlockJob *block_job_get(const char *id)
+{
+ BlockJob *job;
+
+ QLIST_FOREACH(job, &block_jobs, job_list) {
+ if (!strcmp(id, job->id)) {
+ return job;
+ }
+ }
+
+ return NULL;
+}
+
/* Normally the job runs in its BlockBackend's AioContext. The exception is
* block_job_defer_to_main_loop() where it runs in the QEMU main loop. Code
* that supports both cases uses this helper function.
@@ -103,9 +117,9 @@ static void block_job_detach_aio_context(void *opaque)
block_job_unref(job);
}
-void *block_job_create(const BlockJobDriver *driver, BlockDriverState *bs,
- int64_t speed, BlockCompletionFunc *cb,
- void *opaque, Error **errp)
+void *block_job_create(const char *job_id, const BlockJobDriver *driver,
+ BlockDriverState *bs, int64_t speed,
+ BlockCompletionFunc *cb, void *opaque, Error **errp)
{
BlockBackend *blk;
BlockJob *job;
@@ -116,6 +130,20 @@ void *block_job_create(const BlockJobDriver *driver, BlockDriverState *bs,
return NULL;
}
+ if (job_id == NULL) {
+ job_id = bdrv_get_device_name(bs);
+ }
+
+ if (!id_wellformed(job_id)) {
+ error_setg(errp, "Invalid job ID '%s'", job_id);
+ return NULL;
+ }
+
+ if (block_job_get(job_id)) {
+ error_setg(errp, "Job ID '%s' already in use", job_id);
+ return NULL;
+ }
+
blk = blk_new();
blk_insert_bs(blk, bs);
@@ -126,7 +154,7 @@ void *block_job_create(const BlockJobDriver *driver, BlockDriverState *bs,
bdrv_op_unblock(bs, BLOCK_OP_TYPE_DATAPLANE, job->blocker);
job->driver = driver;
- job->id = g_strdup(bdrv_get_device_name(bs));
+ job->id = g_strdup(job_id);
job->blk = blk;
job->cb = cb;
job->opaque = opaque;
@@ -290,7 +318,8 @@ void block_job_set_speed(BlockJob *job, int64_t speed, Error **errp)
void block_job_complete(BlockJob *job, Error **errp)
{
if (job->pause_count || job->cancelled || !job->driver->complete) {
- error_setg(errp, QERR_BLOCK_JOB_NOT_READY, job->id);
+ error_setg(errp, "The active block job '%s' cannot be completed",
+ job->id);
return;
}
@@ -346,7 +375,7 @@ void block_job_resume(BlockJob *job)
void block_job_enter(BlockJob *job)
{
if (job->co && !job->busy) {
- qemu_coroutine_enter(job->co, NULL);
+ qemu_coroutine_enter(job->co);
}
}
@@ -524,6 +553,7 @@ BlockErrorAction block_job_error_action(BlockJob *job, BlockdevOnError on_err,
switch (on_err) {
case BLOCKDEV_ON_ERROR_ENOSPC:
+ case BLOCKDEV_ON_ERROR_AUTO:
action = (error == ENOSPC) ?
BLOCK_ERROR_ACTION_STOP : BLOCK_ERROR_ACTION_REPORT;
break;