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