aboutsummaryrefslogtreecommitdiff
path: root/block/bochs.c
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2011-10-20 13:16:21 +0200
committerKevin Wolf <kwolf@redhat.com>2011-10-21 17:34:13 +0200
commit848c66e8f5b631961580f7f010a5831430dc84c2 (patch)
tree4d6f47f0487b80669eca7185842849706d12b8d5 /block/bochs.c
parentbae0a0cc38d324c83ba737b92215f3447981d73b (diff)
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>
Diffstat (limited to 'block/bochs.c')
-rw-r--r--block/bochs.c2
1 files changed, 2 insertions, 0 deletions
diff --git a/block/bochs.c b/block/bochs.c
index 3c2f8d1b12..b0f80729fe 100644
--- a/block/bochs.c
+++ b/block/bochs.c
@@ -80,6 +80,7 @@ struct bochs_header {
};
typedef struct BDRVBochsState {
+ CoMutex lock;
uint32_t *catalog_bitmap;
int catalog_size;
@@ -150,6 +151,7 @@ static int bochs_open(BlockDriverState *bs, int flags)
s->extent_size = le32_to_cpu(bochs.extra.redolog.extent);
+ qemu_co_mutex_init(&s->lock);
return 0;
fail:
return -1;