static size_t curl_read_cb(void *ptr, size_t size, size_t nmemb, void *opaque) { CURLState *s = ((CURLState*)opaque); size_t realsize = size * nmemb; int i; DPRINTF("CURL: Just reading %zd bytes\n", realsize); if (!s || !s->orig_buf) goto read_end; memcpy(s->orig_buf + s->buf_off, ptr, realsize); s->buf_off += realsize; for(i=0; i<CURL_NUM_ACB; i++) { CURLAIOCB *acb = s->acb[i]; if (!acb) continue; if ((s->buf_off >= acb->end)) { qemu_iovec_from_buffer(acb->qiov, s->orig_buf + acb->start, acb->end - acb->start); acb->common.cb(acb->common.opaque, 0); qemu_aio_release(acb); s->acb[i] = NULL; } } read_end: return realsize; }
static int curl_find_buf(BDRVCURLState *s, size_t start, size_t len, CURLAIOCB *acb) { int i; size_t end = start + len; for (i=0; i<CURL_NUM_STATES; i++) { CURLState *state = &s->states[i]; size_t buf_end = (state->buf_start + state->buf_off); size_t buf_fend = (state->buf_start + state->buf_len); if (!state->orig_buf) continue; if (!state->buf_off) continue; // Does the existing buffer cover our section? if ((start >= state->buf_start) && (start <= buf_end) && (end >= state->buf_start) && (end <= buf_end)) { char *buf = state->orig_buf + (start - state->buf_start); qemu_iovec_from_buffer(acb->qiov, buf, len); acb->common.cb(acb->common.opaque, 0); return FIND_RET_OK; } // Wait for unfinished chunks if ((start >= state->buf_start) && (start <= buf_fend) && (end >= state->buf_start) && (end <= buf_fend)) { int j; acb->start = start - state->buf_start; acb->end = acb->start + len; for (j=0; j<CURL_NUM_ACB; j++) { if (!state->acb[j]) { state->acb[j] = acb; return FIND_RET_WAIT; } } } } return FIND_RET_NONE; }
static void rbd_aio_bh_cb(void *opaque) { RBDAIOCB *acb = opaque; if (acb->cmd == RBD_AIO_READ) { qemu_iovec_from_buffer(acb->qiov, acb->bounce, acb->qiov->size); } qemu_vfree(acb->bounce); acb->common.cb(acb->common.opaque, (acb->ret > 0 ? 0 : acb->ret)); qemu_bh_delete(acb->bh); acb->bh = NULL; acb->status = 0; qemu_aio_unref(acb); }
static void rbd_aio_bh_cb(void *opaque) { RBDAIOCB *acb = opaque; if (!acb->write) { qemu_iovec_from_buffer(acb->qiov, acb->bounce, acb->qiov->size); } qemu_vfree(acb->bounce); acb->common.cb(acb->common.opaque, (acb->ret > 0 ? 0 : acb->ret)); qemu_bh_delete(acb->bh); acb->bh = NULL; qemu_aio_release(acb); }