mirror of https://github.com/xemu-project/xemu.git
block: wait for overlapping requests
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 <stefanha@linux.vnet.ibm.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
53fec9d3fd
commit
f4658285f9
35
block.c
35
block.c
|
@ -1099,6 +1099,7 @@ struct BdrvTrackedRequest {
|
|||
int nb_sectors;
|
||||
bool is_write;
|
||||
QLIST_ENTRY(BdrvTrackedRequest) list;
|
||||
CoQueue wait_queue; /* coroutines blocked on this request */
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1109,6 +1110,7 @@ struct BdrvTrackedRequest {
|
|||
static void tracked_request_end(BdrvTrackedRequest *req)
|
||||
{
|
||||
QLIST_REMOVE(req, list);
|
||||
qemu_co_queue_restart_all(&req->wait_queue);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1126,9 +1128,34 @@ static void tracked_request_begin(BdrvTrackedRequest *req,
|
|||
.is_write = is_write,
|
||||
};
|
||||
|
||||
qemu_co_queue_init(&req->wait_queue);
|
||||
|
||||
QLIST_INSERT_HEAD(&bs->tracked_requests, req, list);
|
||||
}
|
||||
|
||||
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;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (retry);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return values:
|
||||
* 0 - success
|
||||
|
@ -1423,6 +1450,10 @@ static int coroutine_fn bdrv_co_do_readv(BlockDriverState *bs,
|
|||
bdrv_io_limits_intercept(bs, false, nb_sectors);
|
||||
}
|
||||
|
||||
if (bs->copy_on_read) {
|
||||
wait_for_overlapping_requests(bs, sector_num, nb_sectors);
|
||||
}
|
||||
|
||||
tracked_request_begin(&req, bs, sector_num, nb_sectors, false);
|
||||
ret = drv->bdrv_co_readv(bs, sector_num, nb_sectors, qiov);
|
||||
tracked_request_end(&req);
|
||||
|
@ -1462,6 +1493,10 @@ static int coroutine_fn bdrv_co_do_writev(BlockDriverState *bs,
|
|||
bdrv_io_limits_intercept(bs, true, nb_sectors);
|
||||
}
|
||||
|
||||
if (bs->copy_on_read) {
|
||||
wait_for_overlapping_requests(bs, sector_num, nb_sectors);
|
||||
}
|
||||
|
||||
tracked_request_begin(&req, bs, sector_num, nb_sectors, true);
|
||||
|
||||
ret = drv->bdrv_co_writev(bs, sector_num, nb_sectors, qiov);
|
||||
|
|
Loading…
Reference in New Issue