aboutsummaryrefslogtreecommitdiff
path: root/block/io.c
diff options
context:
space:
mode:
Diffstat (limited to 'block/io.c')
-rw-r--r--block/io.c28
1 files changed, 27 insertions, 1 deletions
diff --git a/block/io.c b/block/io.c
index 1eb2b2bddc..7e4cb74cf4 100644
--- a/block/io.c
+++ b/block/io.c
@@ -1565,10 +1565,12 @@ static bool bdrv_init_padding(BlockDriverState *bs,
pad->tail = align - pad->tail;
}
- if ((!pad->head && !pad->tail) || !bytes) {
+ if (!pad->head && !pad->tail) {
return false;
}
+ assert(bytes); /* Nothing good in aligning zero-length requests */
+
sum = pad->head + bytes + pad->tail;
pad->buf_len = (sum > align && pad->head && pad->tail) ? 2 * align : align;
pad->buf = qemu_blockalign(bs, pad->buf_len);
@@ -1706,6 +1708,18 @@ int coroutine_fn bdrv_co_preadv_part(BdrvChild *child,
return ret;
}
+ if (bytes == 0 && !QEMU_IS_ALIGNED(offset, bs->bl.request_alignment)) {
+ /*
+ * Aligning zero request is nonsense. Even if driver has special meaning
+ * of zero-length (like qcow2_co_pwritev_compressed_part), we can't pass
+ * it to driver due to request_alignment.
+ *
+ * Still, no reason to return an error if someone do unaligned
+ * zero-length read occasionally.
+ */
+ return 0;
+ }
+
bdrv_inc_in_flight(bs);
/* Don't do copy-on-read if we read data before write operation */
@@ -2116,6 +2130,18 @@ int coroutine_fn bdrv_co_pwritev_part(BdrvChild *child,
return -ENOTSUP;
}
+ if (bytes == 0 && !QEMU_IS_ALIGNED(offset, bs->bl.request_alignment)) {
+ /*
+ * Aligning zero request is nonsense. Even if driver has special meaning
+ * of zero-length (like qcow2_co_pwritev_compressed_part), we can't pass
+ * it to driver due to request_alignment.
+ *
+ * Still, no reason to return an error if someone do unaligned
+ * zero-length write occasionally.
+ */
+ return 0;
+ }
+
bdrv_inc_in_flight(bs);
/*
* Align write if necessary by performing a read-modify-write cycle.