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 <[email protected]>
---
 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



Reply via email to