|
|
9ae3a8 |
From 4a1e019ac51460ce6329892cc99fc11d518d2eb2 Mon Sep 17 00:00:00 2001
|
|
|
9ae3a8 |
Message-Id: <4a1e019ac51460ce6329892cc99fc11d518d2eb2.1389014116.git.minovotn@redhat.com>
|
|
|
9ae3a8 |
In-Reply-To: <c8cc35838d42aa286242772d97e3a9be7bb786ba.1389014116.git.minovotn@redhat.com>
|
|
|
9ae3a8 |
References: <c8cc35838d42aa286242772d97e3a9be7bb786ba.1389014116.git.minovotn@redhat.com>
|
|
|
9ae3a8 |
From: Paolo Bonzini <pbonzini@redhat.com>
|
|
|
9ae3a8 |
Date: Mon, 9 Dec 2013 14:09:16 +0100
|
|
|
9ae3a8 |
Subject: [PATCH 28/50] block: make bdrv_co_do_write_zeroes stricter in
|
|
|
9ae3a8 |
producing aligned requests
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
RH-Author: Paolo Bonzini <pbonzini@redhat.com>
|
|
|
9ae3a8 |
Message-id: <1386598178-11845-31-git-send-email-pbonzini@redhat.com>
|
|
|
9ae3a8 |
Patchwork-id: 56067
|
|
|
9ae3a8 |
O-Subject: [RHEL 7.0 qemu-kvm PATCH 30/52] block: make bdrv_co_do_write_zeroes stricter in producing aligned requests
|
|
|
9ae3a8 |
Bugzilla: 1007815
|
|
|
9ae3a8 |
RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
|
|
|
9ae3a8 |
RH-Acked-by: Fam Zheng <famz@redhat.com>
|
|
|
9ae3a8 |
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Right now, bdrv_co_do_write_zeroes will only try to align the
|
|
|
9ae3a8 |
beginning of the request. However, it is simpler for many
|
|
|
9ae3a8 |
formats to expect the block layer to separate both the head *and*
|
|
|
9ae3a8 |
the tail. This makes sure that the format's bdrv_co_write_zeroes
|
|
|
9ae3a8 |
function will be called with aligned sector_num and nb_sectors for
|
|
|
9ae3a8 |
the bulk of the request.
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
|
9ae3a8 |
Reviewed-by: Peter Lieven <pl@kamp.de>
|
|
|
9ae3a8 |
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
|
|
9ae3a8 |
(cherry picked from commit b8d71c09f31a9cae248d167dddc75c66d5135ff2)
|
|
|
9ae3a8 |
---
|
|
|
9ae3a8 |
block.c | 35 +++++++++++++++++++++++------------
|
|
|
9ae3a8 |
1 file changed, 23 insertions(+), 12 deletions(-)
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Signed-off-by: Michal Novotny <minovotn@redhat.com>
|
|
|
9ae3a8 |
---
|
|
|
9ae3a8 |
block.c | 35 +++++++++++++++++++++++------------
|
|
|
9ae3a8 |
1 file changed, 23 insertions(+), 12 deletions(-)
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
diff --git a/block.c b/block.c
|
|
|
9ae3a8 |
index c9e65b4..1ac1ab3 100644
|
|
|
9ae3a8 |
--- a/block.c
|
|
|
9ae3a8 |
+++ b/block.c
|
|
|
9ae3a8 |
@@ -2781,14 +2781,21 @@ static int coroutine_fn bdrv_co_do_write_zeroes(BlockDriverState *bs,
|
|
|
9ae3a8 |
while (nb_sectors > 0 && !ret) {
|
|
|
9ae3a8 |
int num = nb_sectors;
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
- /* align request */
|
|
|
9ae3a8 |
- if (bs->bl.write_zeroes_alignment &&
|
|
|
9ae3a8 |
- num >= bs->bl.write_zeroes_alignment &&
|
|
|
9ae3a8 |
- sector_num % bs->bl.write_zeroes_alignment) {
|
|
|
9ae3a8 |
- if (num > bs->bl.write_zeroes_alignment) {
|
|
|
9ae3a8 |
+ /* Align request. Block drivers can expect the "bulk" of the request
|
|
|
9ae3a8 |
+ * to be aligned.
|
|
|
9ae3a8 |
+ */
|
|
|
9ae3a8 |
+ if (bs->bl.write_zeroes_alignment
|
|
|
9ae3a8 |
+ && num > bs->bl.write_zeroes_alignment) {
|
|
|
9ae3a8 |
+ if (sector_num % bs->bl.write_zeroes_alignment != 0) {
|
|
|
9ae3a8 |
+ /* Make a small request up to the first aligned sector. */
|
|
|
9ae3a8 |
num = bs->bl.write_zeroes_alignment;
|
|
|
9ae3a8 |
+ num -= sector_num % bs->bl.write_zeroes_alignment;
|
|
|
9ae3a8 |
+ } else if ((sector_num + num) % bs->bl.write_zeroes_alignment != 0) {
|
|
|
9ae3a8 |
+ /* Shorten the request to the last aligned sector. num cannot
|
|
|
9ae3a8 |
+ * underflow because num > bs->bl.write_zeroes_alignment.
|
|
|
9ae3a8 |
+ */
|
|
|
9ae3a8 |
+ num -= (sector_num + num) % bs->bl.write_zeroes_alignment;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
- num -= sector_num % bs->bl.write_zeroes_alignment;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
/* limit request size */
|
|
|
9ae3a8 |
@@ -2806,16 +2813,20 @@ static int coroutine_fn bdrv_co_do_write_zeroes(BlockDriverState *bs,
|
|
|
9ae3a8 |
/* Fall back to bounce buffer if write zeroes is unsupported */
|
|
|
9ae3a8 |
iov.iov_len = num * BDRV_SECTOR_SIZE;
|
|
|
9ae3a8 |
if (iov.iov_base == NULL) {
|
|
|
9ae3a8 |
- /* allocate bounce buffer only once and ensure that it
|
|
|
9ae3a8 |
- * is big enough for this and all future requests.
|
|
|
9ae3a8 |
- */
|
|
|
9ae3a8 |
- size_t bufsize = num <= nb_sectors ? num : max_write_zeroes;
|
|
|
9ae3a8 |
- iov.iov_base = qemu_blockalign(bs, bufsize * BDRV_SECTOR_SIZE);
|
|
|
9ae3a8 |
- memset(iov.iov_base, 0, bufsize * BDRV_SECTOR_SIZE);
|
|
|
9ae3a8 |
+ iov.iov_base = qemu_blockalign(bs, num * BDRV_SECTOR_SIZE);
|
|
|
9ae3a8 |
+ memset(iov.iov_base, 0, num * BDRV_SECTOR_SIZE);
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
qemu_iovec_init_external(&qiov, &iov, 1);
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
ret = drv->bdrv_co_writev(bs, sector_num, num, &qiov);
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
+ /* Keep bounce buffer around if it is big enough for all
|
|
|
9ae3a8 |
+ * all future requests.
|
|
|
9ae3a8 |
+ */
|
|
|
9ae3a8 |
+ if (num < max_write_zeroes) {
|
|
|
9ae3a8 |
+ qemu_vfree(iov.iov_base);
|
|
|
9ae3a8 |
+ iov.iov_base = NULL;
|
|
|
9ae3a8 |
+ }
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
sector_num += num;
|
|
|
9ae3a8 |
--
|
|
|
9ae3a8 |
1.7.11.7
|
|
|
9ae3a8 |
|