block: Move request tracking to children in copy offloading
in_flight and tracked requests need to be tracked in every layer during recursion. For now the only user is qemu-img convert where overlapping requests and IOThreads don't exist, therefore this change doesn't make much difference form user point of view, but it is incorrect as part of the API. Fix it. Reported-by: Kevin Wolf <kwolf@redhat.com> Signed-off-by: Fam Zheng <famz@redhat.com> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
354d930dc6
commit
37aec7d75e
59
block/io.c
59
block/io.c
@ -2932,6 +2932,9 @@ static int coroutine_fn bdrv_co_copy_range_internal(BdrvChild *src,
|
|||||||
BdrvRequestFlags flags,
|
BdrvRequestFlags flags,
|
||||||
bool recurse_src)
|
bool recurse_src)
|
||||||
{
|
{
|
||||||
|
BdrvTrackedRequest src_req, dst_req;
|
||||||
|
BlockDriverState *src_bs = src->bs;
|
||||||
|
BlockDriverState *dst_bs = dst->bs;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!src || !dst || !src->bs || !dst->bs) {
|
if (!src || !dst || !src->bs || !dst->bs) {
|
||||||
@ -2955,17 +2958,31 @@ static int coroutine_fn bdrv_co_copy_range_internal(BdrvChild *src,
|
|||||||
|| src->bs->encrypted || dst->bs->encrypted) {
|
|| src->bs->encrypted || dst->bs->encrypted) {
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
}
|
}
|
||||||
|
bdrv_inc_in_flight(src_bs);
|
||||||
|
bdrv_inc_in_flight(dst_bs);
|
||||||
|
tracked_request_begin(&src_req, src_bs, src_offset,
|
||||||
|
bytes, BDRV_TRACKED_READ);
|
||||||
|
tracked_request_begin(&dst_req, dst_bs, dst_offset,
|
||||||
|
bytes, BDRV_TRACKED_WRITE);
|
||||||
|
|
||||||
|
wait_serialising_requests(&src_req);
|
||||||
|
wait_serialising_requests(&dst_req);
|
||||||
if (recurse_src) {
|
if (recurse_src) {
|
||||||
return src->bs->drv->bdrv_co_copy_range_from(src->bs,
|
ret = src->bs->drv->bdrv_co_copy_range_from(src->bs,
|
||||||
src, src_offset,
|
src, src_offset,
|
||||||
dst, dst_offset,
|
dst, dst_offset,
|
||||||
bytes, flags);
|
bytes, flags);
|
||||||
} else {
|
} else {
|
||||||
return dst->bs->drv->bdrv_co_copy_range_to(dst->bs,
|
ret = dst->bs->drv->bdrv_co_copy_range_to(dst->bs,
|
||||||
src, src_offset,
|
src, src_offset,
|
||||||
dst, dst_offset,
|
dst, dst_offset,
|
||||||
bytes, flags);
|
bytes, flags);
|
||||||
}
|
}
|
||||||
|
tracked_request_end(&src_req);
|
||||||
|
tracked_request_end(&dst_req);
|
||||||
|
bdrv_dec_in_flight(src_bs);
|
||||||
|
bdrv_dec_in_flight(dst_bs);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copy range from @src to @dst.
|
/* Copy range from @src to @dst.
|
||||||
@ -2996,29 +3013,9 @@ int coroutine_fn bdrv_co_copy_range(BdrvChild *src, uint64_t src_offset,
|
|||||||
BdrvChild *dst, uint64_t dst_offset,
|
BdrvChild *dst, uint64_t dst_offset,
|
||||||
uint64_t bytes, BdrvRequestFlags flags)
|
uint64_t bytes, BdrvRequestFlags flags)
|
||||||
{
|
{
|
||||||
BdrvTrackedRequest src_req, dst_req;
|
return bdrv_co_copy_range_from(src, src_offset,
|
||||||
BlockDriverState *src_bs = src->bs;
|
dst, dst_offset,
|
||||||
BlockDriverState *dst_bs = dst->bs;
|
bytes, flags);
|
||||||
int ret;
|
|
||||||
|
|
||||||
bdrv_inc_in_flight(src_bs);
|
|
||||||
bdrv_inc_in_flight(dst_bs);
|
|
||||||
tracked_request_begin(&src_req, src_bs, src_offset,
|
|
||||||
bytes, BDRV_TRACKED_READ);
|
|
||||||
tracked_request_begin(&dst_req, dst_bs, dst_offset,
|
|
||||||
bytes, BDRV_TRACKED_WRITE);
|
|
||||||
|
|
||||||
wait_serialising_requests(&src_req);
|
|
||||||
wait_serialising_requests(&dst_req);
|
|
||||||
ret = bdrv_co_copy_range_from(src, src_offset,
|
|
||||||
dst, dst_offset,
|
|
||||||
bytes, flags);
|
|
||||||
|
|
||||||
tracked_request_end(&src_req);
|
|
||||||
tracked_request_end(&dst_req);
|
|
||||||
bdrv_dec_in_flight(src_bs);
|
|
||||||
bdrv_dec_in_flight(dst_bs);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bdrv_parent_cb_resize(BlockDriverState *bs)
|
static void bdrv_parent_cb_resize(BlockDriverState *bs)
|
||||||
|
Loading…
Reference in New Issue
Block a user