Move bdrv_drain_all(), bdrv_commit_all(), bdrv_flush_all() and bdrv_invalidate_cache_all() to BB.
The only operation left is bdrv_close_all(), which cannot be moved to the BB because it should not only close all BBs, but also all monitor-owned BDSs. Signed-off-by: Max Reitz <mre...@redhat.com> --- block.c | 97 -------------------------------------------- block/block-backend.c | 104 ++++++++++++++++++++++++++++++++++++++++++------ include/block/block.h | 4 -- stubs/Makefile.objs | 2 +- stubs/bdrv-commit-all.c | 7 ---- stubs/blk-commit-all.c | 7 ++++ 6 files changed, 100 insertions(+), 121 deletions(-) delete mode 100644 stubs/bdrv-commit-all.c create mode 100644 stubs/blk-commit-all.c diff --git a/block.c b/block.c index d4a3c79..00fe705 100644 --- a/block.c +++ b/block.c @@ -1976,37 +1976,6 @@ void bdrv_drain(BlockDriverState *bs) } } -/* - * Wait for pending requests to complete across all BlockDriverStates - * - * This function does not flush data to disk, use bdrv_flush_all() for that - * after calling this function. - * - * Note that completion of an asynchronous I/O operation can trigger any - * number of other I/O operations on other devices---for example a coroutine - * can be arbitrarily complex and a constant flow of I/O can come until the - * coroutine is complete. Because of this, it is not possible to have a - * function to drain a single device's I/O queue. - */ -void bdrv_drain_all(void) -{ - /* Always run first iteration so any pending completion BHs run */ - bool busy = true; - BlockDriverState *bs; - - while (busy) { - busy = false; - - QTAILQ_FOREACH(bs, &bdrv_states, device_list) { - AioContext *aio_context = bdrv_get_aio_context(bs); - - aio_context_acquire(aio_context); - busy |= bdrv_drain_one(bs); - aio_context_release(aio_context); - } - } -} - /* make a BlockDriverState anonymous by removing from bdrv_state and * graph_bdrv_state list. Also, NULL terminate the device_name to prevent double remove */ @@ -2299,26 +2268,6 @@ ro_cleanup: return ret; } -int bdrv_commit_all(void) -{ - BlockDriverState *bs; - - QTAILQ_FOREACH(bs, &bdrv_states, device_list) { - AioContext *aio_context = bdrv_get_aio_context(bs); - - aio_context_acquire(aio_context); - if (bs->drv && bs->backing_hd) { - int ret = bdrv_commit(bs); - if (ret < 0) { - aio_context_release(aio_context); - return ret; - } - } - aio_context_release(aio_context); - } - return 0; -} - /** * Remove an active request from the tracked requests list * @@ -3765,14 +3714,6 @@ BlockDriverState *bdrv_next_node(BlockDriverState *bs) return QTAILQ_NEXT(bs, node_list); } -BlockDriverState *bdrv_next(BlockDriverState *bs) -{ - if (!bs) { - return QTAILQ_FIRST(&bdrv_states); - } - return QTAILQ_NEXT(bs, device_list); -} - const char *bdrv_get_node_name(const BlockDriverState *bs) { return bs->node_name; @@ -3789,26 +3730,6 @@ int bdrv_get_flags(BlockDriverState *bs) return bs->open_flags; } -int bdrv_flush_all(void) -{ - BlockDriverState *bs; - int result = 0; - - QTAILQ_FOREACH(bs, &bdrv_states, device_list) { - AioContext *aio_context = bdrv_get_aio_context(bs); - int ret; - - aio_context_acquire(aio_context); - ret = bdrv_flush(bs); - if (ret < 0 && !result) { - result = ret; - } - aio_context_release(aio_context); - } - - return result; -} - int bdrv_has_zero_init_1(BlockDriverState *bs) { return 1; @@ -4963,24 +4884,6 @@ void bdrv_invalidate_cache(BlockDriverState *bs, Error **errp) } } -void bdrv_invalidate_cache_all(Error **errp) -{ - BlockDriverState *bs; - Error *local_err = NULL; - - QTAILQ_FOREACH(bs, &bdrv_states, device_list) { - AioContext *aio_context = bdrv_get_aio_context(bs); - - aio_context_acquire(aio_context); - bdrv_invalidate_cache(bs, &local_err); - aio_context_release(aio_context); - if (local_err) { - error_propagate(errp, local_err); - return; - } - } -} - int bdrv_flush(BlockDriverState *bs) { Coroutine *co; diff --git a/block/block-backend.c b/block/block-backend.c index aeedabc..9a00645 100644 --- a/block/block-backend.c +++ b/block/block-backend.c @@ -367,6 +367,9 @@ void blk_remove_bs(BlockBackend *blk) assert(blk->bs->blk == blk); blk_update_root_state(blk); + /* After this function, the BDS may longer be accessible to blk_*_all() + * functions */ + blk_drain_all(); bdrv_unref(blk->bs); blk->bs->blk = NULL; @@ -883,16 +886,6 @@ int blk_flush(BlockBackend *blk) return bdrv_flush(blk->bs); } -int blk_flush_all(void) -{ - return bdrv_flush_all(); -} - -void blk_drain_all(void) -{ - bdrv_drain_all(); -} - void blk_set_on_error(BlockBackend *blk, BlockdevOnError on_read_error, BlockdevOnError on_write_error) { @@ -1238,12 +1231,99 @@ BlockBackendRootState *blk_get_root_state(BlockBackend *blk) return &blk->root_state; } +/* + * Wait for pending requests to complete across all BlockBackends + * + * This function does not flush data to disk, use blk_flush_all() for that + * after calling this function. + * + * Note that completion of an asynchronous I/O operation can trigger any + * number of other I/O operations on other devices---for example a coroutine + * can be arbitrarily complex and a constant flow of I/O can come until the + * coroutine is complete. Because of this, it is not possible to have a + * function to drain a single device's I/O queue. + */ +void blk_drain_all(void) +{ + /* Always run first iteration so any pending completion BHs run */ + bool busy = true; + BlockBackend *blk; + + while (busy) { + busy = false; + + QTAILQ_FOREACH(blk, &blk_backends, link) { + AioContext *aio_context = blk_get_aio_context(blk); + + if (!blk_is_inserted(blk)) { + continue; + } + + aio_context_acquire(aio_context); + busy |= bdrv_drain_one(blk->bs); + aio_context_release(aio_context); + } + } +} + int blk_commit_all(void) { - return bdrv_commit_all(); + BlockBackend *blk; + + QTAILQ_FOREACH(blk, &blk_backends, link) { + AioContext *aio_context = blk_get_aio_context(blk); + + aio_context_acquire(aio_context); + if (blk_is_available(blk) && blk->bs->drv && blk->bs->backing_hd) { + int ret = bdrv_commit(blk->bs); + if (ret < 0) { + aio_context_release(aio_context); + return ret; + } + } + aio_context_release(aio_context); + } + return 0; +} + +int blk_flush_all(void) +{ + BlockBackend *blk; + int result = 0; + + QTAILQ_FOREACH(blk, &blk_backends, link) { + AioContext *aio_context = blk_get_aio_context(blk); + int ret; + + aio_context_acquire(aio_context); + if (blk_is_inserted(blk)) { + ret = blk_flush(blk); + if (ret < 0 && !result) { + result = ret; + } + } + aio_context_release(aio_context); + } + + return result; } void blk_invalidate_cache_all(Error **errp) { - bdrv_invalidate_cache_all(errp); + BlockBackend *blk; + Error *local_err = NULL; + + QTAILQ_FOREACH(blk, &blk_backends, link) { + AioContext *aio_context = blk_get_aio_context(blk); + + aio_context_acquire(aio_context); + if (blk_is_inserted(blk)) { + blk_invalidate_cache(blk, &local_err); + } + aio_context_release(aio_context); + if (local_err) { + error_propagate(errp, local_err); + return; + } + } } diff --git a/include/block/block.h b/include/block/block.h index 6688920..1e1039f 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -235,7 +235,6 @@ int64_t bdrv_get_allocated_file_size(BlockDriverState *bs); void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr); void bdrv_refresh_limits(BlockDriverState *bs, Error **errp); int bdrv_commit(BlockDriverState *bs); -int bdrv_commit_all(void); int bdrv_change_backing_file(BlockDriverState *bs, const char *backing_file, const char *backing_fmt); void bdrv_register(BlockDriver *bdrv); @@ -321,15 +320,12 @@ BlockAIOCB *bdrv_aio_ioctl(BlockDriverState *bs, /* Invalidate any cached metadata used by image formats */ void bdrv_invalidate_cache(BlockDriverState *bs, Error **errp); -void bdrv_invalidate_cache_all(Error **errp); /* Ensure contents are flushed to disk. */ int bdrv_flush(BlockDriverState *bs); int coroutine_fn bdrv_co_flush(BlockDriverState *bs); -int bdrv_flush_all(void); void bdrv_close_all(void); void bdrv_drain(BlockDriverState *bs); -void bdrv_drain_all(void); int bdrv_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors); int bdrv_co_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors); diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs index 5e347d0..56eb2e8 100644 --- a/stubs/Makefile.objs +++ b/stubs/Makefile.objs @@ -1,5 +1,5 @@ stub-obj-y += arch-query-cpu-def.o -stub-obj-y += bdrv-commit-all.o +stub-obj-y += blk-commit-all.o stub-obj-y += chr-baum-init.o stub-obj-y += chr-msmouse.o stub-obj-y += chr-testdev.o diff --git a/stubs/bdrv-commit-all.c b/stubs/bdrv-commit-all.c deleted file mode 100644 index a8e0a95..0000000 --- a/stubs/bdrv-commit-all.c +++ /dev/null @@ -1,7 +0,0 @@ -#include "qemu-common.h" -#include "block/block.h" - -int bdrv_commit_all(void) -{ - return 0; -} diff --git a/stubs/blk-commit-all.c b/stubs/blk-commit-all.c new file mode 100644 index 0000000..90b59e5 --- /dev/null +++ b/stubs/blk-commit-all.c @@ -0,0 +1,7 @@ +#include "qemu-common.h" +#include "sysemu/block-backend.h" + +int blk_commit_all(void) +{ + return 0; +} -- 2.1.0