On Mon, Oct 17, 2011 at 04:47:29PM +0100, Stefan Hajnoczi wrote: > When copy-on-read is enabled it is necessary to wait for overlapping > requests before issuing new requests. This prevents races between the > copy-on-read and a write request. > > Signed-off-by: Stefan Hajnoczi <stefa...@linux.vnet.ibm.com> > --- > block.c | 39 +++++++++++++++++++++++++++++++++++++++ > 1 files changed, 39 insertions(+), 0 deletions(-) > > diff --git a/block.c b/block.c > index e624ac3..cc3202c 100644 > --- a/block.c > +++ b/block.c > @@ -1001,6 +1001,7 @@ struct BdrvTrackedRequest { > int nb_sectors; > bool is_write; > QLIST_ENTRY(BdrvTrackedRequest) list; > + CoQueue wait_queue; /* coroutines blocked on this request */ > }; > > /** > @@ -1014,6 +1015,12 @@ static void tracked_request_remove(BdrvTrackedRequest > *req) > { > if (req) { > QLIST_REMOVE(req, list); > + > + /* Wake up all coroutines blocked on this request */ > + while (qemu_co_queue_next(&req->wait_queue)) { > + /* Do nothing */ > + } > + > g_free(req); > } > } > @@ -1038,12 +1045,36 @@ static BdrvTrackedRequest > *tracked_request_add(BlockDriverState *bs, > req->sector_num = sector_num; > req->nb_sectors = nb_sectors; > req->is_write = is_write; > + qemu_co_queue_init(&req->wait_queue); > > QLIST_INSERT_HEAD(&bs->tracked_requests, req, list); > > return req; > } > > +static bool tracked_request_overlaps(BdrvTrackedRequest *req, > + int64_t sector_num, int nb_sectors) { > + return false; /* not yet implemented */ > +} > + > +static void coroutine_fn wait_for_overlapping_requests(BlockDriverState *bs, > + int64_t sector_num, int nb_sectors) > +{ > + BdrvTrackedRequest *req; > + bool retry; > + > + do { > + retry = false; > + QLIST_FOREACH(req, &bs->tracked_requests, list) { > + if (tracked_request_overlaps(req, sector_num, nb_sectors)) { > + qemu_co_queue_wait(&req->wait_queue); > + retry = true;
What prevents overlapping requests (from waiter criteria) to be inserted to the queue while there are waiters again? That is, why is it not possible for a waiter to wait indefinetely?