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 --- |