diff options
author | MORITA Kazutaka <morita.kazutaka@lab.ntt.co.jp> | 2012-06-27 07:26:23 +0900 |
---|---|---|
committer | Kevin Wolf <kwolf@redhat.com> | 2012-07-09 15:53:02 +0200 |
commit | 7dc1cde05bd8c63789edc03fedb71d2d68da1d4f (patch) | |
tree | a7ae827dd91493b4a4f2c18b9a38a86b0477d5a1 | |
parent | c292ee6a67924061345975c02cd25b18f7054c4d (diff) | |
download | qemu-7dc1cde05bd8c63789edc03fedb71d2d68da1d4f.tar.gz qemu-7dc1cde05bd8c63789edc03fedb71d2d68da1d4f.tar.bz2 qemu-7dc1cde05bd8c63789edc03fedb71d2d68da1d4f.zip |
sheepdog: traverse pending_list from the first for each time
The pending list can be modified in other coroutine context
sd_co_rw_vector, so we need to traverse the list from the first again
after we send the pending request.
Signed-off-by: MORITA Kazutaka <morita.kazutaka@lab.ntt.co.jp>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
-rw-r--r-- | block/sheepdog.c | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/block/sheepdog.c b/block/sheepdog.c index f6cd5172a0..6e73efbad1 100644 --- a/block/sheepdog.c +++ b/block/sheepdog.c @@ -634,21 +634,31 @@ static int coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req, struct iovec *iov, int niov, int create, enum AIOCBState aiocb_type); + +static AIOReq *find_pending_req(BDRVSheepdogState *s, uint64_t oid) +{ + AIOReq *aio_req; + + QLIST_FOREACH(aio_req, &s->pending_aio_head, aio_siblings) { + if (aio_req->oid == oid) { + return aio_req; + } + } + + return NULL; +} + /* * This function searchs pending requests to the object `oid', and * sends them. */ static void coroutine_fn send_pending_req(BDRVSheepdogState *s, uint64_t oid) { - AIOReq *aio_req, *next; + AIOReq *aio_req; SheepdogAIOCB *acb; int ret; - QLIST_FOREACH_SAFE(aio_req, &s->pending_aio_head, aio_siblings, next) { - if (aio_req->oid != oid) { - continue; - } - + while ((aio_req = find_pending_req(s, oid)) != NULL) { acb = aio_req->aiocb; /* move aio_req from pending list to inflight one */ QLIST_REMOVE(aio_req, aio_siblings); |