in a read-modify-write cycle a small request might cause head and tail to fall into the same alignment. Currently QEMU reads the same block twice in this case which is not necessary.
Signed-off-by: Peter Lieven <p...@kamp.de> --- block/io.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/block/io.c b/block/io.c index 60a6bd8..fa40121 100644 --- a/block/io.c +++ b/block/io.c @@ -1430,6 +1430,18 @@ int coroutine_fn bdrv_co_pwritev(BlockDriverState *bs, bytes += offset & (align - 1); offset = offset & ~(align - 1); + + /* if head and tail fall into the same alignment + * we can omit the second read as it would read + * the same block again */ + if ((offset + bytes) & (align - 1) && + offset / align == (offset + bytes) / align) { + size_t tail_offs; + tail_offs = (offset + bytes) & (align - 1); + qemu_iovec_add(&local_qiov, head_buf + tail_offs, + align - tail_offs); + bytes += align - tail_offs; + } } if ((offset + bytes) & (align - 1)) { -- 1.9.1