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....@canonical.com> --- block.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/block.c b/block.c index ac184ef..2326dab 100644 --- a/block.c +++ b/block.c @@ -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, -- 1.7.9.5