Skip to content
  • Paolo Bonzini's avatar
    block: add a CoMutex to synchronous read drivers · 848c66e8
    Paolo Bonzini authored
    
    
    The big conversion of bdrv_read/write to coroutines caused the two
    homonymous callbacks in BlockDriver to become reentrant.  It goes
    like this:
    
    1) bdrv_read is now called in a coroutine, and calls bdrv_read or
    bdrv_pread.
    
    2) the nested bdrv_read goes through the fast path in bdrv_rw_co_entry;
    
    3) in the common case when the protocol is file, bdrv_co_do_readv calls
    bdrv_co_readv_em (and from here goes to bdrv_co_io_em), which yields
    until the AIO operation is complete;
    
    4) if bdrv_read had been called from a bottom half, the main loop
    is free to iterate again: a device model or another bottom half
    can then come and call bdrv_read again.
    
    This applies to all four of read/write/flush/discard.  It would also
    apply to is_allocated, but it is not used from within coroutines:
    besides qemu-img.c and qemu-io.c, which operate synchronously, the
    only user is the monitor.  Copy-on-read will introduce a use in the
    block layer, and will require converting it.
    
    The solution is "simply" to convert all drivers to coroutines!  We
    just need to add a CoMutex that is taken around affected operations.
    
    Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
    Signed-off-by: default avatarKevin Wolf <kwolf@redhat.com>
    848c66e8