diff options
-rw-r--r-- | block.c | 11 | ||||
-rw-r--r-- | block/io.c | 7 | ||||
-rw-r--r-- | block/raw-posix.c | 1 | ||||
-rw-r--r-- | include/block/block.h | 2 | ||||
-rw-r--r-- | include/block/block_int.h | 3 |
5 files changed, 23 insertions, 1 deletions
@@ -113,6 +113,16 @@ size_t bdrv_opt_mem_align(BlockDriverState *bs) return bs->bl.opt_mem_alignment; } +size_t bdrv_min_mem_align(BlockDriverState *bs) +{ + if (!bs || !bs->drv) { + /* 4k should be on the safe side */ + return 4096; + } + + return bs->bl.min_mem_alignment; +} + /* check if the path starts with "<protocol>:" */ int path_has_protocol(const char *path) { @@ -890,6 +900,7 @@ static int bdrv_open_common(BlockDriverState *bs, BlockDriverState *file, } assert(bdrv_opt_mem_align(bs) != 0); + assert(bdrv_min_mem_align(bs) != 0); assert((bs->request_alignment != 0) || bs->sg); return 0; diff --git a/block/io.c b/block/io.c index a05ad677d3..e6c363921d 100644 --- a/block/io.c +++ b/block/io.c @@ -201,8 +201,10 @@ void bdrv_refresh_limits(BlockDriverState *bs, Error **errp) } bs->bl.opt_transfer_length = bs->file->bl.opt_transfer_length; bs->bl.max_transfer_length = bs->file->bl.max_transfer_length; + bs->bl.min_mem_alignment = bs->file->bl.min_mem_alignment; bs->bl.opt_mem_alignment = bs->file->bl.opt_mem_alignment; } else { + bs->bl.min_mem_alignment = 512; bs->bl.opt_mem_alignment = 512; } @@ -221,6 +223,9 @@ void bdrv_refresh_limits(BlockDriverState *bs, Error **errp) bs->bl.opt_mem_alignment = MAX(bs->bl.opt_mem_alignment, bs->backing_hd->bl.opt_mem_alignment); + bs->bl.min_mem_alignment = + MAX(bs->bl.min_mem_alignment, + bs->backing_hd->bl.min_mem_alignment); } /* Then let the driver override it */ @@ -2489,7 +2494,7 @@ void *qemu_try_blockalign0(BlockDriverState *bs, size_t size) bool bdrv_qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov) { int i; - size_t alignment = bdrv_opt_mem_align(bs); + size_t alignment = bdrv_min_mem_align(bs); for (i = 0; i < qiov->niov; i++) { if ((uintptr_t) qiov->iov[i].iov_base % alignment) { diff --git a/block/raw-posix.c b/block/raw-posix.c index 24d85826c4..70839245fd 100644 --- a/block/raw-posix.c +++ b/block/raw-posix.c @@ -725,6 +725,7 @@ static void raw_refresh_limits(BlockDriverState *bs, Error **errp) BDRVRawState *s = bs->opaque; raw_probe_alignment(bs, s->fd, errp); + bs->bl.min_mem_alignment = s->buf_align; bs->bl.opt_mem_alignment = s->buf_align; } diff --git a/include/block/block.h b/include/block/block.h index 7d1a7174f6..c1c963eb5c 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -440,6 +440,8 @@ void bdrv_img_create(const char *filename, const char *fmt, /* Returns the alignment in bytes that is required so that no bounce buffer * is required throughout the stack */ +size_t bdrv_min_mem_align(BlockDriverState *bs); +/* Returns optimal alignment in bytes for bounce buffer */ size_t bdrv_opt_mem_align(BlockDriverState *bs); void bdrv_set_guest_block_size(BlockDriverState *bs, int align); void *qemu_blockalign(BlockDriverState *bs, size_t size); diff --git a/include/block/block_int.h b/include/block/block_int.h index db29b7424e..f004378d58 100644 --- a/include/block/block_int.h +++ b/include/block/block_int.h @@ -313,6 +313,9 @@ typedef struct BlockLimits { int max_transfer_length; /* memory alignment so that no bounce buffer is needed */ + size_t min_mem_alignment; + + /* memory alignment for bounce buffer */ size_t opt_mem_alignment; } BlockLimits; |