]> git.proxmox.com Git - mirror_qemu.git/blame - blockjob.c
job: Add Job.aio_context
[mirror_qemu.git] / blockjob.c
CommitLineData
2f0c9fe6
PB
1/*
2 * QEMU System Emulator block driver
3 *
4 * Copyright (c) 2011 IBM Corp.
5 * Copyright (c) 2012 Red Hat, Inc.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 * THE SOFTWARE.
24 */
25
d38ea87a 26#include "qemu/osdep.h"
2f0c9fe6 27#include "qemu-common.h"
737e150e 28#include "block/block.h"
c87621ea 29#include "block/blockjob_int.h"
737e150e 30#include "block/block_int.h"
c9de4050 31#include "block/trace.h"
373340b2 32#include "sysemu/block-backend.h"
e688df6b 33#include "qapi/error.h"
9af23989 34#include "qapi/qapi-events-block-core.h"
cc7a8ea7 35#include "qapi/qmp/qerror.h"
10817bf0 36#include "qemu/coroutine.h"
1de7afc9 37#include "qemu/timer.h"
2f0c9fe6 38
fc24908e
PB
39/* Right now, this mutex is only needed to synchronize accesses to job->busy
40 * and job->sleep_timer, such as concurrent calls to block_job_do_yield and
41 * block_job_enter. */
42static QemuMutex block_job_mutex;
43
44static void block_job_lock(void)
45{
46 qemu_mutex_lock(&block_job_mutex);
47}
48
49static void block_job_unlock(void)
50{
51 qemu_mutex_unlock(&block_job_mutex);
52}
53
54static void __attribute__((__constructor__)) block_job_init(void)
55{
56 qemu_mutex_init(&block_job_mutex);
57}
58
8254b6d9
JS
59static void block_job_event_cancelled(BlockJob *job);
60static void block_job_event_completed(BlockJob *job, const char *msg);
5f241594 61static int block_job_event_pending(BlockJob *job);
aa9ef2e6 62static void block_job_enter_cond(BlockJob *job, bool(*fn)(BlockJob *job));
8254b6d9 63
c55a832f
FZ
64/* Transactional group of block jobs */
65struct BlockJobTxn {
66
67 /* Is this txn being cancelled? */
68 bool aborting;
69
70 /* List of jobs */
71 QLIST_HEAD(, BlockJob) jobs;
72
73 /* Reference count */
74 int refcnt;
75};
76
88691b37
PB
77/*
78 * The block job API is composed of two categories of functions.
79 *
80 * The first includes functions used by the monitor. The monitor is
81 * peculiar in that it accesses the block job list with block_job_get, and
82 * therefore needs consistency across block_job_get and the actual operation
83 * (e.g. block_job_set_speed). The consistency is achieved with
84 * aio_context_acquire/release. These functions are declared in blockjob.h.
85 *
86 * The second includes functions used by the block job drivers and sometimes
87 * by the core block layer. These do not care about locking, because the
88 * whole coroutine runs under the AioContext lock, and are declared in
89 * blockjob_int.h.
90 */
91
e7c1d78b 92static bool is_block_job(Job *job)
a7112795 93{
e7c1d78b
KW
94 return job_type(job) == JOB_TYPE_BACKUP ||
95 job_type(job) == JOB_TYPE_COMMIT ||
96 job_type(job) == JOB_TYPE_MIRROR ||
97 job_type(job) == JOB_TYPE_STREAM;
98}
99
100BlockJob *block_job_next(BlockJob *bjob)
101{
102 Job *job = bjob ? &bjob->job : NULL;
103
104 do {
105 job = job_next(job);
106 } while (job && !is_block_job(job));
107
108 return job ? container_of(job, BlockJob, job) : NULL;
a7112795
AG
109}
110
ffb1f10c
AG
111BlockJob *block_job_get(const char *id)
112{
e7c1d78b 113 Job *job = job_get(id);
ffb1f10c 114
e7c1d78b
KW
115 if (job && is_block_job(job)) {
116 return container_of(job, BlockJob, job);
117 } else {
118 return NULL;
ffb1f10c 119 }
ffb1f10c
AG
120}
121
c8ab5c2d
PB
122BlockJobTxn *block_job_txn_new(void)
123{
124 BlockJobTxn *txn = g_new0(BlockJobTxn, 1);
125 QLIST_INIT(&txn->jobs);
126 txn->refcnt = 1;
127 return txn;
128}
129
130static void block_job_txn_ref(BlockJobTxn *txn)
131{
132 txn->refcnt++;
133}
134
135void block_job_txn_unref(BlockJobTxn *txn)
136{
137 if (txn && --txn->refcnt == 0) {
138 g_free(txn);
139 }
140}
141
142void block_job_txn_add_job(BlockJobTxn *txn, BlockJob *job)
143{
144 if (!txn) {
145 return;
146 }
147
148 assert(!job->txn);
149 job->txn = txn;
150
151 QLIST_INSERT_HEAD(&txn->jobs, job, txn_list);
152 block_job_txn_ref(txn);
153}
154
a865cebb
MAL
155static void block_job_txn_del_job(BlockJob *job)
156{
157 if (job->txn) {
158 QLIST_REMOVE(job, txn_list);
159 block_job_txn_unref(job->txn);
160 job->txn = NULL;
161 }
162}
163
4c7e813c
SH
164/* Assumes the block_job_mutex is held */
165static bool block_job_timer_pending(BlockJob *job)
166{
167 return timer_pending(&job->sleep_timer);
168}
169
170/* Assumes the block_job_mutex is held */
171static bool block_job_timer_not_pending(BlockJob *job)
172{
173 return !block_job_timer_pending(job);
174}
175
f321dcb5
PB
176static void block_job_pause(BlockJob *job)
177{
178 job->pause_count++;
179}
180
181static void block_job_resume(BlockJob *job)
182{
183 assert(job->pause_count > 0);
184 job->pause_count--;
185 if (job->pause_count) {
186 return;
187 }
4c7e813c
SH
188
189 /* kick only if no timer is pending */
190 block_job_enter_cond(job, block_job_timer_not_pending);
f321dcb5
PB
191}
192
05b0d8e3
PB
193static void block_job_attached_aio_context(AioContext *new_context,
194 void *opaque);
195static void block_job_detach_aio_context(void *opaque);
196
80fa2c75 197void block_job_free(Job *job)
05b0d8e3 198{
80fa2c75
KW
199 BlockJob *bjob = container_of(job, BlockJob, job);
200 BlockDriverState *bs = blk_bs(bjob->blk);
201
202 assert(!bjob->txn);
203
204 bs->job = NULL;
205 block_job_remove_all_bdrv(bjob);
206 blk_remove_aio_context_notifier(bjob->blk,
207 block_job_attached_aio_context,
208 block_job_detach_aio_context, bjob);
209 blk_unref(bjob->blk);
210 error_free(bjob->blocker);
211 assert(!timer_pending(&bjob->sleep_timer));
05b0d8e3
PB
212}
213
463e0be1
SH
214static void block_job_attached_aio_context(AioContext *new_context,
215 void *opaque)
216{
217 BlockJob *job = opaque;
218
08be6fe2 219 job->job.aio_context = new_context;
463e0be1
SH
220 if (job->driver->attached_aio_context) {
221 job->driver->attached_aio_context(job, new_context);
222 }
223
224 block_job_resume(job);
225}
226
bae8196d
PB
227static void block_job_drain(BlockJob *job)
228{
229 /* If job is !job->busy this kicks it into the next pause point. */
230 block_job_enter(job);
231
232 blk_drain(job->blk);
233 if (job->driver->drain) {
234 job->driver->drain(job);
235 }
236}
237
463e0be1
SH
238static void block_job_detach_aio_context(void *opaque)
239{
240 BlockJob *job = opaque;
241
242 /* In case the job terminates during aio_poll()... */
80fa2c75 243 job_ref(&job->job);
463e0be1
SH
244
245 block_job_pause(job);
246
463e0be1 247 while (!job->paused && !job->completed) {
bae8196d 248 block_job_drain(job);
463e0be1
SH
249 }
250
08be6fe2 251 job->job.aio_context = NULL;
80fa2c75 252 job_unref(&job->job);
463e0be1
SH
253}
254
f321dcb5
PB
255static char *child_job_get_parent_desc(BdrvChild *c)
256{
257 BlockJob *job = c->opaque;
252291ea 258 return g_strdup_printf("%s job '%s'", job_type_str(&job->job), job->job.id);
f321dcb5
PB
259}
260
ad90feba 261static void child_job_drained_begin(BdrvChild *c)
f321dcb5 262{
ad90feba 263 BlockJob *job = c->opaque;
f321dcb5
PB
264 block_job_pause(job);
265}
266
ad90feba 267static void child_job_drained_end(BdrvChild *c)
f321dcb5 268{
ad90feba 269 BlockJob *job = c->opaque;
f321dcb5
PB
270 block_job_resume(job);
271}
272
ad90feba
KW
273static const BdrvChildRole child_job = {
274 .get_parent_desc = child_job_get_parent_desc,
275 .drained_begin = child_job_drained_begin,
276 .drained_end = child_job_drained_end,
277 .stay_at_node = true,
f321dcb5
PB
278};
279
bbc02b90
KW
280void block_job_remove_all_bdrv(BlockJob *job)
281{
282 GSList *l;
283 for (l = job->nodes; l; l = l->next) {
284 BdrvChild *c = l->data;
285 bdrv_op_unblock_all(c->bs, job->blocker);
286 bdrv_root_unref_child(c);
287 }
288 g_slist_free(job->nodes);
289 job->nodes = NULL;
290}
291
76d554e2
KW
292int block_job_add_bdrv(BlockJob *job, const char *name, BlockDriverState *bs,
293 uint64_t perm, uint64_t shared_perm, Error **errp)
23d402d4 294{
76d554e2
KW
295 BdrvChild *c;
296
297 c = bdrv_root_attach_child(bs, name, &child_job, perm, shared_perm,
298 job, errp);
299 if (c == NULL) {
300 return -EPERM;
301 }
302
303 job->nodes = g_slist_prepend(job->nodes, c);
23d402d4
AG
304 bdrv_ref(bs);
305 bdrv_op_block_all(bs, job->blocker);
76d554e2
KW
306
307 return 0;
23d402d4
AG
308}
309
559b935f
JS
310bool block_job_is_internal(BlockJob *job)
311{
33e9e9bd 312 return (job->job.id == NULL);
559b935f
JS
313}
314
5ccac6f1
JS
315static bool block_job_started(BlockJob *job)
316{
317 return job->co;
318}
319
bd21935b
KW
320const BlockJobDriver *block_job_driver(BlockJob *job)
321{
322 return job->driver;
323}
324
e3796a24
JS
325/**
326 * All jobs must allow a pause point before entering their job proper. This
327 * ensures that jobs can be paused prior to being started, then resumed later.
328 */
329static void coroutine_fn block_job_co_entry(void *opaque)
330{
331 BlockJob *job = opaque;
332
333 assert(job && job->driver && job->driver->start);
334 block_job_pause_point(job);
335 job->driver->start(job);
336}
337
fc24908e
PB
338static void block_job_sleep_timer_cb(void *opaque)
339{
340 BlockJob *job = opaque;
341
342 block_job_enter(job);
343}
344
5ccac6f1
JS
345void block_job_start(BlockJob *job)
346{
347 assert(job && !block_job_started(job) && job->paused &&
e3796a24
JS
348 job->driver && job->driver->start);
349 job->co = qemu_coroutine_create(block_job_co_entry, job);
350 job->pause_count--;
351 job->busy = true;
352 job->paused = false;
a50c2ab8 353 job_state_transition(&job->job, JOB_STATUS_RUNNING);
aef4278c 354 bdrv_coroutine_enter(blk_bs(job->blk), job->co);
5ccac6f1
JS
355}
356
3925cd3b
JS
357static void block_job_decommission(BlockJob *job)
358{
359 assert(job);
360 job->completed = true;
361 job->busy = false;
362 job->paused = false;
363 job->deferred_to_main_loop = true;
a865cebb 364 block_job_txn_del_job(job);
a50c2ab8 365 job_state_transition(&job->job, JOB_STATUS_NULL);
80fa2c75 366 job_unref(&job->job);
3925cd3b
JS
367}
368
75f71059
JS
369static void block_job_do_dismiss(BlockJob *job)
370{
371 block_job_decommission(job);
372}
373
e0cf0364
JS
374static void block_job_conclude(BlockJob *job)
375{
a50c2ab8 376 job_state_transition(&job->job, JOB_STATUS_CONCLUDED);
75f71059
JS
377 if (job->auto_dismiss || !block_job_started(job)) {
378 block_job_do_dismiss(job);
379 }
e0cf0364
JS
380}
381
35d6b368
JS
382static void block_job_update_rc(BlockJob *job)
383{
daa7f2f9 384 if (!job->ret && job_is_cancelled(&job->job)) {
35d6b368
JS
385 job->ret = -ECANCELED;
386 }
387 if (job->ret) {
a50c2ab8 388 job_state_transition(&job->job, JOB_STATUS_ABORTING);
35d6b368
JS
389 }
390}
391
2da4617a
JS
392static int block_job_prepare(BlockJob *job)
393{
394 if (job->ret == 0 && job->driver->prepare) {
395 job->ret = job->driver->prepare(job);
396 }
397 return job->ret;
398}
399
43628d93
JS
400static void block_job_commit(BlockJob *job)
401{
402 assert(!job->ret);
403 if (job->driver->commit) {
404 job->driver->commit(job);
405 }
406}
407
408static void block_job_abort(BlockJob *job)
409{
410 assert(job->ret);
411 if (job->driver->abort) {
412 job->driver->abort(job);
413 }
414}
415
416static void block_job_clean(BlockJob *job)
417{
418 if (job->driver->clean) {
419 job->driver->clean(job);
420 }
421}
422
11b61fbc 423static int block_job_finalize_single(BlockJob *job)
c55a832f 424{
4fb588e9
PB
425 assert(job->completed);
426
35d6b368
JS
427 /* Ensure abort is called for late-transactional failures */
428 block_job_update_rc(job);
10a3fbb0 429
c55a832f 430 if (!job->ret) {
43628d93 431 block_job_commit(job);
c55a832f 432 } else {
43628d93 433 block_job_abort(job);
e8a40bf7 434 }
43628d93 435 block_job_clean(job);
8254b6d9
JS
436
437 if (job->cb) {
438 job->cb(job->opaque, job->ret);
439 }
5ccac6f1
JS
440
441 /* Emit events only if we actually started */
442 if (block_job_started(job)) {
daa7f2f9 443 if (job_is_cancelled(&job->job)) {
5ccac6f1
JS
444 block_job_event_cancelled(job);
445 } else {
446 const char *msg = NULL;
447 if (job->ret < 0) {
448 msg = strerror(-job->ret);
449 }
450 block_job_event_completed(job, msg);
8254b6d9 451 }
8254b6d9
JS
452 }
453
a865cebb 454 block_job_txn_del_job(job);
e0cf0364 455 block_job_conclude(job);
2da4617a 456 return 0;
c55a832f
FZ
457}
458
b76e4458 459static void block_job_cancel_async(BlockJob *job, bool force)
4c241cf5
PB
460{
461 if (job->iostatus != BLOCK_DEVICE_IO_STATUS_OK) {
462 block_job_iostatus_reset(job);
463 }
464 if (job->user_paused) {
465 /* Do not call block_job_enter here, the caller will handle it. */
466 job->user_paused = false;
467 job->pause_count--;
468 }
daa7f2f9 469 job->job.cancelled = true;
b76e4458
LL
470 /* To prevent 'force == false' overriding a previous 'force == true' */
471 job->force |= force;
4c241cf5
PB
472}
473
5f241594 474static int block_job_txn_apply(BlockJobTxn *txn, int fn(BlockJob *), bool lock)
efe4d4b7
JS
475{
476 AioContext *ctx;
477 BlockJob *job, *next;
2da4617a 478 int rc = 0;
efe4d4b7
JS
479
480 QLIST_FOREACH_SAFE(job, &txn->jobs, txn_list, next) {
5f241594
JS
481 if (lock) {
482 ctx = blk_get_aio_context(job->blk);
483 aio_context_acquire(ctx);
484 }
2da4617a 485 rc = fn(job);
5f241594
JS
486 if (lock) {
487 aio_context_release(ctx);
488 }
2da4617a
JS
489 if (rc) {
490 break;
491 }
efe4d4b7 492 }
2da4617a 493 return rc;
efe4d4b7
JS
494}
495
c8ab5c2d
PB
496static int block_job_finish_sync(BlockJob *job,
497 void (*finish)(BlockJob *, Error **errp),
498 Error **errp)
499{
500 Error *local_err = NULL;
501 int ret;
502
503 assert(blk_bs(job->blk)->job == job);
504
80fa2c75 505 job_ref(&job->job);
c8ab5c2d 506
4fb588e9
PB
507 if (finish) {
508 finish(job, &local_err);
509 }
c8ab5c2d
PB
510 if (local_err) {
511 error_propagate(errp, local_err);
80fa2c75 512 job_unref(&job->job);
c8ab5c2d
PB
513 return -EBUSY;
514 }
515 /* block_job_drain calls block_job_enter, and it should be enough to
516 * induce progress until the job completes or moves to the main thread.
517 */
518 while (!job->deferred_to_main_loop && !job->completed) {
519 block_job_drain(job);
520 }
521 while (!job->completed) {
522 aio_poll(qemu_get_aio_context(), true);
523 }
daa7f2f9
KW
524 ret = (job_is_cancelled(&job->job) && job->ret == 0)
525 ? -ECANCELED : job->ret;
80fa2c75 526 job_unref(&job->job);
c8ab5c2d
PB
527 return ret;
528}
529
c55a832f
FZ
530static void block_job_completed_txn_abort(BlockJob *job)
531{
532 AioContext *ctx;
533 BlockJobTxn *txn = job->txn;
4fb588e9 534 BlockJob *other_job;
c55a832f
FZ
535
536 if (txn->aborting) {
537 /*
538 * We are cancelled by another job, which will handle everything.
539 */
540 return;
541 }
542 txn->aborting = true;
4fb588e9
PB
543 block_job_txn_ref(txn);
544
c55a832f
FZ
545 /* We are the first failed job. Cancel other jobs. */
546 QLIST_FOREACH(other_job, &txn->jobs, txn_list) {
b6d2e599 547 ctx = blk_get_aio_context(other_job->blk);
c55a832f
FZ
548 aio_context_acquire(ctx);
549 }
4fb588e9
PB
550
551 /* Other jobs are effectively cancelled by us, set the status for
552 * them; this job, however, may or may not be cancelled, depending
553 * on the caller, so leave it. */
c55a832f 554 QLIST_FOREACH(other_job, &txn->jobs, txn_list) {
4fb588e9 555 if (other_job != job) {
b76e4458 556 block_job_cancel_async(other_job, false);
c55a832f 557 }
c55a832f 558 }
4fb588e9
PB
559 while (!QLIST_EMPTY(&txn->jobs)) {
560 other_job = QLIST_FIRST(&txn->jobs);
b6d2e599 561 ctx = blk_get_aio_context(other_job->blk);
4fb588e9 562 if (!other_job->completed) {
daa7f2f9 563 assert(job_is_cancelled(&other_job->job));
4fb588e9
PB
564 block_job_finish_sync(other_job, NULL, NULL);
565 }
11b61fbc 566 block_job_finalize_single(other_job);
c55a832f
FZ
567 aio_context_release(ctx);
568 }
4fb588e9
PB
569
570 block_job_txn_unref(txn);
c55a832f
FZ
571}
572
11b61fbc
JS
573static int block_job_needs_finalize(BlockJob *job)
574{
575 return !job->auto_finalize;
576}
577
578static void block_job_do_finalize(BlockJob *job)
579{
580 int rc;
581 assert(job && job->txn);
582
583 /* prepare the transaction to complete */
584 rc = block_job_txn_apply(job->txn, block_job_prepare, true);
585 if (rc) {
586 block_job_completed_txn_abort(job);
587 } else {
588 block_job_txn_apply(job->txn, block_job_finalize_single, true);
589 }
590}
591
c55a832f
FZ
592static void block_job_completed_txn_success(BlockJob *job)
593{
c55a832f 594 BlockJobTxn *txn = job->txn;
efe4d4b7 595 BlockJob *other_job;
2da4617a 596
a50c2ab8 597 job_state_transition(&job->job, JOB_STATUS_WAITING);
e8af5686 598
c55a832f
FZ
599 /*
600 * Successful completion, see if there are other running jobs in this
601 * txn.
602 */
603 QLIST_FOREACH(other_job, &txn->jobs, txn_list) {
604 if (!other_job->completed) {
605 return;
606 }
c55a832f 607 assert(other_job->ret == 0);
c55a832f 608 }
2da4617a 609
5f241594 610 block_job_txn_apply(txn, block_job_event_pending, false);
11b61fbc
JS
611
612 /* If no jobs need manual finalization, automatically do so */
613 if (block_job_txn_apply(txn, block_job_needs_finalize, false) == 0) {
614 block_job_do_finalize(job);
615 }
c55a832f
FZ
616}
617
2f0c9fe6
PB
618void block_job_set_speed(BlockJob *job, int64_t speed, Error **errp)
619{
aa9ef2e6 620 int64_t old_speed = job->speed;
2f0c9fe6 621
a50c2ab8 622 if (job_apply_verb(&job->job, JOB_VERB_SET_SPEED, errp)) {
0ec4dfb8
JS
623 return;
624 }
18bb6928
KW
625 if (speed < 0) {
626 error_setg(errp, QERR_INVALID_PARAMETER, "speed");
2f0c9fe6
PB
627 return;
628 }
629
18bb6928
KW
630 ratelimit_set_speed(&job->limit, speed, BLOCK_JOB_SLICE_TIME);
631
2f0c9fe6 632 job->speed = speed;
d4fce188 633 if (speed && speed <= old_speed) {
aa9ef2e6
JS
634 return;
635 }
636
637 /* kick only if a timer is pending */
638 block_job_enter_cond(job, block_job_timer_pending);
2f0c9fe6
PB
639}
640
dee81d51
KW
641int64_t block_job_ratelimit_get_delay(BlockJob *job, uint64_t n)
642{
643 if (!job->speed) {
644 return 0;
645 }
646
647 return ratelimit_calculate_delay(&job->limit, n);
648}
649
aeae883b
PB
650void block_job_complete(BlockJob *job, Error **errp)
651{
559b935f 652 /* Should not be reachable via external interface for internal jobs */
33e9e9bd 653 assert(job->job.id);
a50c2ab8 654 if (job_apply_verb(&job->job, JOB_VERB_COMPLETE, errp)) {
0ec4dfb8
JS
655 return;
656 }
daa7f2f9
KW
657 if (job->pause_count || job_is_cancelled(&job->job) ||
658 !job->driver->complete)
659 {
9df229c3 660 error_setg(errp, "The active block job '%s' cannot be completed",
33e9e9bd 661 job->job.id);
aeae883b
PB
662 return;
663 }
664
3fc4b10a 665 job->driver->complete(job, errp);
aeae883b
PB
666}
667
11b61fbc
JS
668void block_job_finalize(BlockJob *job, Error **errp)
669{
33e9e9bd 670 assert(job && job->job.id);
a50c2ab8 671 if (job_apply_verb(&job->job, JOB_VERB_FINALIZE, errp)) {
11b61fbc
JS
672 return;
673 }
674 block_job_do_finalize(job);
675}
676
75f71059
JS
677void block_job_dismiss(BlockJob **jobptr, Error **errp)
678{
679 BlockJob *job = *jobptr;
680 /* similarly to _complete, this is QMP-interface only. */
33e9e9bd 681 assert(job->job.id);
a50c2ab8 682 if (job_apply_verb(&job->job, JOB_VERB_DISMISS, errp)) {
75f71059
JS
683 return;
684 }
685
686 block_job_do_dismiss(job);
687 *jobptr = NULL;
688}
689
0ec4dfb8 690void block_job_user_pause(BlockJob *job, Error **errp)
0df4ba58 691{
a50c2ab8 692 if (job_apply_verb(&job->job, JOB_VERB_PAUSE, errp)) {
0ec4dfb8
JS
693 return;
694 }
695 if (job->user_paused) {
696 error_setg(errp, "Job is already paused");
697 return;
698 }
0df4ba58
JS
699 job->user_paused = true;
700 block_job_pause(job);
701}
702
0df4ba58
JS
703bool block_job_user_paused(BlockJob *job)
704{
6573d9c6 705 return job->user_paused;
0df4ba58
JS
706}
707
0ec4dfb8 708void block_job_user_resume(BlockJob *job, Error **errp)
0df4ba58 709{
0ec4dfb8
JS
710 assert(job);
711 if (!job->user_paused || job->pause_count <= 0) {
712 error_setg(errp, "Can't resume a job that was not paused");
713 return;
0df4ba58 714 }
a50c2ab8 715 if (job_apply_verb(&job->job, JOB_VERB_RESUME, errp)) {
0ec4dfb8
JS
716 return;
717 }
718 block_job_iostatus_reset(job);
719 job->user_paused = false;
720 block_job_resume(job);
0df4ba58
JS
721}
722
b76e4458 723void block_job_cancel(BlockJob *job, bool force)
8acc72a4 724{
a50c2ab8 725 if (job->job.status == JOB_STATUS_CONCLUDED) {
75f71059 726 block_job_do_dismiss(job);
11b61fbc
JS
727 return;
728 }
b76e4458 729 block_job_cancel_async(job, force);
11b61fbc 730 if (!block_job_started(job)) {
5ccac6f1 731 block_job_completed(job, -ECANCELED);
11b61fbc
JS
732 } else if (job->deferred_to_main_loop) {
733 block_job_completed_txn_abort(job);
734 } else {
735 block_job_enter(job);
5ccac6f1 736 }
8acc72a4
PB
737}
738
b76e4458 739void block_job_user_cancel(BlockJob *job, bool force, Error **errp)
0ec4dfb8 740{
a50c2ab8 741 if (job_apply_verb(&job->job, JOB_VERB_CANCEL, errp)) {
0ec4dfb8
JS
742 return;
743 }
b76e4458 744 block_job_cancel(job, force);
0ec4dfb8
JS
745}
746
345f9e1b
HR
747/* A wrapper around block_job_cancel() taking an Error ** parameter so it may be
748 * used with block_job_finish_sync() without the need for (rather nasty)
749 * function pointer casts there. */
750static void block_job_cancel_err(BlockJob *job, Error **errp)
751{
b76e4458 752 block_job_cancel(job, false);
345f9e1b
HR
753}
754
755int block_job_cancel_sync(BlockJob *job)
756{
757 return block_job_finish_sync(job, &block_job_cancel_err, NULL);
758}
759
a1a2af07
KW
760void block_job_cancel_sync_all(void)
761{
762 BlockJob *job;
763 AioContext *aio_context;
764
e7c1d78b 765 while ((job = block_job_next(NULL))) {
b6d2e599 766 aio_context = blk_get_aio_context(job->blk);
a1a2af07
KW
767 aio_context_acquire(aio_context);
768 block_job_cancel_sync(job);
769 aio_context_release(aio_context);
770 }
771}
772
345f9e1b
HR
773int block_job_complete_sync(BlockJob *job, Error **errp)
774{
775 return block_job_finish_sync(job, &block_job_complete, errp);
776}
777
05df8a6a
KW
778void block_job_progress_update(BlockJob *job, uint64_t done)
779{
780 job->offset += done;
781}
782
783void block_job_progress_set_remaining(BlockJob *job, uint64_t remaining)
784{
785 job->len = job->offset + remaining;
786}
787
559b935f 788BlockJobInfo *block_job_query(BlockJob *job, Error **errp)
30e628b7 789{
559b935f
JS
790 BlockJobInfo *info;
791
792 if (block_job_is_internal(job)) {
793 error_setg(errp, "Cannot query QEMU internal jobs");
794 return NULL;
795 }
796 info = g_new0(BlockJobInfo, 1);
252291ea 797 info->type = g_strdup(job_type_str(&job->job));
33e9e9bd 798 info->device = g_strdup(job->job.id);
32c81a4a 799 info->len = job->len;
fc24908e 800 info->busy = atomic_read(&job->busy);
751ebd76 801 info->paused = job->pause_count > 0;
32c81a4a
PB
802 info->offset = job->offset;
803 info->speed = job->speed;
804 info->io_status = job->iostatus;
ef6dbf1e 805 info->ready = job->ready;
a50c2ab8 806 info->status = job->job.status;
b40dacdc
JS
807 info->auto_finalize = job->auto_finalize;
808 info->auto_dismiss = job->auto_dismiss;
ab9ba614
JS
809 info->has_error = job->ret != 0;
810 info->error = job->ret ? g_strdup(strerror(-job->ret)) : NULL;
30e628b7
PB
811 return info;
812}
32c81a4a
PB
813
814static void block_job_iostatus_set_err(BlockJob *job, int error)
815{
816 if (job->iostatus == BLOCK_DEVICE_IO_STATUS_OK) {
817 job->iostatus = error == ENOSPC ? BLOCK_DEVICE_IO_STATUS_NOSPACE :
818 BLOCK_DEVICE_IO_STATUS_FAILED;
819 }
820}
821
8254b6d9 822static void block_job_event_cancelled(BlockJob *job)
bcada37b 823{
559b935f
JS
824 if (block_job_is_internal(job)) {
825 return;
826 }
827
252291ea 828 qapi_event_send_block_job_cancelled(job_type(&job->job),
33e9e9bd 829 job->job.id,
bcada37b
WX
830 job->len,
831 job->offset,
832 job->speed,
833 &error_abort);
834}
32c81a4a 835
8254b6d9 836static void block_job_event_completed(BlockJob *job, const char *msg)
a66a2a36 837{
559b935f
JS
838 if (block_job_is_internal(job)) {
839 return;
840 }
841
252291ea 842 qapi_event_send_block_job_completed(job_type(&job->job),
33e9e9bd 843 job->job.id,
bcada37b
WX
844 job->len,
845 job->offset,
846 job->speed,
847 !!msg,
848 msg,
849 &error_abort);
a66a2a36
PB
850}
851
5f241594
JS
852static int block_job_event_pending(BlockJob *job)
853{
a50c2ab8 854 job_state_transition(&job->job, JOB_STATUS_PENDING);
5f241594 855 if (!job->auto_finalize && !block_job_is_internal(job)) {
252291ea 856 qapi_event_send_block_job_pending(job_type(&job->job),
33e9e9bd 857 job->job.id,
5f241594
JS
858 &error_abort);
859 }
860 return 0;
861}
862
88691b37
PB
863/*
864 * API for block job drivers and the block layer. These functions are
865 * declared in blockjob_int.h.
866 */
867
868void *block_job_create(const char *job_id, const BlockJobDriver *driver,
75859b94 869 BlockJobTxn *txn, BlockDriverState *bs, uint64_t perm,
88691b37
PB
870 uint64_t shared_perm, int64_t speed, int flags,
871 BlockCompletionFunc *cb, void *opaque, Error **errp)
872{
873 BlockBackend *blk;
874 BlockJob *job;
875 int ret;
876
877 if (bs->job) {
878 error_setg(errp, QERR_DEVICE_IN_USE, bdrv_get_device_name(bs));
879 return NULL;
880 }
881
882 if (job_id == NULL && !(flags & BLOCK_JOB_INTERNAL)) {
883 job_id = bdrv_get_device_name(bs);
884 if (!*job_id) {
885 error_setg(errp, "An explicit job ID is required for this node");
886 return NULL;
887 }
888 }
889
890 if (job_id) {
891 if (flags & BLOCK_JOB_INTERNAL) {
892 error_setg(errp, "Cannot specify job ID for internal block job");
893 return NULL;
894 }
88691b37
PB
895 }
896
897 blk = blk_new(perm, shared_perm);
898 ret = blk_insert_bs(blk, bs, errp);
899 if (ret < 0) {
900 blk_unref(blk);
901 return NULL;
902 }
903
08be6fe2
KW
904 job = job_create(job_id, &driver->job_driver, blk_get_aio_context(blk),
905 errp);
33e9e9bd
KW
906 if (job == NULL) {
907 blk_unref(blk);
908 return NULL;
909 }
910
e7c1d78b 911 assert(is_block_job(&job->job));
80fa2c75 912 assert(job->job.driver->free == &block_job_free);
e7c1d78b 913
88691b37 914 job->driver = driver;
88691b37
PB
915 job->blk = blk;
916 job->cb = cb;
917 job->opaque = opaque;
918 job->busy = false;
919 job->paused = true;
920 job->pause_count = 1;
5f241594 921 job->auto_finalize = !(flags & BLOCK_JOB_MANUAL_FINALIZE);
75f71059 922 job->auto_dismiss = !(flags & BLOCK_JOB_MANUAL_DISMISS);
fc24908e
PB
923 aio_timer_init(qemu_get_aio_context(), &job->sleep_timer,
924 QEMU_CLOCK_REALTIME, SCALE_NS,
925 block_job_sleep_timer_cb, job);
88691b37
PB
926
927 error_setg(&job->blocker, "block device is in use by block job: %s",
252291ea 928 job_type_str(&job->job));
88691b37
PB
929 block_job_add_bdrv(job, "main node", bs, 0, BLK_PERM_ALL, &error_abort);
930 bs->job = job;
931
88691b37
PB
932 bdrv_op_unblock(bs, BLOCK_OP_TYPE_DATAPLANE, job->blocker);
933
88691b37
PB
934 blk_add_aio_context_notifier(blk, block_job_attached_aio_context,
935 block_job_detach_aio_context, job);
936
937 /* Only set speed when necessary to avoid NotSupported error */
938 if (speed != 0) {
939 Error *local_err = NULL;
940
941 block_job_set_speed(job, speed, &local_err);
942 if (local_err) {
3925cd3b 943 block_job_early_fail(job);
88691b37
PB
944 error_propagate(errp, local_err);
945 return NULL;
946 }
947 }
75859b94
JS
948
949 /* Single jobs are modeled as single-job transactions for sake of
950 * consolidating the job management logic */
951 if (!txn) {
952 txn = block_job_txn_new();
953 block_job_txn_add_job(txn, job);
954 block_job_txn_unref(txn);
955 } else {
956 block_job_txn_add_job(txn, job);
957 }
958
88691b37
PB
959 return job;
960}
961
88691b37
PB
962void block_job_early_fail(BlockJob *job)
963{
a50c2ab8 964 assert(job->job.status == JOB_STATUS_CREATED);
3925cd3b 965 block_job_decommission(job);
88691b37
PB
966}
967
968void block_job_completed(BlockJob *job, int ret)
969{
75859b94 970 assert(job && job->txn && !job->completed);
88691b37 971 assert(blk_bs(job->blk)->job == job);
88691b37
PB
972 job->completed = true;
973 job->ret = ret;
35d6b368
JS
974 block_job_update_rc(job);
975 trace_block_job_completed(job, ret, job->ret);
976 if (job->ret) {
88691b37
PB
977 block_job_completed_txn_abort(job);
978 } else {
979 block_job_completed_txn_success(job);
980 }
981}
982
983static bool block_job_should_pause(BlockJob *job)
984{
985 return job->pause_count > 0;
986}
987
fc24908e
PB
988/* Yield, and schedule a timer to reenter the coroutine after @ns nanoseconds.
989 * Reentering the job coroutine with block_job_enter() before the timer has
990 * expired is allowed and cancels the timer.
991 *
992 * If @ns is (uint64_t) -1, no timer is scheduled and block_job_enter() must be
993 * called explicitly. */
994static void block_job_do_yield(BlockJob *job, uint64_t ns)
356f59b8 995{
fc24908e
PB
996 block_job_lock();
997 if (ns != -1) {
998 timer_mod(&job->sleep_timer, ns);
999 }
356f59b8 1000 job->busy = false;
fc24908e 1001 block_job_unlock();
356f59b8
PB
1002 qemu_coroutine_yield();
1003
1004 /* Set by block_job_enter before re-entering the coroutine. */
1005 assert(job->busy);
1006}
1007
88691b37
PB
1008void coroutine_fn block_job_pause_point(BlockJob *job)
1009{
1010 assert(job && block_job_started(job));
1011
1012 if (!block_job_should_pause(job)) {
1013 return;
1014 }
daa7f2f9 1015 if (job_is_cancelled(&job->job)) {
88691b37
PB
1016 return;
1017 }
1018
1019 if (job->driver->pause) {
1020 job->driver->pause(job);
1021 }
1022
daa7f2f9 1023 if (block_job_should_pause(job) && !job_is_cancelled(&job->job)) {
a50c2ab8
KW
1024 JobStatus status = job->job.status;
1025 job_state_transition(&job->job, status == JOB_STATUS_READY
1026 ? JOB_STATUS_STANDBY
1027 : JOB_STATUS_PAUSED);
88691b37 1028 job->paused = true;
fc24908e 1029 block_job_do_yield(job, -1);
88691b37 1030 job->paused = false;
a50c2ab8 1031 job_state_transition(&job->job, status);
88691b37
PB
1032 }
1033
1034 if (job->driver->resume) {
1035 job->driver->resume(job);
1036 }
1037}
1038
aa9ef2e6
JS
1039/*
1040 * Conditionally enter a block_job pending a call to fn() while
1041 * under the block_job_lock critical section.
1042 */
1043static void block_job_enter_cond(BlockJob *job, bool(*fn)(BlockJob *job))
88691b37 1044{
eb05e011
PB
1045 if (!block_job_started(job)) {
1046 return;
1047 }
1048 if (job->deferred_to_main_loop) {
1049 return;
1050 }
1051
fc24908e 1052 block_job_lock();
356f59b8 1053 if (job->busy) {
fc24908e 1054 block_job_unlock();
356f59b8 1055 return;
88691b37 1056 }
356f59b8 1057
aa9ef2e6
JS
1058 if (fn && !fn(job)) {
1059 block_job_unlock();
1060 return;
1061 }
1062
fc24908e
PB
1063 assert(!job->deferred_to_main_loop);
1064 timer_del(&job->sleep_timer);
356f59b8 1065 job->busy = true;
fc24908e 1066 block_job_unlock();
356f59b8 1067 aio_co_wake(job->co);
88691b37
PB
1068}
1069
aa9ef2e6
JS
1070void block_job_enter(BlockJob *job)
1071{
1072 block_job_enter_cond(job, NULL);
1073}
1074
5bf1d5a7 1075void block_job_sleep_ns(BlockJob *job, int64_t ns)
88691b37
PB
1076{
1077 assert(job->busy);
1078
1079 /* Check cancellation *before* setting busy = false, too! */
daa7f2f9 1080 if (job_is_cancelled(&job->job)) {
88691b37
PB
1081 return;
1082 }
1083
88691b37 1084 if (!block_job_should_pause(job)) {
fc24908e 1085 block_job_do_yield(job, qemu_clock_get_ns(QEMU_CLOCK_REALTIME) + ns);
88691b37 1086 }
88691b37
PB
1087
1088 block_job_pause_point(job);
1089}
1090
1091void block_job_yield(BlockJob *job)
1092{
1093 assert(job->busy);
1094
1095 /* Check cancellation *before* setting busy = false, too! */
daa7f2f9 1096 if (job_is_cancelled(&job->job)) {
88691b37
PB
1097 return;
1098 }
1099
88691b37 1100 if (!block_job_should_pause(job)) {
fc24908e 1101 block_job_do_yield(job, -1);
88691b37 1102 }
88691b37
PB
1103
1104 block_job_pause_point(job);
1105}
1106
2caf63a9
PB
1107void block_job_iostatus_reset(BlockJob *job)
1108{
4c241cf5
PB
1109 if (job->iostatus == BLOCK_DEVICE_IO_STATUS_OK) {
1110 return;
1111 }
1112 assert(job->user_paused && job->pause_count > 0);
2caf63a9
PB
1113 job->iostatus = BLOCK_DEVICE_IO_STATUS_OK;
1114}
1115
bcada37b 1116void block_job_event_ready(BlockJob *job)
a66a2a36 1117{
a50c2ab8 1118 job_state_transition(&job->job, JOB_STATUS_READY);
ef6dbf1e
HR
1119 job->ready = true;
1120
559b935f
JS
1121 if (block_job_is_internal(job)) {
1122 return;
1123 }
1124
252291ea 1125 qapi_event_send_block_job_ready(job_type(&job->job),
33e9e9bd 1126 job->job.id,
518848a2
MA
1127 job->len,
1128 job->offset,
1129 job->speed, &error_abort);
a66a2a36
PB
1130}
1131
81e254dc 1132BlockErrorAction block_job_error_action(BlockJob *job, BlockdevOnError on_err,
32c81a4a
PB
1133 int is_read, int error)
1134{
1135 BlockErrorAction action;
1136
1137 switch (on_err) {
1138 case BLOCKDEV_ON_ERROR_ENOSPC:
8c398252 1139 case BLOCKDEV_ON_ERROR_AUTO:
a589569f
WX
1140 action = (error == ENOSPC) ?
1141 BLOCK_ERROR_ACTION_STOP : BLOCK_ERROR_ACTION_REPORT;
32c81a4a
PB
1142 break;
1143 case BLOCKDEV_ON_ERROR_STOP:
a589569f 1144 action = BLOCK_ERROR_ACTION_STOP;
32c81a4a
PB
1145 break;
1146 case BLOCKDEV_ON_ERROR_REPORT:
a589569f 1147 action = BLOCK_ERROR_ACTION_REPORT;
32c81a4a
PB
1148 break;
1149 case BLOCKDEV_ON_ERROR_IGNORE:
a589569f 1150 action = BLOCK_ERROR_ACTION_IGNORE;
32c81a4a
PB
1151 break;
1152 default:
1153 abort();
1154 }
559b935f 1155 if (!block_job_is_internal(job)) {
33e9e9bd 1156 qapi_event_send_block_job_error(job->job.id,
559b935f
JS
1157 is_read ? IO_OPERATION_TYPE_READ :
1158 IO_OPERATION_TYPE_WRITE,
1159 action, &error_abort);
1160 }
a589569f 1161 if (action == BLOCK_ERROR_ACTION_STOP) {
0ec4dfb8 1162 block_job_pause(job);
751ebd76 1163 /* make the pause user visible, which will be resumed from QMP. */
0ec4dfb8 1164 job->user_paused = true;
32c81a4a 1165 block_job_iostatus_set_err(job, error);
32c81a4a
PB
1166 }
1167 return action;
1168}
dec7d421
SH
1169
1170typedef struct {
1171 BlockJob *job;
dec7d421
SH
1172 AioContext *aio_context;
1173 BlockJobDeferToMainLoopFn *fn;
1174 void *opaque;
1175} BlockJobDeferToMainLoopData;
1176
1177static void block_job_defer_to_main_loop_bh(void *opaque)
1178{
1179 BlockJobDeferToMainLoopData *data = opaque;
1180 AioContext *aio_context;
1181
dec7d421
SH
1182 /* Prevent race with block_job_defer_to_main_loop() */
1183 aio_context_acquire(data->aio_context);
1184
1185 /* Fetch BDS AioContext again, in case it has changed */
b6d2e599 1186 aio_context = blk_get_aio_context(data->job->blk);
d79df2a2
PB
1187 if (aio_context != data->aio_context) {
1188 aio_context_acquire(aio_context);
1189 }
dec7d421
SH
1190
1191 data->fn(data->job, data->opaque);
1192
d79df2a2
PB
1193 if (aio_context != data->aio_context) {
1194 aio_context_release(aio_context);
1195 }
dec7d421
SH
1196
1197 aio_context_release(data->aio_context);
1198
1199 g_free(data);
1200}
1201
1202void block_job_defer_to_main_loop(BlockJob *job,
1203 BlockJobDeferToMainLoopFn *fn,
1204 void *opaque)
1205{
1206 BlockJobDeferToMainLoopData *data = g_malloc(sizeof(*data));
1207 data->job = job;
b6d2e599 1208 data->aio_context = blk_get_aio_context(job->blk);
dec7d421
SH
1209 data->fn = fn;
1210 data->opaque = opaque;
794f0141 1211 job->deferred_to_main_loop = true;
dec7d421 1212
fffb6e12
PB
1213 aio_bh_schedule_oneshot(qemu_get_aio_context(),
1214 block_job_defer_to_main_loop_bh, data);
dec7d421 1215}