qcow2: avoid reentrant bdrv_read() in copy_sectors()
commitaef4acb6616ab7fb5c105660aa8a2cee4e250e75
authorStefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Wed, 30 Nov 2011 12:23:41 +0000 (30 12:23 +0000)
committerKevin Wolf <kwolf@redhat.com>
Mon, 5 Dec 2011 13:49:47 +0000 (5 14:49 +0100)
tree53fe5915dd55fd1e4197f462c153b6c551417af4
parent1b9f1491f82de0c8f9b09d1a06ac33304449a634
qcow2: avoid reentrant bdrv_read() in copy_sectors()

A BlockDriverState should not issue requests on itself through the
public block layer interface.  Nested, or reentrant, requests are
problematic because they do I/O throttling and request tracking twice.

Features like block layer copy-on-read use request tracking to avoid
race conditions between concurrent requests.  The reentrant request will
have to "wait" for its parent request to complete.  But the parent is
waiting for the reentrant request to make progress so we have reached
deadlock.

The solution is for block drivers to avoid the public block layer
interfaces for reentrant requests.   Instead they should call their own
internal functions if they wish to perform reentrant requests.

This is also a good opportunity to make copy_sectors() a true
coroutine_fn.  That means calling bdrv_co_writev() instead of
bdrv_write().  Behavior is unchanged but we're being explicit that this
executes in coroutine context.

Signed-off-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
block/qcow2-cluster.c