This fixes io-test 179 with qcow2. Otherwise, there would be more 'data'
sectors.

Signed-off-by: Fiona Ebner <[email protected]>
---

Not sure if we should even attempt this without considering
detect-zeroes. While it does keep 179 working, it is a change in
behavior, since it could turn previously data sectors (with zeroes)
into zero sectors when they are part of the head or tail of a zero
write.

Would it even be tolerable from a performance perspective?


Remaining test failures after this patch are:
154 177 204 271

177 and 204 use opt-write-zero=15M with blkdebug, making an
is_power_of_2(align) assertion fail.

Changes in the output of 154 and 271 might be expected, but I didn't
look into it in detail yet, as I wanted to discuss everything first.

 block/io.c | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/block/io.c b/block/io.c
index d92b30bce5..34b523c951 100644
--- a/block/io.c
+++ b/block/io.c
@@ -2179,10 +2179,14 @@ bdrv_co_do_zero_pwritev(BdrvChild *child, int64_t 
offset, int64_t bytes,
             int64_t write_bytes = pad.merge_reads ? pad.buf_len : align;
 
             if (total_length >= aligned_offset + write_bytes) {
+                BdrvRequestFlags head_flags =
+                    buffer_is_zero(pad.buf, write_bytes) ?
+                    flags : flags & ~BDRV_REQ_ZERO_WRITE;
+
                 qemu_iovec_init_buf(&local_qiov, pad.buf, write_bytes);
                 ret = bdrv_aligned_pwritev(child, req, aligned_offset,
                                            write_bytes, align, &local_qiov, 0,
-                                           flags & ~BDRV_REQ_ZERO_WRITE);
+                                           head_flags);
             } else {
                 write_bytes = total_length - aligned_offset;
                 qemu_iovec_init_buf(&local_qiov, pad.buf, write_bytes);
@@ -2220,10 +2224,13 @@ bdrv_co_do_zero_pwritev(BdrvChild *child, int64_t 
offset, int64_t bytes,
         if (total_length >= offset + align) {
             assert(align == pad.tail + bytes);
 
+            BdrvRequestFlags tail_flags =
+                buffer_is_zero(pad.tail_buf + bytes, pad.tail) ?
+                flags : flags & ~BDRV_REQ_ZERO_WRITE;
+
             qemu_iovec_init_buf(&local_qiov, pad.tail_buf, align);
             ret = bdrv_aligned_pwritev(child, req, offset, align, align,
-                                       &local_qiov, 0,
-                                       flags & ~BDRV_REQ_ZERO_WRITE);
+                                       &local_qiov, 0, tail_flags);
         } else {
             int64_t write_bytes = total_length - offset;
             qemu_iovec_init_buf(&local_qiov, pad.tail_buf, write_bytes);
-- 
2.47.3



Reply via email to