Currently, all callers use bs->bl.request_alignment. This will change
when making bdrv_co_do_zero_pwritev() honor the block driver's
pwrite_zeroes_alignment. Note that the alignment for reading is not
necessarily the alignment for the request. In particular with qcow2
images, the total image length is not necessarily aligned to
pwrite_zeroes_alignment, and in such cases, a request with that bigger
alignment would cause an assertion failure.
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
---
block/io.c | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/block/io.c b/block/io.c
index e80aecf194..403a45f91d 100644
--- a/block/io.c
+++ b/block/io.c
@@ -1511,7 +1511,7 @@ static bool bdrv_init_padding(BlockDriverState *bs,
}
static int coroutine_fn GRAPH_RDLOCK
-bdrv_padding_rmw_read(BdrvChild *child, BdrvTrackedRequest *req,
+bdrv_padding_rmw_read(BdrvChild *child, BdrvTrackedRequest *req, int64_t bytes,
BdrvRequestPadding *pad, bool zero_middle)
{
QEMUIOVector local_qiov;
@@ -1522,7 +1522,9 @@ bdrv_padding_rmw_read(BdrvChild *child, BdrvTrackedRequest *req,
assert(req->serialising && pad->buf);
if (pad->head || pad->merge_reads) {
- int64_t bytes = pad->merge_reads ? pad->buf_len : align;
+ if (pad->merge_reads) {
+ bytes = pad->buf_len;
+ }
qemu_iovec_init_buf(&local_qiov, pad->buf, bytes);
@@ -1550,13 +1552,13 @@ bdrv_padding_rmw_read(BdrvChild *child, BdrvTrackedRequest *req,
}
if (pad->tail) {
- qemu_iovec_init_buf(&local_qiov, pad->tail_buf, align);
+ qemu_iovec_init_buf(&local_qiov, pad->tail_buf, bytes);
bdrv_co_debug_event(bs, BLKDBG_PWRITEV_RMW_TAIL);
ret = bdrv_aligned_preadv(
child, req,
- req->overlap_offset + req->overlap_bytes - align,
- align, align, &local_qiov, 0, 0);
+ req->overlap_offset + req->overlap_bytes - bytes,
+ bytes, align, &local_qiov, 0, 0);
if (ret < 0) {
return ret;
}
@@ -2166,7 +2168,7 @@ bdrv_co_do_zero_pwritev(BdrvChild *child, int64_t offset, int64_t bytes,
assert(!(flags & BDRV_REQ_NO_WAIT));
bdrv_make_request_serialising(req, align);
- bdrv_padding_rmw_read(child, req, &pad, true);
+ bdrv_padding_rmw_read(child, req, align, &pad, true);
if (pad.head || pad.merge_reads) {
int64_t aligned_offset = offset & ~(align - 1);
@@ -2302,7 +2304,7 @@ int coroutine_fn bdrv_co_pwritev_part(BdrvChild *child,
*/
assert(!(flags & BDRV_REQ_NO_WAIT));
bdrv_make_request_serialising(&req, align);
- bdrv_padding_rmw_read(child, &req, &pad, false);
+ bdrv_padding_rmw_read(child, &req, align, &pad, false);
}
ret = bdrv_aligned_pwritev(child, &req, offset, bytes, align,
--
2.47.3