diff --git a/block/stream.c b/block/stream.c index c32c98339a..3f5d773535 100644 --- a/block/stream.c +++ b/block/stream.c @@ -90,7 +90,7 @@ static int stream_prepare(Job *job) unfiltered_base = bdrv_skip_filters(base); bdrv_graph_rdunlock_main_loop(); - if (bdrv_cow_child(unfiltered_bs)) { + if (unfiltered_bs_cow) { const char *base_id = NULL, *base_fmt = NULL; if (unfiltered_base) { base_id = s->backing_file_str ?: unfiltered_base->filename; diff --git a/include/block/block_int-io.h b/include/block/block_int-io.h index 17547a2dab..4a7cf2b4fd 100644 --- a/include/block/block_int-io.h +++ b/include/block/block_int-io.h @@ -130,14 +130,15 @@ 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); +BdrvChild * GRAPH_RDLOCK bdrv_cow_child(BlockDriverState *bs); BdrvChild * GRAPH_RDLOCK bdrv_filter_child(BlockDriverState *bs); BdrvChild * GRAPH_RDLOCK bdrv_filter_or_cow_child(BlockDriverState *bs); BdrvChild * GRAPH_RDLOCK bdrv_primary_child(BlockDriverState *bs); BlockDriverState * GRAPH_RDLOCK bdrv_skip_filters(BlockDriverState *bs); BlockDriverState * GRAPH_RDLOCK bdrv_backing_chain_next(BlockDriverState *bs); -static inline BlockDriverState *bdrv_cow_bs(BlockDriverState *bs) +static inline BlockDriverState * GRAPH_RDLOCK +bdrv_cow_bs(BlockDriverState *bs) { IO_CODE(); return child_bs(bdrv_cow_child(bs)); diff --git a/qemu-img.c b/qemu-img.c index 33f3ab5fba..5a77f67719 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -3541,7 +3541,7 @@ static int img_rebase(int argc, char **argv) uint8_t *buf_old = NULL; uint8_t *buf_new = NULL; BlockDriverState *bs = NULL, *prefix_chain_bs = NULL; - BlockDriverState *unfiltered_bs; + BlockDriverState *unfiltered_bs, *unfiltered_bs_cow; BlockDriverInfo bdi = {0}; char *filename; const char *fmt, *cache, *src_cache, *out_basefmt, *out_baseimg; @@ -3675,6 +3675,7 @@ static int img_rebase(int argc, char **argv) bdrv_graph_rdlock_main_loop(); unfiltered_bs = bdrv_skip_filters(bs); + unfiltered_bs_cow = bdrv_cow_bs(unfiltered_bs); bdrv_graph_rdunlock_main_loop(); if (compress && !block_driver_can_compress(unfiltered_bs->drv)) { @@ -3710,7 +3711,11 @@ static int img_rebase(int argc, char **argv) /* For safe rebasing we need to compare old and new backing file */ if (!unsafe) { QDict *options = NULL; - BlockDriverState *base_bs = bdrv_cow_bs(unfiltered_bs); + BlockDriverState *base_bs; + + bdrv_graph_rdlock_main_loop(); + base_bs = bdrv_cow_bs(unfiltered_bs); + bdrv_graph_rdunlock_main_loop(); if (base_bs) { blk_old_backing = blk_new(qemu_get_aio_context(), @@ -3876,7 +3881,7 @@ static int img_rebase(int argc, char **argv) * If cluster wasn't changed since prefix_chain, we don't need * to take action */ - ret = bdrv_is_allocated_above(bdrv_cow_bs(unfiltered_bs), + ret = bdrv_is_allocated_above(unfiltered_bs_cow, prefix_chain_bs, false, offset, n, &n); if (ret < 0) {