[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCHv2 07/20] block: honour alignment and limit in bdrv_c
From: |
Peter Lieven |
Subject: |
[Qemu-devel] [PATCHv2 07/20] block: honour alignment and limit in bdrv_co_do_write_zeroes |
Date: |
Tue, 17 Sep 2013 15:48:43 +0200 |
Signed-off-by: Peter Lieven <address@hidden>
---
block.c | 57 +++++++++++++++++++++++++++++++++++++++++----------------
1 file changed, 41 insertions(+), 16 deletions(-)
diff --git a/block.c b/block.c
index 177720e..74ec342 100644
--- a/block.c
+++ b/block.c
@@ -2660,28 +2660,53 @@ static int coroutine_fn
bdrv_co_do_write_zeroes(BlockDriverState *bs,
BlockDriver *drv = bs->drv;
QEMUIOVector qiov;
struct iovec iov;
- int ret;
+ int ret = 0;
- /* TODO Emulate only part of misaligned requests instead of letting block
- * drivers return -ENOTSUP and emulate everything */
+ /* if no limit is specified in the BlockDriverState use a default
+ * of 32768 512-byte sectors (16 MiB) per request.
+ */
+ int max_write_zeroes = bs->max_write_zeroes ? bs->max_write_zeroes : 32768;
- /* First try the efficient write zeroes operation */
- if (drv->bdrv_co_write_zeroes) {
- ret = drv->bdrv_co_write_zeroes(bs, sector_num, nb_sectors, flags);
- if (ret != -ENOTSUP) {
- return ret;
+ while (nb_sectors > 0 && !ret) {
+ int num = nb_sectors;
+
+ /* align request */
+ if (bs->write_zeroes_alignment &&
+ num >= bs->write_zeroes_alignment &&
+ sector_num % bs->write_zeroes_alignment) {
+ if (num > bs->write_zeroes_alignment) {
+ num = bs->write_zeroes_alignment;
+ }
+ num -= sector_num % bs->write_zeroes_alignment;
}
- }
- /* Fall back to bounce buffer if write zeroes is unsupported */
- iov.iov_len = nb_sectors * BDRV_SECTOR_SIZE;
- iov.iov_base = qemu_blockalign(bs, iov.iov_len);
- memset(iov.iov_base, 0, iov.iov_len);
- qemu_iovec_init_external(&qiov, &iov, 1);
+ /* limit request size */
+ if (num > max_write_zeroes) {
+ num = max_write_zeroes;
+ }
- ret = drv->bdrv_co_writev(bs, sector_num, nb_sectors, &qiov);
+ ret = -ENOTSUP;
+ /* First try the efficient write zeroes operation */
+ if (drv->bdrv_co_write_zeroes) {
+ ret = drv->bdrv_co_write_zeroes(bs, sector_num, num, flags);
+ }
+
+ if (ret == -ENOTSUP) {
+ /* Fall back to bounce buffer if write zeroes is unsupported */
+ iov.iov_len = nb_sectors * BDRV_SECTOR_SIZE;
+ iov.iov_base = qemu_blockalign(bs, iov.iov_len);
+ memset(iov.iov_base, 0, iov.iov_len);
+ qemu_iovec_init_external(&qiov, &iov, 1);
+
+ ret = drv->bdrv_co_writev(bs, sector_num, num, &qiov);
+
+ qemu_vfree(iov.iov_base);
+ }
+
+ sector_num += num;
+ nb_sectors -= num;
+ }
- qemu_vfree(iov.iov_base);
return ret;
}
--
1.7.9.5
- [Qemu-devel] [PATCHv2 10/20] iscsi: set limits in BlockDriverState, (continued)
- [Qemu-devel] [PATCHv2 10/20] iscsi: set limits in BlockDriverState, Peter Lieven, 2013/09/17
- [Qemu-devel] [PATCHv2 09/20] iscsi: simplify iscsi_co_discard, Peter Lieven, 2013/09/17
- [Qemu-devel] [PATCHv2 05/20] block/raw: add bdrv_has_discard_zeroes and bdrv_has_discard_write_zeroes, Peter Lieven, 2013/09/17
- [Qemu-devel] [PATCHv2 11/20] iscsi: add bdrv_has_discard_zeroes and bdrv_has_discard_write_zeroes, Peter Lieven, 2013/09/17
- [Qemu-devel] [PATCHv2 12/20] iscsi: add bdrv_co_write_zeroes, Peter Lieven, 2013/09/17
- [Qemu-devel] [PATCHv2 07/20] block: honour alignment and limit in bdrv_co_do_write_zeroes,
Peter Lieven <=
- [Qemu-devel] [PATCHv2 14/20] block/get_block_status: set *pnum = 0 on error, Peter Lieven, 2013/09/17
- [Qemu-devel] [PATCHv2 13/20] block: introduce bdrv_zeroize, Peter Lieven, 2013/09/17
- [Qemu-devel] [PATCHv2 15/20] block/get_block_status: avoid segfault if there is no backing_hd, Peter Lieven, 2013/09/17
- [Qemu-devel] [PATCHv2 20/20] block/raw: copy block limits and alignment information on raw_open, Peter Lieven, 2013/09/17