mirror of
https://git.proxmox.com/git/qemu
synced 2025-07-09 13:18:26 +00:00
sheepdog: check simultaneous create in resend_aioreq
After reconnection happens, all the inflight requests are moved to the failed request list. As a result, sd_co_rw_vector() can send another create request before resend_aioreq() resends a create request from the failed list. This patch adds a helper function check_simultaneous_create() and checks simultaneous create requests more strictly in resend_aioreq(). Signed-off-by: MORITA Kazutaka <morita.kazutaka@lab.ntt.co.jp> Tested-by: Liu Yuan <namei.unix@gmail.com> Reviewed-by: Liu Yuan <namei.unix@gmail.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
35200687a1
commit
80308d33ec
@ -1288,6 +1288,29 @@ out:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return true if the specified request is linked to the pending list. */
|
||||||
|
static bool check_simultaneous_create(BDRVSheepdogState *s, AIOReq *aio_req)
|
||||||
|
{
|
||||||
|
AIOReq *areq;
|
||||||
|
QLIST_FOREACH(areq, &s->inflight_aio_head, aio_siblings) {
|
||||||
|
if (areq != aio_req && areq->oid == aio_req->oid) {
|
||||||
|
/*
|
||||||
|
* Sheepdog cannot handle simultaneous create requests to the same
|
||||||
|
* object, so we cannot send the request until the previous request
|
||||||
|
* finishes.
|
||||||
|
*/
|
||||||
|
DPRINTF("simultaneous create to %" PRIx64 "\n", aio_req->oid);
|
||||||
|
aio_req->flags = 0;
|
||||||
|
aio_req->base_oid = 0;
|
||||||
|
QLIST_REMOVE(aio_req, aio_siblings);
|
||||||
|
QLIST_INSERT_HEAD(&s->pending_aio_head, aio_req, aio_siblings);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static void coroutine_fn resend_aioreq(BDRVSheepdogState *s, AIOReq *aio_req)
|
static void coroutine_fn resend_aioreq(BDRVSheepdogState *s, AIOReq *aio_req)
|
||||||
{
|
{
|
||||||
SheepdogAIOCB *acb = aio_req->aiocb;
|
SheepdogAIOCB *acb = aio_req->aiocb;
|
||||||
@ -1296,29 +1319,19 @@ static void coroutine_fn resend_aioreq(BDRVSheepdogState *s, AIOReq *aio_req)
|
|||||||
/* check whether this request becomes a CoW one */
|
/* check whether this request becomes a CoW one */
|
||||||
if (acb->aiocb_type == AIOCB_WRITE_UDATA && is_data_obj(aio_req->oid)) {
|
if (acb->aiocb_type == AIOCB_WRITE_UDATA && is_data_obj(aio_req->oid)) {
|
||||||
int idx = data_oid_to_idx(aio_req->oid);
|
int idx = data_oid_to_idx(aio_req->oid);
|
||||||
AIOReq *areq;
|
|
||||||
|
|
||||||
if (s->inode.data_vdi_id[idx] == 0) {
|
|
||||||
create = true;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
if (is_data_obj_writable(&s->inode, idx)) {
|
if (is_data_obj_writable(&s->inode, idx)) {
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* link to the pending list if there is another CoW request to
|
if (check_simultaneous_create(s, aio_req)) {
|
||||||
* the same object */
|
return;
|
||||||
QLIST_FOREACH(areq, &s->inflight_aio_head, aio_siblings) {
|
|
||||||
if (areq != aio_req && areq->oid == aio_req->oid) {
|
|
||||||
DPRINTF("simultaneous CoW to %" PRIx64 "\n", aio_req->oid);
|
|
||||||
QLIST_REMOVE(aio_req, aio_siblings);
|
|
||||||
QLIST_INSERT_HEAD(&s->pending_aio_head, aio_req, aio_siblings);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
aio_req->base_oid = vid_to_data_oid(s->inode.data_vdi_id[idx], idx);
|
if (s->inode.data_vdi_id[idx]) {
|
||||||
aio_req->flags |= SD_FLAG_CMD_COW;
|
aio_req->base_oid = vid_to_data_oid(s->inode.data_vdi_id[idx], idx);
|
||||||
|
aio_req->flags |= SD_FLAG_CMD_COW;
|
||||||
|
}
|
||||||
create = true;
|
create = true;
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
@ -1945,27 +1958,14 @@ static int coroutine_fn sd_co_rw_vector(void *p)
|
|||||||
}
|
}
|
||||||
|
|
||||||
aio_req = alloc_aio_req(s, acb, oid, len, offset, flags, old_oid, done);
|
aio_req = alloc_aio_req(s, acb, oid, len, offset, flags, old_oid, done);
|
||||||
|
QLIST_INSERT_HEAD(&s->inflight_aio_head, aio_req, aio_siblings);
|
||||||
|
|
||||||
if (create) {
|
if (create) {
|
||||||
AIOReq *areq;
|
if (check_simultaneous_create(s, aio_req)) {
|
||||||
QLIST_FOREACH(areq, &s->inflight_aio_head, aio_siblings) {
|
goto done;
|
||||||
if (areq->oid == oid) {
|
|
||||||
/*
|
|
||||||
* Sheepdog cannot handle simultaneous create
|
|
||||||
* requests to the same object. So we cannot send
|
|
||||||
* the request until the previous request
|
|
||||||
* finishes.
|
|
||||||
*/
|
|
||||||
aio_req->flags = 0;
|
|
||||||
aio_req->base_oid = 0;
|
|
||||||
QLIST_INSERT_HEAD(&s->pending_aio_head, aio_req,
|
|
||||||
aio_siblings);
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QLIST_INSERT_HEAD(&s->inflight_aio_head, aio_req, aio_siblings);
|
|
||||||
add_aio_request(s, aio_req, acb->qiov->iov, acb->qiov->niov, create,
|
add_aio_request(s, aio_req, acb->qiov->iov, acb->qiov->niov, create,
|
||||||
acb->aiocb_type);
|
acb->aiocb_type);
|
||||||
done:
|
done:
|
||||||
|
Loading…
Reference in New Issue
Block a user