block: add a CoMutex to synchronous read drivers
authorPaolo Bonzini <pbonzini@redhat.com>
Thu, 20 Oct 2011 11:16:21 +0000 (13:16 +0200)
committerKevin Wolf <kwolf@redhat.com>
Fri, 21 Oct 2011 15:34:13 +0000 (17:34 +0200)
commit848c66e8f5b631961580f7f010a5831430dc84c2
tree4d6f47f0487b80669eca7185842849706d12b8d5
parentbae0a0cc38d324c83ba737b92215f3447981d73b
block: add a CoMutex to synchronous read drivers

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: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
block/bochs.c
block/cloop.c
block/cow.c
block/dmg.c
block/nbd.c
block/parallels.c
block/vmdk.c
block/vpc.c
block/vvfat.c