sheepdog: split outstanding list into inflight and pending

outstanding_list_head is used for both pending and inflight requests.
This patch splits it and improves readability.

Signed-off-by: MORITA Kazutaka <morita.kazutaka@lab.ntt.co.jp>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
MORITA Kazutaka 2012-06-27 07:26:22 +09:00 committed by Kevin Wolf
parent 1d732d7d7c
commit c292ee6a67

View File

@ -259,7 +259,7 @@ typedef struct AIOReq {
uint8_t flags;
uint32_t id;
QLIST_ENTRY(AIOReq) outstanding_aio_siblings;
QLIST_ENTRY(AIOReq) aio_siblings;
} AIOReq;
enum AIOCBState {
@ -305,7 +305,8 @@ typedef struct BDRVSheepdogState {
Coroutine *co_recv;
uint32_t aioreq_seq_num;
QLIST_HEAD(outstanding_aio_head, AIOReq) outstanding_aio_head;
QLIST_HEAD(inflight_aio_head, AIOReq) inflight_aio_head;
QLIST_HEAD(pending_aio_head, AIOReq) pending_aio_head;
} BDRVSheepdogState;
static const char * sd_strerror(int err)
@ -356,7 +357,7 @@ static const char * sd_strerror(int err)
* Sheepdog I/O handling:
*
* 1. In sd_co_rw_vector, we send the I/O requests to the server and
* link the requests to the outstanding_list in the
* link the requests to the inflight_list in the
* BDRVSheepdogState. The function exits without waiting for
* receiving the response.
*
@ -384,9 +385,6 @@ static inline AIOReq *alloc_aio_req(BDRVSheepdogState *s, SheepdogAIOCB *acb,
aio_req->flags = flags;
aio_req->id = s->aioreq_seq_num++;
QLIST_INSERT_HEAD(&s->outstanding_aio_head, aio_req,
outstanding_aio_siblings);
acb->nr_pending++;
return aio_req;
}
@ -395,7 +393,7 @@ static inline void free_aio_req(BDRVSheepdogState *s, AIOReq *aio_req)
{
SheepdogAIOCB *acb = aio_req->aiocb;
QLIST_REMOVE(aio_req, outstanding_aio_siblings);
QLIST_REMOVE(aio_req, aio_siblings);
g_free(aio_req);
acb->nr_pending--;
@ -640,22 +638,21 @@ static int coroutine_fn add_aio_request(BDRVSheepdogState *s, AIOReq *aio_req,
* This function searchs pending requests to the object `oid', and
* sends them.
*/
static void coroutine_fn send_pending_req(BDRVSheepdogState *s, uint64_t oid, uint32_t id)
static void coroutine_fn send_pending_req(BDRVSheepdogState *s, uint64_t oid)
{
AIOReq *aio_req, *next;
SheepdogAIOCB *acb;
int ret;
QLIST_FOREACH_SAFE(aio_req, &s->outstanding_aio_head,
outstanding_aio_siblings, next) {
if (id == aio_req->id) {
continue;
}
QLIST_FOREACH_SAFE(aio_req, &s->pending_aio_head, aio_siblings, next) {
if (aio_req->oid != oid) {
continue;
}
acb = aio_req->aiocb;
/* move aio_req from pending list to inflight one */
QLIST_REMOVE(aio_req, aio_siblings);
QLIST_INSERT_HEAD(&s->inflight_aio_head, aio_req, aio_siblings);
ret = add_aio_request(s, aio_req, acb->qiov->iov,
acb->qiov->niov, 0, acb->aiocb_type);
if (ret < 0) {
@ -684,7 +681,7 @@ static void coroutine_fn aio_read_response(void *opaque)
SheepdogAIOCB *acb;
unsigned long idx;
if (QLIST_EMPTY(&s->outstanding_aio_head)) {
if (QLIST_EMPTY(&s->inflight_aio_head)) {
goto out;
}
@ -695,8 +692,8 @@ static void coroutine_fn aio_read_response(void *opaque)
goto out;
}
/* find the right aio_req from the outstanding_aio list */
QLIST_FOREACH(aio_req, &s->outstanding_aio_head, outstanding_aio_siblings) {
/* find the right aio_req from the inflight aio list */
QLIST_FOREACH(aio_req, &s->inflight_aio_head, aio_siblings) {
if (aio_req->id == rsp.id) {
break;
}
@ -734,7 +731,7 @@ static void coroutine_fn aio_read_response(void *opaque)
* create requests are not allowed, so we search the
* pending requests here.
*/
send_pending_req(s, vid_to_data_oid(s->inode.vdi_id, idx), rsp.id);
send_pending_req(s, vid_to_data_oid(s->inode.vdi_id, idx));
}
break;
case AIOCB_READ_UDATA:
@ -786,7 +783,8 @@ static int aio_flush_request(void *opaque)
{
BDRVSheepdogState *s = opaque;
return !QLIST_EMPTY(&s->outstanding_aio_head);
return !QLIST_EMPTY(&s->inflight_aio_head) ||
!QLIST_EMPTY(&s->pending_aio_head);
}
static int set_nodelay(int fd)
@ -1103,7 +1101,8 @@ static int sd_open(BlockDriverState *bs, const char *filename, int flags)
strstart(filename, "sheepdog:", (const char **)&filename);
QLIST_INIT(&s->outstanding_aio_head);
QLIST_INIT(&s->inflight_aio_head);
QLIST_INIT(&s->pending_aio_head);
s->fd = -1;
memset(vdi, 0, sizeof(vdi));
@ -1465,6 +1464,7 @@ static void coroutine_fn sd_write_done(SheepdogAIOCB *acb)
iov.iov_len = sizeof(s->inode);
aio_req = alloc_aio_req(s, acb, vid_to_vdi_oid(s->inode.vdi_id),
data_len, offset, 0, 0, offset);
QLIST_INSERT_HEAD(&s->inflight_aio_head, aio_req, aio_siblings);
ret = add_aio_request(s, aio_req, &iov, 1, 0, AIOCB_WRITE_UDATA);
if (ret) {
free_aio_req(s, aio_req);
@ -1533,7 +1533,7 @@ out:
* Send I/O requests to the server.
*
* This function sends requests to the server, links the requests to
* the outstanding_list in BDRVSheepdogState, and exits without
* the inflight_list in BDRVSheepdogState, and exits without
* waiting the response. The responses are received in the
* `aio_read_response' function which is called from the main loop as
* a fd handler.
@ -1606,11 +1606,7 @@ static int coroutine_fn sd_co_rw_vector(void *p)
if (create) {
AIOReq *areq;
QLIST_FOREACH(areq, &s->outstanding_aio_head,
outstanding_aio_siblings) {
if (areq == aio_req) {
continue;
}
QLIST_FOREACH(areq, &s->inflight_aio_head, aio_siblings) {
if (areq->oid == oid) {
/*
* Sheepdog cannot handle simultaneous create
@ -1620,11 +1616,14 @@ static int coroutine_fn sd_co_rw_vector(void *p)
*/
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);
ret = add_aio_request(s, aio_req, acb->qiov->iov, acb->qiov->niov,
create, acb->aiocb_type);
if (ret < 0) {