@@ -4718,6 +4718,44 @@ static void coroutine_fn bdrv_co_do_rw(void *opaque)
qemu_bh_schedule(acb->bh);
}
+static bool bdrv_rw_aligned(BlockDriverState *bs,
+ int64_t offset,
+ int bytes)
+{
+ uint64_t align = MAX(BDRV_SECTOR_SIZE, bs->request_alignment);
+
+ if ((offset & (align - 1)) || ((offset + bytes) & (align - 1))) {
+ return false;
+ } else {
+ return true;
+ }
+}
+
+static bool bdrv_co_can_bypass_co(BlockDriverState *bs,
+ int64_t sector_num,
+ int nb_sectors,
+ BdrvRequestFlags flags,
+ bool is_write)
+{
+ if (flags || bs->copy_on_read || bs->io_limits_enabled) {
+ return false;
+ }
+
+ /* unaligned read is safe */
+ if (!is_write) {
+ return true;
+ }
+
+ if (!bs->enable_write_cache ||
+ bs->detect_zeroes != BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF ||
+ !QLIST_EMPTY(&bs->before_write_notifiers.notifiers)) {
+ return false;
+ } else {
+ return bdrv_rw_aligned(bs, sector_num << BDRV_SECTOR_BITS,
+ nb_sectors << BDRV_SECTOR_BITS);
+ }
+}
+
static BlockDriverAIOCB *bdrv_co_aio_rw_vector(BlockDriverState *bs,
int64_t sector_num,
QEMUIOVector *qiov,
This function is introduced to check if the current block I/O can be allowed to run without coroutine for sake of performance. Signed-off-by: Ming Lei <ming.lei@canonical.com> --- block.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+)