blob: ba2255d91f71ec9b93059b38014205eee9d1927e [file] [log] [blame]
Paolo Bonzini2f0c9fe2012-09-28 17:22:47 +02001/*
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
26#include "config-host.h"
27#include "qemu-common.h"
28#include "trace.h"
Paolo Bonzini737e1502012-12-17 18:19:44 +010029#include "block/block.h"
30#include "block/blockjob.h"
31#include "block/block_int.h"
Paolo Bonzini7b1b5d12012-12-17 18:19:43 +010032#include "qapi/qmp/qjson.h"
Paolo Bonzini737e1502012-12-17 18:19:44 +010033#include "block/coroutine.h"
Paolo Bonzini2f0c9fe2012-09-28 17:22:47 +020034#include "qmp-commands.h"
Paolo Bonzini1de7afc2012-12-17 18:20:00 +010035#include "qemu/timer.h"
Wenchao Xia5a2d2cb2014-06-18 08:43:45 +020036#include "qapi-event.h"
Paolo Bonzini2f0c9fe2012-09-28 17:22:47 +020037
Fam Zheng3fc4b102013-10-08 17:29:38 +080038void *block_job_create(const BlockJobDriver *driver, BlockDriverState *bs,
Markus Armbruster097310b2014-10-07 13:59:15 +020039 int64_t speed, BlockCompletionFunc *cb,
Paolo Bonzini2f0c9fe2012-09-28 17:22:47 +020040 void *opaque, Error **errp)
41{
42 BlockJob *job;
43
Fam Zheng628ff682014-05-23 21:29:44 +080044 if (bs->job) {
Paolo Bonzini2f0c9fe2012-09-28 17:22:47 +020045 error_set(errp, QERR_DEVICE_IN_USE, bdrv_get_device_name(bs));
46 return NULL;
47 }
Fam Zhengfa510eb2013-08-23 09:14:51 +080048 bdrv_ref(bs);
Fam Zheng3fc4b102013-10-08 17:29:38 +080049 job = g_malloc0(driver->instance_size);
Fam Zheng3718d8a2014-05-23 21:29:43 +080050 error_setg(&job->blocker, "block device is in use by block job: %s",
51 BlockJobType_lookup[driver->job_type]);
52 bdrv_op_block_all(bs, job->blocker);
Stefan Hajnoczib112a652014-10-21 12:04:00 +010053 bdrv_op_unblock(bs, BLOCK_OP_TYPE_DATAPLANE, job->blocker);
Fam Zheng3718d8a2014-05-23 21:29:43 +080054
Fam Zheng3fc4b102013-10-08 17:29:38 +080055 job->driver = driver;
Paolo Bonzini2f0c9fe2012-09-28 17:22:47 +020056 job->bs = bs;
57 job->cb = cb;
58 job->opaque = opaque;
59 job->busy = true;
60 bs->job = job;
61
62 /* Only set speed when necessary to avoid NotSupported error */
63 if (speed != 0) {
64 Error *local_err = NULL;
65
66 block_job_set_speed(job, speed, &local_err);
Markus Armbruster84d18f02014-01-30 15:07:28 +010067 if (local_err) {
Paolo Bonzini2f0c9fe2012-09-28 17:22:47 +020068 bs->job = NULL;
Fam Zheng3718d8a2014-05-23 21:29:43 +080069 bdrv_op_unblock_all(bs, job->blocker);
70 error_free(job->blocker);
Paolo Bonzini2f0c9fe2012-09-28 17:22:47 +020071 g_free(job);
Paolo Bonzini2f0c9fe2012-09-28 17:22:47 +020072 error_propagate(errp, local_err);
73 return NULL;
74 }
75 }
76 return job;
77}
78
Paolo Bonzini65f46322012-10-18 16:49:20 +020079void block_job_completed(BlockJob *job, int ret)
Paolo Bonzini2f0c9fe2012-09-28 17:22:47 +020080{
81 BlockDriverState *bs = job->bs;
82
83 assert(bs->job == job);
84 job->cb(job->opaque, ret);
85 bs->job = NULL;
Fam Zheng3718d8a2014-05-23 21:29:43 +080086 bdrv_op_unblock_all(bs, job->blocker);
87 error_free(job->blocker);
Paolo Bonzini2f0c9fe2012-09-28 17:22:47 +020088 g_free(job);
Paolo Bonzini2f0c9fe2012-09-28 17:22:47 +020089}
90
91void block_job_set_speed(BlockJob *job, int64_t speed, Error **errp)
92{
93 Error *local_err = NULL;
94
Fam Zheng3fc4b102013-10-08 17:29:38 +080095 if (!job->driver->set_speed) {
Cole Robinson0b15abf2014-03-21 19:42:27 -040096 error_set(errp, QERR_UNSUPPORTED);
Paolo Bonzini2f0c9fe2012-09-28 17:22:47 +020097 return;
98 }
Fam Zheng3fc4b102013-10-08 17:29:38 +080099 job->driver->set_speed(job, speed, &local_err);
Markus Armbruster84d18f02014-01-30 15:07:28 +0100100 if (local_err) {
Paolo Bonzini2f0c9fe2012-09-28 17:22:47 +0200101 error_propagate(errp, local_err);
102 return;
103 }
104
105 job->speed = speed;
106}
107
Paolo Bonziniaeae8832012-10-18 16:49:21 +0200108void block_job_complete(BlockJob *job, Error **errp)
109{
Fam Zheng3fc4b102013-10-08 17:29:38 +0800110 if (job->paused || job->cancelled || !job->driver->complete) {
Markus Armbrusterbfb197e2014-10-07 13:59:11 +0200111 error_set(errp, QERR_BLOCK_JOB_NOT_READY,
112 bdrv_get_device_name(job->bs));
Paolo Bonziniaeae8832012-10-18 16:49:21 +0200113 return;
114 }
115
Fam Zheng3fc4b102013-10-08 17:29:38 +0800116 job->driver->complete(job, errp);
Paolo Bonziniaeae8832012-10-18 16:49:21 +0200117}
118
Paolo Bonzini8acc72a2012-09-28 17:22:50 +0200119void block_job_pause(BlockJob *job)
Paolo Bonzini2f0c9fe2012-09-28 17:22:47 +0200120{
Paolo Bonzini8acc72a2012-09-28 17:22:50 +0200121 job->paused = true;
122}
123
124bool block_job_is_paused(BlockJob *job)
125{
126 return job->paused;
127}
128
129void block_job_resume(BlockJob *job)
130{
131 job->paused = false;
Paolo Bonzini32c81a42012-09-28 17:22:58 +0200132 block_job_iostatus_reset(job);
Paolo Bonzini2f0c9fe2012-09-28 17:22:47 +0200133 if (job->co && !job->busy) {
134 qemu_coroutine_enter(job->co, NULL);
135 }
136}
137
Paolo Bonzini8acc72a2012-09-28 17:22:50 +0200138void block_job_cancel(BlockJob *job)
139{
140 job->cancelled = true;
141 block_job_resume(job);
142}
143
Paolo Bonzini2f0c9fe2012-09-28 17:22:47 +0200144bool block_job_is_cancelled(BlockJob *job)
145{
146 return job->cancelled;
147}
148
Paolo Bonzini32c81a42012-09-28 17:22:58 +0200149void block_job_iostatus_reset(BlockJob *job)
150{
151 job->iostatus = BLOCK_DEVICE_IO_STATUS_OK;
Fam Zheng3fc4b102013-10-08 17:29:38 +0800152 if (job->driver->iostatus_reset) {
153 job->driver->iostatus_reset(job);
Paolo Bonzini3bd293c2012-10-18 16:49:27 +0200154 }
Paolo Bonzini32c81a42012-09-28 17:22:58 +0200155}
156
Max Reitz345f9e12014-10-24 15:57:33 +0200157struct BlockFinishData {
Paolo Bonzini2f0c9fe2012-09-28 17:22:47 +0200158 BlockJob *job;
Markus Armbruster097310b2014-10-07 13:59:15 +0200159 BlockCompletionFunc *cb;
Paolo Bonzini2f0c9fe2012-09-28 17:22:47 +0200160 void *opaque;
161 bool cancelled;
162 int ret;
163};
164
Max Reitz345f9e12014-10-24 15:57:33 +0200165static void block_job_finish_cb(void *opaque, int ret)
Paolo Bonzini2f0c9fe2012-09-28 17:22:47 +0200166{
Max Reitz345f9e12014-10-24 15:57:33 +0200167 struct BlockFinishData *data = opaque;
Paolo Bonzini2f0c9fe2012-09-28 17:22:47 +0200168
169 data->cancelled = block_job_is_cancelled(data->job);
170 data->ret = ret;
171 data->cb(data->opaque, ret);
172}
173
Max Reitz345f9e12014-10-24 15:57:33 +0200174static int block_job_finish_sync(BlockJob *job,
175 void (*finish)(BlockJob *, Error **errp),
176 Error **errp)
Paolo Bonzini2f0c9fe2012-09-28 17:22:47 +0200177{
Max Reitz345f9e12014-10-24 15:57:33 +0200178 struct BlockFinishData data;
Paolo Bonzini2f0c9fe2012-09-28 17:22:47 +0200179 BlockDriverState *bs = job->bs;
Max Reitz345f9e12014-10-24 15:57:33 +0200180 Error *local_err = NULL;
Paolo Bonzini2f0c9fe2012-09-28 17:22:47 +0200181
182 assert(bs->job == job);
183
184 /* Set up our own callback to store the result and chain to
185 * the original callback.
186 */
187 data.job = job;
188 data.cb = job->cb;
189 data.opaque = job->opaque;
190 data.ret = -EINPROGRESS;
Max Reitz345f9e12014-10-24 15:57:33 +0200191 job->cb = block_job_finish_cb;
Paolo Bonzini2f0c9fe2012-09-28 17:22:47 +0200192 job->opaque = &data;
Max Reitz345f9e12014-10-24 15:57:33 +0200193 finish(job, &local_err);
194 if (local_err) {
195 error_propagate(errp, local_err);
196 return -EBUSY;
197 }
Paolo Bonzini2f0c9fe2012-09-28 17:22:47 +0200198 while (data.ret == -EINPROGRESS) {
Paolo Bonzinib47ec2c2014-07-07 15:18:01 +0200199 aio_poll(bdrv_get_aio_context(bs), true);
Paolo Bonzini2f0c9fe2012-09-28 17:22:47 +0200200 }
201 return (data.cancelled && data.ret == 0) ? -ECANCELED : data.ret;
202}
203
Max Reitz345f9e12014-10-24 15:57:33 +0200204/* A wrapper around block_job_cancel() taking an Error ** parameter so it may be
205 * used with block_job_finish_sync() without the need for (rather nasty)
206 * function pointer casts there. */
207static void block_job_cancel_err(BlockJob *job, Error **errp)
208{
209 block_job_cancel(job);
210}
211
212int block_job_cancel_sync(BlockJob *job)
213{
214 return block_job_finish_sync(job, &block_job_cancel_err, NULL);
215}
216
217int block_job_complete_sync(BlockJob *job, Error **errp)
218{
219 return block_job_finish_sync(job, &block_job_complete, errp);
220}
221
Alex Bligh7483d1e2013-08-21 16:03:05 +0100222void block_job_sleep_ns(BlockJob *job, QEMUClockType type, int64_t ns)
Paolo Bonzini2f0c9fe2012-09-28 17:22:47 +0200223{
Paolo Bonzini8acc72a2012-09-28 17:22:50 +0200224 assert(job->busy);
225
Paolo Bonzini2f0c9fe2012-09-28 17:22:47 +0200226 /* Check cancellation *before* setting busy = false, too! */
Paolo Bonzini8acc72a2012-09-28 17:22:50 +0200227 if (block_job_is_cancelled(job)) {
228 return;
Paolo Bonzini2f0c9fe2012-09-28 17:22:47 +0200229 }
Paolo Bonzini8acc72a2012-09-28 17:22:50 +0200230
231 job->busy = false;
232 if (block_job_is_paused(job)) {
233 qemu_coroutine_yield();
234 } else {
Fam Zheng0b9caf92014-08-26 15:15:43 +0800235 co_aio_sleep_ns(bdrv_get_aio_context(job->bs), type, ns);
Paolo Bonzini8acc72a2012-09-28 17:22:50 +0200236 }
237 job->busy = true;
Paolo Bonzini2f0c9fe2012-09-28 17:22:47 +0200238}
Paolo Bonzini30e628b2012-09-28 17:22:48 +0200239
Fam Zhengdc71ce42014-06-24 20:26:35 +0800240void block_job_yield(BlockJob *job)
241{
242 assert(job->busy);
243
244 /* Check cancellation *before* setting busy = false, too! */
245 if (block_job_is_cancelled(job)) {
246 return;
247 }
248
249 job->busy = false;
250 qemu_coroutine_yield();
251 job->busy = true;
252}
253
Paolo Bonzini30e628b2012-09-28 17:22:48 +0200254BlockJobInfo *block_job_query(BlockJob *job)
255{
256 BlockJobInfo *info = g_new0(BlockJobInfo, 1);
Fam Zheng79e14bf2013-10-08 17:29:40 +0800257 info->type = g_strdup(BlockJobType_lookup[job->driver->job_type]);
Paolo Bonzini32c81a42012-09-28 17:22:58 +0200258 info->device = g_strdup(bdrv_get_device_name(job->bs));
259 info->len = job->len;
260 info->busy = job->busy;
261 info->paused = job->paused;
262 info->offset = job->offset;
263 info->speed = job->speed;
264 info->io_status = job->iostatus;
Max Reitzef6dbf12014-10-24 15:57:34 +0200265 info->ready = job->ready;
Paolo Bonzini30e628b2012-09-28 17:22:48 +0200266 return info;
267}
Paolo Bonzini32c81a42012-09-28 17:22:58 +0200268
269static void block_job_iostatus_set_err(BlockJob *job, int error)
270{
271 if (job->iostatus == BLOCK_DEVICE_IO_STATUS_OK) {
272 job->iostatus = error == ENOSPC ? BLOCK_DEVICE_IO_STATUS_NOSPACE :
273 BLOCK_DEVICE_IO_STATUS_FAILED;
274 }
275}
276
Wenchao Xiabcada37b2014-06-18 08:43:47 +0200277void block_job_event_cancelled(BlockJob *job)
Paolo Bonzinia66a2a32012-07-23 15:15:47 +0200278{
Wenchao Xiabcada37b2014-06-18 08:43:47 +0200279 qapi_event_send_block_job_cancelled(job->driver->job_type,
280 bdrv_get_device_name(job->bs),
281 job->len,
282 job->offset,
283 job->speed,
284 &error_abort);
Paolo Bonzinia66a2a32012-07-23 15:15:47 +0200285}
286
Wenchao Xiabcada37b2014-06-18 08:43:47 +0200287void block_job_event_completed(BlockJob *job, const char *msg)
Paolo Bonzinia66a2a32012-07-23 15:15:47 +0200288{
Wenchao Xiabcada37b2014-06-18 08:43:47 +0200289 qapi_event_send_block_job_completed(job->driver->job_type,
290 bdrv_get_device_name(job->bs),
291 job->len,
292 job->offset,
293 job->speed,
294 !!msg,
295 msg,
296 &error_abort);
297}
298
299void block_job_event_ready(BlockJob *job)
300{
Max Reitzef6dbf12014-10-24 15:57:34 +0200301 job->ready = true;
302
Markus Armbruster518848a2014-06-27 19:24:13 +0200303 qapi_event_send_block_job_ready(job->driver->job_type,
304 bdrv_get_device_name(job->bs),
305 job->len,
306 job->offset,
307 job->speed, &error_abort);
Paolo Bonzinia66a2a32012-07-23 15:15:47 +0200308}
309
Paolo Bonzini32c81a42012-09-28 17:22:58 +0200310BlockErrorAction block_job_error_action(BlockJob *job, BlockDriverState *bs,
311 BlockdevOnError on_err,
312 int is_read, int error)
313{
314 BlockErrorAction action;
315
316 switch (on_err) {
317 case BLOCKDEV_ON_ERROR_ENOSPC:
Wenchao Xiaa5895692014-06-18 08:43:30 +0200318 action = (error == ENOSPC) ?
319 BLOCK_ERROR_ACTION_STOP : BLOCK_ERROR_ACTION_REPORT;
Paolo Bonzini32c81a42012-09-28 17:22:58 +0200320 break;
321 case BLOCKDEV_ON_ERROR_STOP:
Wenchao Xiaa5895692014-06-18 08:43:30 +0200322 action = BLOCK_ERROR_ACTION_STOP;
Paolo Bonzini32c81a42012-09-28 17:22:58 +0200323 break;
324 case BLOCKDEV_ON_ERROR_REPORT:
Wenchao Xiaa5895692014-06-18 08:43:30 +0200325 action = BLOCK_ERROR_ACTION_REPORT;
Paolo Bonzini32c81a42012-09-28 17:22:58 +0200326 break;
327 case BLOCKDEV_ON_ERROR_IGNORE:
Wenchao Xiaa5895692014-06-18 08:43:30 +0200328 action = BLOCK_ERROR_ACTION_IGNORE;
Paolo Bonzini32c81a42012-09-28 17:22:58 +0200329 break;
330 default:
331 abort();
332 }
Markus Armbruster823c6862014-06-27 19:24:14 +0200333 qapi_event_send_block_job_error(bdrv_get_device_name(job->bs),
Wenchao Xia5a2d2cb2014-06-18 08:43:45 +0200334 is_read ? IO_OPERATION_TYPE_READ :
335 IO_OPERATION_TYPE_WRITE,
336 action, &error_abort);
Wenchao Xiaa5895692014-06-18 08:43:30 +0200337 if (action == BLOCK_ERROR_ACTION_STOP) {
Paolo Bonzini32c81a42012-09-28 17:22:58 +0200338 block_job_pause(job);
339 block_job_iostatus_set_err(job, error);
340 if (bs != job->bs) {
341 bdrv_iostatus_set_err(bs, error);
342 }
343 }
344 return action;
345}
Stefan Hajnoczidec7d422014-10-21 12:03:54 +0100346
347typedef struct {
348 BlockJob *job;
349 QEMUBH *bh;
350 AioContext *aio_context;
351 BlockJobDeferToMainLoopFn *fn;
352 void *opaque;
353} BlockJobDeferToMainLoopData;
354
355static void block_job_defer_to_main_loop_bh(void *opaque)
356{
357 BlockJobDeferToMainLoopData *data = opaque;
358 AioContext *aio_context;
359
360 qemu_bh_delete(data->bh);
361
362 /* Prevent race with block_job_defer_to_main_loop() */
363 aio_context_acquire(data->aio_context);
364
365 /* Fetch BDS AioContext again, in case it has changed */
366 aio_context = bdrv_get_aio_context(data->job->bs);
367 aio_context_acquire(aio_context);
368
369 data->fn(data->job, data->opaque);
370
371 aio_context_release(aio_context);
372
373 aio_context_release(data->aio_context);
374
375 g_free(data);
376}
377
378void block_job_defer_to_main_loop(BlockJob *job,
379 BlockJobDeferToMainLoopFn *fn,
380 void *opaque)
381{
382 BlockJobDeferToMainLoopData *data = g_malloc(sizeof(*data));
383 data->job = job;
384 data->bh = qemu_bh_new(block_job_defer_to_main_loop_bh, data);
385 data->aio_context = bdrv_get_aio_context(job->bs);
386 data->fn = fn;
387 data->opaque = opaque;
388
389 qemu_bh_schedule(data->bh);
390}