block-backend.c (191b5fbfa66e5b23e2150f3c6981d30eb84418a9) block-backend.c (5e003f17ec518cd96f5d2ac23ce9e14144426235)
1/*
2 * QEMU Block backends
3 *
4 * Copyright (C) 2014-2016 Red Hat, Inc.
5 *
6 * Authors:
7 * Markus Armbruster <armbru@redhat.com>,
8 *

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

437 return blk ? QTAILQ_NEXT(blk, monitor_link)
438 : QTAILQ_FIRST(&monitor_block_backends);
439}
440
441/* Iterates over all top-level BlockDriverStates, i.e. BDSs that are owned by
442 * the monitor or attached to a BlockBackend */
443BlockDriverState *bdrv_next(BdrvNextIterator *it)
444{
1/*
2 * QEMU Block backends
3 *
4 * Copyright (C) 2014-2016 Red Hat, Inc.
5 *
6 * Authors:
7 * Markus Armbruster <armbru@redhat.com>,
8 *

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

437 return blk ? QTAILQ_NEXT(blk, monitor_link)
438 : QTAILQ_FIRST(&monitor_block_backends);
439}
440
441/* Iterates over all top-level BlockDriverStates, i.e. BDSs that are owned by
442 * the monitor or attached to a BlockBackend */
443BlockDriverState *bdrv_next(BdrvNextIterator *it)
444{
445 BlockDriverState *bs;
445 BlockDriverState *bs, *old_bs;
446
446
447 /* Must be called from the main loop */
448 assert(qemu_get_current_aio_context() == qemu_get_aio_context());
449
447 /* First, return all root nodes of BlockBackends. In order to avoid
448 * returning a BDS twice when multiple BBs refer to it, we only return it
449 * if the BB is the first one in the parent list of the BDS. */
450 if (it->phase == BDRV_NEXT_BACKEND_ROOTS) {
450 /* First, return all root nodes of BlockBackends. In order to avoid
451 * returning a BDS twice when multiple BBs refer to it, we only return it
452 * if the BB is the first one in the parent list of the BDS. */
453 if (it->phase == BDRV_NEXT_BACKEND_ROOTS) {
454 BlockBackend *old_blk = it->blk;
455
456 old_bs = old_blk ? blk_bs(old_blk) : NULL;
457
451 do {
452 it->blk = blk_all_next(it->blk);
453 bs = it->blk ? blk_bs(it->blk) : NULL;
454 } while (it->blk && (bs == NULL || bdrv_first_blk(bs) != it->blk));
455
458 do {
459 it->blk = blk_all_next(it->blk);
460 bs = it->blk ? blk_bs(it->blk) : NULL;
461 } while (it->blk && (bs == NULL || bdrv_first_blk(bs) != it->blk));
462
463 if (it->blk) {
464 blk_ref(it->blk);
465 }
466 blk_unref(old_blk);
467
456 if (bs) {
468 if (bs) {
469 bdrv_ref(bs);
470 bdrv_unref(old_bs);
457 return bs;
458 }
459 it->phase = BDRV_NEXT_MONITOR_OWNED;
471 return bs;
472 }
473 it->phase = BDRV_NEXT_MONITOR_OWNED;
474 } else {
475 old_bs = it->bs;
460 }
461
462 /* Then return the monitor-owned BDSes without a BB attached. Ignore all
463 * BDSes that are attached to a BlockBackend here; they have been handled
464 * by the above block already */
465 do {
466 it->bs = bdrv_next_monitor_owned(it->bs);
467 bs = it->bs;
468 } while (bs && bdrv_has_blk(bs));
469
476 }
477
478 /* Then return the monitor-owned BDSes without a BB attached. Ignore all
479 * BDSes that are attached to a BlockBackend here; they have been handled
480 * by the above block already */
481 do {
482 it->bs = bdrv_next_monitor_owned(it->bs);
483 bs = it->bs;
484 } while (bs && bdrv_has_blk(bs));
485
486 if (bs) {
487 bdrv_ref(bs);
488 }
489 bdrv_unref(old_bs);
490
470 return bs;
471}
472
491 return bs;
492}
493
473BlockDriverState *bdrv_first(BdrvNextIterator *it)
494static void bdrv_next_reset(BdrvNextIterator *it)
474{
475 *it = (BdrvNextIterator) {
476 .phase = BDRV_NEXT_BACKEND_ROOTS,
477 };
495{
496 *it = (BdrvNextIterator) {
497 .phase = BDRV_NEXT_BACKEND_ROOTS,
498 };
499}
478
500
501BlockDriverState *bdrv_first(BdrvNextIterator *it)
502{
503 bdrv_next_reset(it);
479 return bdrv_next(it);
480}
481
504 return bdrv_next(it);
505}
506
507/* Must be called when aborting a bdrv_next() iteration before
508 * bdrv_next() returns NULL */
509void bdrv_next_cleanup(BdrvNextIterator *it)
510{
511 /* Must be called from the main loop */
512 assert(qemu_get_current_aio_context() == qemu_get_aio_context());
513
514 if (it->phase == BDRV_NEXT_BACKEND_ROOTS) {
515 if (it->blk) {
516 bdrv_unref(blk_bs(it->blk));
517 blk_unref(it->blk);
518 }
519 } else {
520 bdrv_unref(it->bs);
521 }
522
523 bdrv_next_reset(it);
524}
525
482/*
483 * Add a BlockBackend into the list of backends referenced by the monitor, with
484 * the given @name acting as the handle for the monitor.
485 * Strictly for use by blockdev.c.
486 *
487 * @name must not be null or empty.
488 *
489 * Returns true on success and false on failure. In the latter case, an Error

--- 1563 unchanged lines hidden ---
526/*
527 * Add a BlockBackend into the list of backends referenced by the monitor, with
528 * the given @name acting as the handle for the monitor.
529 * Strictly for use by blockdev.c.
530 *
531 * @name must not be null or empty.
532 *
533 * Returns true on success and false on failure. In the latter case, an Error

--- 1563 unchanged lines hidden ---