@@ -2631,6 +2631,8 @@ int coroutine_fn blk_co_copy_range(BlockBackend *blk_in, int64_t off_in,
if (r) {
return r;
}
+
+ GRAPH_RDLOCK_GUARD();
return bdrv_co_copy_range(blk_in->root, off_in,
blk_out->root, off_out,
bytes, read_flags, write_flags);
@@ -3165,6 +3165,7 @@ static int coroutine_fn bdrv_co_copy_range_internal(
{
BdrvTrackedRequest req;
int ret;
+ assert_bdrv_graph_readable();
/* TODO We can support BDRV_REQ_NO_FALLBACK here */
assert(!(read_flags & BDRV_REQ_NO_FALLBACK));
@@ -3246,6 +3247,7 @@ int coroutine_fn bdrv_co_copy_range_from(BdrvChild *src, int64_t src_offset,
BdrvRequestFlags write_flags)
{
IO_CODE();
+ assert_bdrv_graph_readable();
trace_bdrv_co_copy_range_from(src, src_offset, dst, dst_offset, bytes,
read_flags, write_flags);
return bdrv_co_copy_range_internal(src, src_offset, dst, dst_offset,
@@ -3263,6 +3265,7 @@ int coroutine_fn bdrv_co_copy_range_to(BdrvChild *src, int64_t src_offset,
BdrvRequestFlags write_flags)
{
IO_CODE();
+ assert_bdrv_graph_readable();
trace_bdrv_co_copy_range_to(src, src_offset, dst, dst_offset, bytes,
read_flags, write_flags);
return bdrv_co_copy_range_internal(src, src_offset, dst, dst_offset,
@@ -3275,6 +3278,8 @@ int coroutine_fn bdrv_co_copy_range(BdrvChild *src, int64_t src_offset,
BdrvRequestFlags write_flags)
{
IO_CODE();
+ assert_bdrv_graph_readable();
+
return bdrv_co_copy_range_from(src, src_offset,
dst, dst_offset,
bytes, read_flags, write_flags);
@@ -574,6 +574,8 @@ struct BlockDriver {
*
* See the comment of bdrv_co_copy_range for the parameter and return value
* semantics.
+ *
+ * Called with graph rdlock taken.
*/
int coroutine_fn (*bdrv_co_copy_range_from)(BlockDriverState *bs,
BdrvChild *src,
@@ -592,6 +594,8 @@ struct BlockDriver {
*
* See the comment of bdrv_co_copy_range for the parameter and return value
* semantics.
+ *
+ * Called with graph rdlock taken.
*/
int coroutine_fn (*bdrv_co_copy_range_to)(BlockDriverState *bs,
BdrvChild *src,
@@ -2027,7 +2027,9 @@ retry:
if (s->ret == -EINPROGRESS) {
if (copy_range) {
- ret = convert_co_copy_range(s, sector_num, n);
+ WITH_GRAPH_RDLOCK_GUARD() {
+ ret = convert_co_copy_range(s, sector_num, n);
+ }
if (ret) {
s->copy_range = false;
goto retry;
The only non-protected caller is convert_co_copy_range(), all other callers are BlockDriver callbacks that already take the rdlock. Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com> --- block/block-backend.c | 2 ++ block/io.c | 5 +++++ include/block/block_int-common.h | 4 ++++ qemu-img.c | 4 +++- 4 files changed, 14 insertions(+), 1 deletion(-)