On Tue, Oct 18, 2011 at 6:48 AM, Marcelo Tosatti <mtosa...@redhat.com> wrote: > 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?
CoQueue is FIFO so overlapping requests are processed in order and will not wait indefinitely. Stefan