Kevin noted how the part of stream_run() that is after the for loop runs with s->common.busy = false. At least bdrv_change_backing_file() can yield, possibly other functions, too.
The race window is really small but it's there. The patch takes a more flexible implementation of block_job_cancel_sync from the mirroring patches so that the race can be fixed easily. Paolo Bonzini (3): block: allow interrupting a co_sleep_ns block: wait for job callback in block_job_cancel_sync block: mark streaming job busy at the end block.c | 41 +++++++++++++++++++++++++++++++++++++++-- block/stream.c | 8 ++++---- block_int.h | 17 ++++++++++++----- qemu-coroutine-sleep.c | 3 ++- 4 files changed, 57 insertions(+), 12 deletions(-) -- 1.7.9.3