block.c (83d0521a1e35989b0cb7235aef48455fedda3ca4) block.c (c282e1fdf7ec9659c7f320123be397477a359d01)
1/*
2 * QEMU System Emulator block driver
3 *
4 * Copyright (c) 2003 Fabrice Bellard
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights

--- 315 unchanged lines hidden (view full) ---

324 */
325 if (!bdrv->bdrv_aio_readv) {
326 /* add AIO emulation layer */
327 bdrv->bdrv_aio_readv = bdrv_aio_readv_em;
328 bdrv->bdrv_aio_writev = bdrv_aio_writev_em;
329 }
330 }
331
1/*
2 * QEMU System Emulator block driver
3 *
4 * Copyright (c) 2003 Fabrice Bellard
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights

--- 315 unchanged lines hidden (view full) ---

324 */
325 if (!bdrv->bdrv_aio_readv) {
326 /* add AIO emulation layer */
327 bdrv->bdrv_aio_readv = bdrv_aio_readv_em;
328 bdrv->bdrv_aio_writev = bdrv_aio_writev_em;
329 }
330 }
331
332 if (bdrv->bdrv_create) {
333 assert(!bdrv->bdrv_create2 && !bdrv->create_opts);
334 assert(!bdrv->bdrv_amend_options2);
335 } else if (bdrv->bdrv_create2) {
336 assert(!bdrv->bdrv_create && !bdrv->create_options);
337 assert(!bdrv->bdrv_amend_options);
338 }
339 QLIST_INSERT_HEAD(&bdrv_drivers, bdrv, list);
340}
341
342/* create a new block device (by default it is empty) */
343BlockDriverState *bdrv_new(const char *device_name, Error **errp)
344{
345 BlockDriverState *bs;
346 int i;

--- 79 unchanged lines hidden (view full) ---

426{
427 BlockDriver *drv = bdrv_find_format(format_name);
428 return drv && bdrv_is_whitelisted(drv, read_only) ? drv : NULL;
429}
430
431typedef struct CreateCo {
432 BlockDriver *drv;
433 char *filename;
332 QLIST_INSERT_HEAD(&bdrv_drivers, bdrv, list);
333}
334
335/* create a new block device (by default it is empty) */
336BlockDriverState *bdrv_new(const char *device_name, Error **errp)
337{
338 BlockDriverState *bs;
339 int i;

--- 79 unchanged lines hidden (view full) ---

419{
420 BlockDriver *drv = bdrv_find_format(format_name);
421 return drv && bdrv_is_whitelisted(drv, read_only) ? drv : NULL;
422}
423
424typedef struct CreateCo {
425 BlockDriver *drv;
426 char *filename;
434 QEMUOptionParameter *options;
435 QemuOpts *opts;
436 int ret;
437 Error *err;
438} CreateCo;
439
440static void coroutine_fn bdrv_create_co_entry(void *opaque)
441{
442 Error *local_err = NULL;
443 int ret;
444
445 CreateCo *cco = opaque;
446 assert(cco->drv);
427 QemuOpts *opts;
428 int ret;
429 Error *err;
430} CreateCo;
431
432static void coroutine_fn bdrv_create_co_entry(void *opaque)
433{
434 Error *local_err = NULL;
435 int ret;
436
437 CreateCo *cco = opaque;
438 assert(cco->drv);
447 assert(!(cco->options && cco->opts));
448
439
449 if (cco->drv->bdrv_create2) {
450 QemuOptsList *opts_list = NULL;
451 if (cco->options) {
452 opts_list = params_to_opts(cco->options);
453 cco->opts = qemu_opts_create(opts_list, NULL, 0, &error_abort);
454 }
455 ret = cco->drv->bdrv_create2(cco->filename, cco->opts, &local_err);
456 if (cco->options) {
457 qemu_opts_del(cco->opts);
458 qemu_opts_free(opts_list);
459 }
460 } else {
461 if (cco->opts) {
462 cco->options = opts_to_params(cco->opts);
463 }
464 ret = cco->drv->bdrv_create(cco->filename, cco->options, &local_err);
465 if (cco->opts) {
466 free_option_parameters(cco->options);
467 }
468 }
440 ret = cco->drv->bdrv_create(cco->filename, cco->opts, &local_err);
469 if (local_err) {
470 error_propagate(&cco->err, local_err);
471 }
472 cco->ret = ret;
473}
474
475int bdrv_create(BlockDriver *drv, const char* filename,
441 if (local_err) {
442 error_propagate(&cco->err, local_err);
443 }
444 cco->ret = ret;
445}
446
447int bdrv_create(BlockDriver *drv, const char* filename,
476 QEMUOptionParameter *options,
477 QemuOpts *opts, Error **errp)
478{
479 int ret;
480
481 Coroutine *co;
482 CreateCo cco = {
483 .drv = drv,
484 .filename = g_strdup(filename),
448 QemuOpts *opts, Error **errp)
449{
450 int ret;
451
452 Coroutine *co;
453 CreateCo cco = {
454 .drv = drv,
455 .filename = g_strdup(filename),
485 .options = options,
486 .opts = opts,
487 .ret = NOT_DONE,
488 .err = NULL,
489 };
490
456 .opts = opts,
457 .ret = NOT_DONE,
458 .err = NULL,
459 };
460
491 if (!drv->bdrv_create && !drv->bdrv_create2) {
461 if (!drv->bdrv_create) {
492 error_setg(errp, "Driver '%s' does not support image creation", drv->format_name);
493 ret = -ENOTSUP;
494 goto out;
495 }
496
497 if (qemu_in_coroutine()) {
498 /* Fast-path if already in coroutine context */
499 bdrv_create_co_entry(&cco);

--- 14 unchanged lines hidden (view full) ---

514 }
515 }
516
517out:
518 g_free(cco.filename);
519 return ret;
520}
521
462 error_setg(errp, "Driver '%s' does not support image creation", drv->format_name);
463 ret = -ENOTSUP;
464 goto out;
465 }
466
467 if (qemu_in_coroutine()) {
468 /* Fast-path if already in coroutine context */
469 bdrv_create_co_entry(&cco);

--- 14 unchanged lines hidden (view full) ---

484 }
485 }
486
487out:
488 g_free(cco.filename);
489 return ret;
490}
491
522int bdrv_create_file(const char* filename, QEMUOptionParameter *options,
523 QemuOpts *opts, Error **errp)
492int bdrv_create_file(const char *filename, QemuOpts *opts, Error **errp)
524{
525 BlockDriver *drv;
526 Error *local_err = NULL;
527 int ret;
528
529 drv = bdrv_find_protocol(filename, true);
530 if (drv == NULL) {
531 error_setg(errp, "Could not find protocol for file '%s'", filename);
532 return -ENOENT;
533 }
534
493{
494 BlockDriver *drv;
495 Error *local_err = NULL;
496 int ret;
497
498 drv = bdrv_find_protocol(filename, true);
499 if (drv == NULL) {
500 error_setg(errp, "Could not find protocol for file '%s'", filename);
501 return -ENOENT;
502 }
503
535 ret = bdrv_create(drv, filename, options, opts, &local_err);
504 ret = bdrv_create(drv, filename, opts, &local_err);
536 if (local_err) {
537 error_propagate(errp, local_err);
538 }
539 return ret;
540}
541
542int bdrv_refresh_limits(BlockDriverState *bs)
543{

--- 728 unchanged lines hidden (view full) ---

1272}
1273
1274void bdrv_append_temp_snapshot(BlockDriverState *bs, int flags, Error **errp)
1275{
1276 /* TODO: extra byte is a hack to ensure MAX_PATH space on Windows. */
1277 char *tmp_filename = g_malloc0(PATH_MAX + 1);
1278 int64_t total_size;
1279 BlockDriver *bdrv_qcow2;
505 if (local_err) {
506 error_propagate(errp, local_err);
507 }
508 return ret;
509}
510
511int bdrv_refresh_limits(BlockDriverState *bs)
512{

--- 728 unchanged lines hidden (view full) ---

1241}
1242
1243void bdrv_append_temp_snapshot(BlockDriverState *bs, int flags, Error **errp)
1244{
1245 /* TODO: extra byte is a hack to ensure MAX_PATH space on Windows. */
1246 char *tmp_filename = g_malloc0(PATH_MAX + 1);
1247 int64_t total_size;
1248 BlockDriver *bdrv_qcow2;
1280 QemuOptsList *create_opts = NULL;
1281 QemuOpts *opts = NULL;
1282 QDict *snapshot_options;
1283 BlockDriverState *bs_snapshot;
1284 Error *local_err;
1285 int ret;
1286
1287 /* if snapshot, we create a temporary backing file and open it
1288 instead of opening 'filename' directly */

--- 9 unchanged lines hidden (view full) ---

1298 /* Create the temporary image */
1299 ret = get_tmp_filename(tmp_filename, PATH_MAX + 1);
1300 if (ret < 0) {
1301 error_setg_errno(errp, -ret, "Could not get temporary filename");
1302 goto out;
1303 }
1304
1305 bdrv_qcow2 = bdrv_find_format("qcow2");
1249 QemuOpts *opts = NULL;
1250 QDict *snapshot_options;
1251 BlockDriverState *bs_snapshot;
1252 Error *local_err;
1253 int ret;
1254
1255 /* if snapshot, we create a temporary backing file and open it
1256 instead of opening 'filename' directly */

--- 9 unchanged lines hidden (view full) ---

1266 /* Create the temporary image */
1267 ret = get_tmp_filename(tmp_filename, PATH_MAX + 1);
1268 if (ret < 0) {
1269 error_setg_errno(errp, -ret, "Could not get temporary filename");
1270 goto out;
1271 }
1272
1273 bdrv_qcow2 = bdrv_find_format("qcow2");
1306
1307 assert(!(bdrv_qcow2->create_options && bdrv_qcow2->create_opts));
1308 if (bdrv_qcow2->create_options) {
1309 create_opts = params_to_opts(bdrv_qcow2->create_options);
1310 } else {
1311 create_opts = bdrv_qcow2->create_opts;
1312 }
1313 opts = qemu_opts_create(create_opts, NULL, 0, &error_abort);
1274 opts = qemu_opts_create(bdrv_qcow2->create_opts, NULL, 0,
1275 &error_abort);
1314 qemu_opt_set_number(opts, BLOCK_OPT_SIZE, total_size);
1276 qemu_opt_set_number(opts, BLOCK_OPT_SIZE, total_size);
1315 ret = bdrv_create(bdrv_qcow2, tmp_filename, NULL, opts, &local_err);
1277 ret = bdrv_create(bdrv_qcow2, tmp_filename, opts, &local_err);
1316 qemu_opts_del(opts);
1278 qemu_opts_del(opts);
1317 if (bdrv_qcow2->create_options) {
1318 qemu_opts_free(create_opts);
1319 }
1320 if (ret < 0) {
1321 error_setg_errno(errp, -ret, "Could not create temporary overlay "
1322 "'%s': %s", tmp_filename,
1323 error_get_pretty(local_err));
1324 error_free(local_err);
1325 goto out;
1326 }
1327

--- 4246 unchanged lines hidden (view full) ---

5574 }
5575
5576 proto_drv = bdrv_find_protocol(filename, true);
5577 if (!proto_drv) {
5578 error_setg(errp, "Unknown protocol '%s'", filename);
5579 return;
5580 }
5581
1279 if (ret < 0) {
1280 error_setg_errno(errp, -ret, "Could not create temporary overlay "
1281 "'%s': %s", tmp_filename,
1282 error_get_pretty(local_err));
1283 error_free(local_err);
1284 goto out;
1285 }
1286

--- 4246 unchanged lines hidden (view full) ---

5533 }
5534
5535 proto_drv = bdrv_find_protocol(filename, true);
5536 if (!proto_drv) {
5537 error_setg(errp, "Unknown protocol '%s'", filename);
5538 return;
5539 }
5540
5582 create_opts = qemu_opts_append(create_opts, drv->create_opts,
5583 drv->create_options);
5584 create_opts = qemu_opts_append(create_opts, proto_drv->create_opts,
5585 proto_drv->create_options);
5541 create_opts = qemu_opts_append(create_opts, drv->create_opts);
5542 create_opts = qemu_opts_append(create_opts, proto_drv->create_opts);
5586
5587 /* Create parameter list with default values */
5588 opts = qemu_opts_create(create_opts, NULL, 0, &error_abort);
5589 qemu_opt_set_number(opts, BLOCK_OPT_SIZE, img_size);
5590
5591 /* Parse -o options */
5592 if (options) {
5593 if (qemu_opts_do_parse(opts, options, NULL) != 0) {

--- 76 unchanged lines hidden (view full) ---

5670 }
5671
5672 if (!quiet) {
5673 printf("Formatting '%s', fmt=%s ", filename, fmt);
5674 qemu_opts_print(opts);
5675 puts("");
5676 }
5677
5543
5544 /* Create parameter list with default values */
5545 opts = qemu_opts_create(create_opts, NULL, 0, &error_abort);
5546 qemu_opt_set_number(opts, BLOCK_OPT_SIZE, img_size);
5547
5548 /* Parse -o options */
5549 if (options) {
5550 if (qemu_opts_do_parse(opts, options, NULL) != 0) {

--- 76 unchanged lines hidden (view full) ---

5627 }
5628
5629 if (!quiet) {
5630 printf("Formatting '%s', fmt=%s ", filename, fmt);
5631 qemu_opts_print(opts);
5632 puts("");
5633 }
5634
5678 ret = bdrv_create(drv, filename, NULL, opts, &local_err);
5635 ret = bdrv_create(drv, filename, opts, &local_err);
5679
5680 if (ret == -EFBIG) {
5681 /* This is generally a better message than whatever the driver would
5682 * deliver (especially because of the cluster_size_hint), since that
5683 * is most probably not much different from "image too large". */
5684 const char *cluster_size_hint = "";
5685 if (qemu_opt_get_size(opts, BLOCK_OPT_CLUSTER_SIZE, 0)) {
5686 cluster_size_hint = " (try using a larger cluster size)";

--- 77 unchanged lines hidden (view full) ---

5764}
5765
5766void bdrv_add_before_write_notifier(BlockDriverState *bs,
5767 NotifierWithReturn *notifier)
5768{
5769 notifier_with_return_list_add(&bs->before_write_notifiers, notifier);
5770}
5771
5636
5637 if (ret == -EFBIG) {
5638 /* This is generally a better message than whatever the driver would
5639 * deliver (especially because of the cluster_size_hint), since that
5640 * is most probably not much different from "image too large". */
5641 const char *cluster_size_hint = "";
5642 if (qemu_opt_get_size(opts, BLOCK_OPT_CLUSTER_SIZE, 0)) {
5643 cluster_size_hint = " (try using a larger cluster size)";

--- 77 unchanged lines hidden (view full) ---

5721}
5722
5723void bdrv_add_before_write_notifier(BlockDriverState *bs,
5724 NotifierWithReturn *notifier)
5725{
5726 notifier_with_return_list_add(&bs->before_write_notifiers, notifier);
5727}
5728
5772int bdrv_amend_options(BlockDriverState *bs, QEMUOptionParameter *options,
5773 QemuOpts *opts)
5729int bdrv_amend_options(BlockDriverState *bs, QemuOpts *opts)
5774{
5730{
5775 int ret;
5776 assert(!(options && opts));
5777
5778 if (!bs->drv->bdrv_amend_options && !bs->drv->bdrv_amend_options2) {
5731 if (!bs->drv->bdrv_amend_options) {
5779 return -ENOTSUP;
5780 }
5732 return -ENOTSUP;
5733 }
5781 if (bs->drv->bdrv_amend_options2) {
5782 QemuOptsList *opts_list = NULL;
5783 if (options) {
5784 opts_list = params_to_opts(options);
5785 opts = qemu_opts_create(opts_list, NULL, 0, &error_abort);
5786 }
5787 ret = bs->drv->bdrv_amend_options2(bs, opts);
5788 if (options) {
5789 qemu_opts_del(opts);
5790 qemu_opts_free(opts_list);
5791 }
5792 } else {
5793 if (opts) {
5794 options = opts_to_params(opts);
5795 }
5796 ret = bs->drv->bdrv_amend_options(bs, options);
5797 if (opts) {
5798 free_option_parameters(options);
5799 }
5800 }
5801 return ret;
5734 return bs->drv->bdrv_amend_options(bs, opts);
5802}
5803
5804/* This function will be called by the bdrv_recurse_is_first_non_filter method
5805 * of block filter and by bdrv_is_first_non_filter.
5806 * It is used to test if the given bs is the candidate or recurse more in the
5807 * node graph.
5808 */
5809bool bdrv_recurse_is_first_non_filter(BlockDriverState *bs,

--- 50 unchanged lines hidden ---
5735}
5736
5737/* This function will be called by the bdrv_recurse_is_first_non_filter method
5738 * of block filter and by bdrv_is_first_non_filter.
5739 * It is used to test if the given bs is the candidate or recurse more in the
5740 * node graph.
5741 */
5742bool bdrv_recurse_is_first_non_filter(BlockDriverState *bs,

--- 50 unchanged lines hidden ---