Revision c292ee6a block/sheepdog.c
b/block/sheepdog.c | ||
---|---|---|
259 | 259 |
uint8_t flags; |
260 | 260 |
uint32_t id; |
261 | 261 |
|
262 |
QLIST_ENTRY(AIOReq) outstanding_aio_siblings;
|
|
262 |
QLIST_ENTRY(AIOReq) aio_siblings; |
|
263 | 263 |
} AIOReq; |
264 | 264 |
|
265 | 265 |
enum AIOCBState { |
... | ... | |
305 | 305 |
Coroutine *co_recv; |
306 | 306 |
|
307 | 307 |
uint32_t aioreq_seq_num; |
308 |
QLIST_HEAD(outstanding_aio_head, AIOReq) outstanding_aio_head; |
|
308 |
QLIST_HEAD(inflight_aio_head, AIOReq) inflight_aio_head; |
|
309 |
QLIST_HEAD(pending_aio_head, AIOReq) pending_aio_head; |
|
309 | 310 |
} BDRVSheepdogState; |
310 | 311 |
|
311 | 312 |
static const char * sd_strerror(int err) |
... | ... | |
356 | 357 |
* Sheepdog I/O handling: |
357 | 358 |
* |
358 | 359 |
* 1. In sd_co_rw_vector, we send the I/O requests to the server and |
359 |
* link the requests to the outstanding_list in the
|
|
360 |
* link the requests to the inflight_list in the
|
|
360 | 361 |
* BDRVSheepdogState. The function exits without waiting for |
361 | 362 |
* receiving the response. |
362 | 363 |
* |
... | ... | |
384 | 385 |
aio_req->flags = flags; |
385 | 386 |
aio_req->id = s->aioreq_seq_num++; |
386 | 387 |
|
387 |
QLIST_INSERT_HEAD(&s->outstanding_aio_head, aio_req, |
|
388 |
outstanding_aio_siblings); |
|
389 |
|
|
390 | 388 |
acb->nr_pending++; |
391 | 389 |
return aio_req; |
392 | 390 |
} |
... | ... | |
395 | 393 |
{ |
396 | 394 |
SheepdogAIOCB *acb = aio_req->aiocb; |
397 | 395 |
|
398 |
QLIST_REMOVE(aio_req, outstanding_aio_siblings);
|
|
396 |
QLIST_REMOVE(aio_req, aio_siblings); |
|
399 | 397 |
g_free(aio_req); |
400 | 398 |
|
401 | 399 |
acb->nr_pending--; |
... | ... | |
640 | 638 |
* This function searchs pending requests to the object `oid', and |
641 | 639 |
* sends them. |
642 | 640 |
*/ |
643 |
static void coroutine_fn send_pending_req(BDRVSheepdogState *s, uint64_t oid, uint32_t id)
|
|
641 |
static void coroutine_fn send_pending_req(BDRVSheepdogState *s, uint64_t oid) |
|
644 | 642 |
{ |
645 | 643 |
AIOReq *aio_req, *next; |
646 | 644 |
SheepdogAIOCB *acb; |
647 | 645 |
int ret; |
648 | 646 |
|
649 |
QLIST_FOREACH_SAFE(aio_req, &s->outstanding_aio_head, |
|
650 |
outstanding_aio_siblings, next) { |
|
651 |
if (id == aio_req->id) { |
|
652 |
continue; |
|
653 |
} |
|
647 |
QLIST_FOREACH_SAFE(aio_req, &s->pending_aio_head, aio_siblings, next) { |
|
654 | 648 |
if (aio_req->oid != oid) { |
655 | 649 |
continue; |
656 | 650 |
} |
657 | 651 |
|
658 | 652 |
acb = aio_req->aiocb; |
653 |
/* move aio_req from pending list to inflight one */ |
|
654 |
QLIST_REMOVE(aio_req, aio_siblings); |
|
655 |
QLIST_INSERT_HEAD(&s->inflight_aio_head, aio_req, aio_siblings); |
|
659 | 656 |
ret = add_aio_request(s, aio_req, acb->qiov->iov, |
660 | 657 |
acb->qiov->niov, 0, acb->aiocb_type); |
661 | 658 |
if (ret < 0) { |
... | ... | |
684 | 681 |
SheepdogAIOCB *acb; |
685 | 682 |
unsigned long idx; |
686 | 683 |
|
687 |
if (QLIST_EMPTY(&s->outstanding_aio_head)) {
|
|
684 |
if (QLIST_EMPTY(&s->inflight_aio_head)) {
|
|
688 | 685 |
goto out; |
689 | 686 |
} |
690 | 687 |
|
... | ... | |
695 | 692 |
goto out; |
696 | 693 |
} |
697 | 694 |
|
698 |
/* find the right aio_req from the outstanding_aio list */
|
|
699 |
QLIST_FOREACH(aio_req, &s->outstanding_aio_head, outstanding_aio_siblings) {
|
|
695 |
/* find the right aio_req from the inflight aio list */
|
|
696 |
QLIST_FOREACH(aio_req, &s->inflight_aio_head, aio_siblings) {
|
|
700 | 697 |
if (aio_req->id == rsp.id) { |
701 | 698 |
break; |
702 | 699 |
} |
... | ... | |
734 | 731 |
* create requests are not allowed, so we search the |
735 | 732 |
* pending requests here. |
736 | 733 |
*/ |
737 |
send_pending_req(s, vid_to_data_oid(s->inode.vdi_id, idx), rsp.id);
|
|
734 |
send_pending_req(s, vid_to_data_oid(s->inode.vdi_id, idx)); |
|
738 | 735 |
} |
739 | 736 |
break; |
740 | 737 |
case AIOCB_READ_UDATA: |
... | ... | |
786 | 783 |
{ |
787 | 784 |
BDRVSheepdogState *s = opaque; |
788 | 785 |
|
789 |
return !QLIST_EMPTY(&s->outstanding_aio_head); |
|
786 |
return !QLIST_EMPTY(&s->inflight_aio_head) || |
|
787 |
!QLIST_EMPTY(&s->pending_aio_head); |
|
790 | 788 |
} |
791 | 789 |
|
792 | 790 |
static int set_nodelay(int fd) |
... | ... | |
1103 | 1101 |
|
1104 | 1102 |
strstart(filename, "sheepdog:", (const char **)&filename); |
1105 | 1103 |
|
1106 |
QLIST_INIT(&s->outstanding_aio_head); |
|
1104 |
QLIST_INIT(&s->inflight_aio_head); |
|
1105 |
QLIST_INIT(&s->pending_aio_head); |
|
1107 | 1106 |
s->fd = -1; |
1108 | 1107 |
|
1109 | 1108 |
memset(vdi, 0, sizeof(vdi)); |
... | ... | |
1465 | 1464 |
iov.iov_len = sizeof(s->inode); |
1466 | 1465 |
aio_req = alloc_aio_req(s, acb, vid_to_vdi_oid(s->inode.vdi_id), |
1467 | 1466 |
data_len, offset, 0, 0, offset); |
1467 |
QLIST_INSERT_HEAD(&s->inflight_aio_head, aio_req, aio_siblings); |
|
1468 | 1468 |
ret = add_aio_request(s, aio_req, &iov, 1, 0, AIOCB_WRITE_UDATA); |
1469 | 1469 |
if (ret) { |
1470 | 1470 |
free_aio_req(s, aio_req); |
... | ... | |
1533 | 1533 |
* Send I/O requests to the server. |
1534 | 1534 |
* |
1535 | 1535 |
* This function sends requests to the server, links the requests to |
1536 |
* the outstanding_list in BDRVSheepdogState, and exits without
|
|
1536 |
* the inflight_list in BDRVSheepdogState, and exits without
|
|
1537 | 1537 |
* waiting the response. The responses are received in the |
1538 | 1538 |
* `aio_read_response' function which is called from the main loop as |
1539 | 1539 |
* a fd handler. |
... | ... | |
1606 | 1606 |
|
1607 | 1607 |
if (create) { |
1608 | 1608 |
AIOReq *areq; |
1609 |
QLIST_FOREACH(areq, &s->outstanding_aio_head, |
|
1610 |
outstanding_aio_siblings) { |
|
1611 |
if (areq == aio_req) { |
|
1612 |
continue; |
|
1613 |
} |
|
1609 |
QLIST_FOREACH(areq, &s->inflight_aio_head, aio_siblings) { |
|
1614 | 1610 |
if (areq->oid == oid) { |
1615 | 1611 |
/* |
1616 | 1612 |
* Sheepdog cannot handle simultaneous create |
... | ... | |
1620 | 1616 |
*/ |
1621 | 1617 |
aio_req->flags = 0; |
1622 | 1618 |
aio_req->base_oid = 0; |
1619 |
QLIST_INSERT_HEAD(&s->pending_aio_head, aio_req, |
|
1620 |
aio_siblings); |
|
1623 | 1621 |
goto done; |
1624 | 1622 |
} |
1625 | 1623 |
} |
1626 | 1624 |
} |
1627 | 1625 |
|
1626 |
QLIST_INSERT_HEAD(&s->inflight_aio_head, aio_req, aio_siblings); |
|
1628 | 1627 |
ret = add_aio_request(s, aio_req, acb->qiov->iov, acb->qiov->niov, |
1629 | 1628 |
create, acb->aiocb_type); |
1630 | 1629 |
if (ret < 0) { |
Also available in: Unified diff