diff --git a/block.c b/block.c index c4c67d09d4..0dd604d0f6 100644 --- a/block.c +++ b/block.c @@ -1042,6 +1042,7 @@ int coroutine_fn bdrv_co_refresh_total_sectors(BlockDriverState *bs, { BlockDriver *drv = bs->drv; IO_CODE(); + assert_bdrv_graph_readable(); if (!drv) { return -ENOMEDIUM; @@ -5843,6 +5844,7 @@ int64_t coroutine_fn bdrv_co_nb_sectors(BlockDriverState *bs) { BlockDriver *drv = bs->drv; IO_CODE(); + assert_bdrv_graph_readable(); if (!drv) return -ENOMEDIUM; @@ -5864,6 +5866,7 @@ int64_t coroutine_fn bdrv_co_getlength(BlockDriverState *bs) { int64_t ret; IO_CODE(); + assert_bdrv_graph_readable(); ret = bdrv_co_nb_sectors(bs); if (ret < 0) { diff --git a/block/blkdebug.c b/block/blkdebug.c index f418a90873..978c8cff9e 100644 --- a/block/blkdebug.c +++ b/block/blkdebug.c @@ -967,7 +967,8 @@ static bool blkdebug_debug_is_suspended(BlockDriverState *bs, const char *tag) return false; } -static int64_t coroutine_fn blkdebug_co_getlength(BlockDriverState *bs) +static int64_t coroutine_fn GRAPH_RDLOCK +blkdebug_co_getlength(BlockDriverState *bs) { return bdrv_co_getlength(bs->file->bs); } diff --git a/block/blklogwrites.c b/block/blklogwrites.c index 93086c31e1..3ea7141cb5 100644 --- a/block/blklogwrites.c +++ b/block/blklogwrites.c @@ -267,7 +267,8 @@ static void blk_log_writes_close(BlockDriverState *bs) s->log_file = NULL; } -static int64_t coroutine_fn blk_log_writes_co_getlength(BlockDriverState *bs) +static int64_t coroutine_fn GRAPH_RDLOCK +blk_log_writes_co_getlength(BlockDriverState *bs) { return bdrv_co_getlength(bs->file->bs); } diff --git a/block/blkreplay.c b/block/blkreplay.c index bc96bbd41e..04f53eea41 100644 --- a/block/blkreplay.c +++ b/block/blkreplay.c @@ -40,7 +40,8 @@ fail: return ret; } -static int64_t coroutine_fn blkreplay_co_getlength(BlockDriverState *bs) +static int64_t coroutine_fn GRAPH_RDLOCK +blkreplay_co_getlength(BlockDriverState *bs) { return bdrv_co_getlength(bs->file->bs); } diff --git a/block/blkverify.c b/block/blkverify.c index 8c11c2eae4..1c16f86b2e 100644 --- a/block/blkverify.c +++ b/block/blkverify.c @@ -155,7 +155,8 @@ static void blkverify_close(BlockDriverState *bs) s->test_file = NULL; } -static int64_t coroutine_fn blkverify_co_getlength(BlockDriverState *bs) +static int64_t coroutine_fn GRAPH_RDLOCK +blkverify_co_getlength(BlockDriverState *bs) { BDRVBlkverifyState *s = bs->opaque; diff --git a/block/copy-on-read.c b/block/copy-on-read.c index 20215cff93..cc0f848b0f 100644 --- a/block/copy-on-read.c +++ b/block/copy-on-read.c @@ -121,7 +121,7 @@ static void cor_child_perm(BlockDriverState *bs, BdrvChild *c, } -static int64_t coroutine_fn cor_co_getlength(BlockDriverState *bs) +static int64_t coroutine_fn GRAPH_RDLOCK cor_co_getlength(BlockDriverState *bs) { return bdrv_co_getlength(bs->file->bs); } diff --git a/block/crypto.c b/block/crypto.c index e77790ac8a..ca67289187 100644 --- a/block/crypto.c +++ b/block/crypto.c @@ -530,7 +530,8 @@ static void block_crypto_refresh_limits(BlockDriverState *bs, Error **errp) } -static int64_t coroutine_fn block_crypto_co_getlength(BlockDriverState *bs) +static int64_t coroutine_fn GRAPH_RDLOCK +block_crypto_co_getlength(BlockDriverState *bs) { BlockCrypto *crypto = bs->opaque; int64_t len = bdrv_co_getlength(bs->file->bs); diff --git a/block/filter-compress.c b/block/filter-compress.c index c7d50a67a7..ac285f4b66 100644 --- a/block/filter-compress.c +++ b/block/filter-compress.c @@ -55,7 +55,8 @@ static int compress_open(BlockDriverState *bs, QDict *options, int flags, } -static int64_t coroutine_fn compress_co_getlength(BlockDriverState *bs) +static int64_t coroutine_fn GRAPH_RDLOCK +compress_co_getlength(BlockDriverState *bs) { return bdrv_co_getlength(bs->file->bs); } diff --git a/block/mirror.c b/block/mirror.c index ec5cd22a7c..97c6a5777d 100644 --- a/block/mirror.c +++ b/block/mirror.c @@ -917,7 +917,10 @@ static int coroutine_fn mirror_run(Job *job, Error **errp) goto immediate_exit; } + bdrv_graph_co_rdlock(); s->bdev_length = bdrv_co_getlength(bs); + bdrv_graph_co_rdunlock(); + if (s->bdev_length < 0) { ret = s->bdev_length; goto immediate_exit; diff --git a/block/preallocate.c b/block/preallocate.c index 63a296882d..71c3601809 100644 --- a/block/preallocate.c +++ b/block/preallocate.c @@ -443,7 +443,8 @@ static int coroutine_fn GRAPH_RDLOCK preallocate_co_flush(BlockDriverState *bs) return bdrv_co_flush(bs->file->bs); } -static int64_t coroutine_fn preallocate_co_getlength(BlockDriverState *bs) +static int64_t coroutine_fn GRAPH_RDLOCK +preallocate_co_getlength(BlockDriverState *bs) { int64_t ret; BDRVPreallocateState *s = bs->opaque; diff --git a/block/quorum.c b/block/quorum.c index d58f86d3a5..ff5a0a2da3 100644 --- a/block/quorum.c +++ b/block/quorum.c @@ -764,7 +764,8 @@ quorum_co_pwrite_zeroes(BlockDriverState *bs, int64_t offset, int64_t bytes, flags | BDRV_REQ_ZERO_WRITE); } -static int64_t coroutine_fn quorum_co_getlength(BlockDriverState *bs) +static int64_t coroutine_fn GRAPH_RDLOCK +quorum_co_getlength(BlockDriverState *bs) { BDRVQuorumState *s = bs->opaque; int64_t result; diff --git a/block/raw-format.c b/block/raw-format.c index f4203d4806..66783ed8e7 100644 --- a/block/raw-format.c +++ b/block/raw-format.c @@ -317,7 +317,8 @@ raw_co_pdiscard(BlockDriverState *bs, int64_t offset, int64_t bytes) return bdrv_co_pdiscard(bs->file, offset, bytes); } -static int64_t coroutine_fn raw_co_getlength(BlockDriverState *bs) +static int64_t coroutine_fn GRAPH_RDLOCK +raw_co_getlength(BlockDriverState *bs) { int64_t len; BDRVRawState *s = bs->opaque; diff --git a/block/replication.c b/block/replication.c index f9f899bfc8..de01f96184 100644 --- a/block/replication.c +++ b/block/replication.c @@ -179,7 +179,8 @@ static void replication_child_perm(BlockDriverState *bs, BdrvChild *c, return; } -static int64_t coroutine_fn replication_co_getlength(BlockDriverState *bs) +static int64_t coroutine_fn GRAPH_RDLOCK +replication_co_getlength(BlockDriverState *bs) { return bdrv_co_getlength(bs->file->bs); } diff --git a/block/stream.c b/block/stream.c index 22368ce186..68018699de 100644 --- a/block/stream.c +++ b/block/stream.c @@ -141,9 +141,11 @@ static int coroutine_fn stream_run(Job *job, Error **errp) return 0; } - len = bdrv_getlength(s->target_bs); - if (len < 0) { - return len; + WITH_GRAPH_RDLOCK_GUARD() { + len = bdrv_co_getlength(s->target_bs); + if (len < 0) { + return len; + } } job_progress_set_remaining(&s->common.job, len); diff --git a/block/throttle.c b/block/throttle.c index 5cfea3d5f8..3aaef18d4e 100644 --- a/block/throttle.c +++ b/block/throttle.c @@ -106,7 +106,8 @@ static void throttle_close(BlockDriverState *bs) } -static int64_t coroutine_fn throttle_co_getlength(BlockDriverState *bs) +static int64_t coroutine_fn GRAPH_RDLOCK +throttle_co_getlength(BlockDriverState *bs) { return bdrv_co_getlength(bs->file->bs); } diff --git a/include/block/block-io.h b/include/block/block-io.h index 95bcc79b75..5da99d4d60 100644 --- a/include/block/block-io.h +++ b/include/block/block-io.h @@ -78,11 +78,11 @@ int coroutine_fn GRAPH_RDLOCK bdrv_co_truncate(BdrvChild *child, int64_t offset, bool exact, PreallocMode prealloc, BdrvRequestFlags flags, Error **errp); -int64_t coroutine_fn bdrv_co_nb_sectors(BlockDriverState *bs); -int64_t co_wrapper_mixed bdrv_nb_sectors(BlockDriverState *bs); +int64_t coroutine_fn GRAPH_RDLOCK bdrv_co_nb_sectors(BlockDriverState *bs); +int64_t co_wrapper_mixed_bdrv_rdlock bdrv_nb_sectors(BlockDriverState *bs); -int64_t coroutine_fn bdrv_co_getlength(BlockDriverState *bs); -int64_t co_wrapper_mixed bdrv_getlength(BlockDriverState *bs); +int64_t coroutine_fn GRAPH_RDLOCK bdrv_co_getlength(BlockDriverState *bs); +int64_t co_wrapper_mixed_bdrv_rdlock bdrv_getlength(BlockDriverState *bs); int64_t coroutine_fn bdrv_co_get_allocated_file_size(BlockDriverState *bs); int64_t co_wrapper bdrv_get_allocated_file_size(BlockDriverState *bs); diff --git a/include/block/block_int-common.h b/include/block/block_int-common.h index d72e31aba3..d419017328 100644 --- a/include/block/block_int-common.h +++ b/include/block/block_int-common.h @@ -684,7 +684,9 @@ struct BlockDriver { BlockDriverState *bs, int64_t offset, bool exact, PreallocMode prealloc, BdrvRequestFlags flags, Error **errp); - int64_t coroutine_fn (*bdrv_co_getlength)(BlockDriverState *bs); + int64_t coroutine_fn GRAPH_RDLOCK_PTR (*bdrv_co_getlength)( + BlockDriverState *bs); + int64_t coroutine_fn (*bdrv_co_get_allocated_file_size)( BlockDriverState *bs); diff --git a/include/block/block_int-io.h b/include/block/block_int-io.h index 612e5ddf99..eb0da7232e 100644 --- a/include/block/block_int-io.h +++ b/include/block/block_int-io.h @@ -124,9 +124,10 @@ bdrv_co_copy_range_to(BdrvChild *src, int64_t src_offset, int64_t bytes, BdrvRequestFlags read_flags, BdrvRequestFlags write_flags); -int coroutine_fn bdrv_co_refresh_total_sectors(BlockDriverState *bs, - int64_t hint); -int co_wrapper_mixed +int coroutine_fn GRAPH_RDLOCK +bdrv_co_refresh_total_sectors(BlockDriverState *bs, int64_t hint); + +int co_wrapper_mixed_bdrv_rdlock bdrv_refresh_total_sectors(BlockDriverState *bs, int64_t hint); BdrvChild *bdrv_cow_child(BlockDriverState *bs);