static int archipelago_submit_request(BDRVArchipelagoState *s, uint64_t bufidx, size_t count, off_t offset, ArchipelagoAIOCB *aio_cb, ArchipelagoSegmentedRequest *segreq, int op) { int ret, targetlen; char *target; void *data = NULL; struct xseg_request *req; AIORequestData *reqdata = g_malloc(sizeof(AIORequestData)); targetlen = strlen(s->volname); req = xseg_get_request(s->xseg, s->srcport, s->vportno, X_ALLOC); if (!req) { archipelagolog("Cannot get XSEG request\n"); goto err_exit2; } ret = xseg_prep_request(s->xseg, req, targetlen, count); if (ret < 0) { archipelagolog("Cannot prepare XSEG request\n"); goto err_exit; } target = xseg_get_target(s->xseg, req); if (!target) { archipelagolog("Cannot get XSEG target\n"); goto err_exit; } memcpy(target, s->volname, targetlen); req->size = count; req->offset = offset; switch (op) { case ARCHIP_OP_READ: req->op = X_READ; break; case ARCHIP_OP_WRITE: req->op = X_WRITE; break; case ARCHIP_OP_FLUSH: req->op = X_FLUSH; break; } reqdata->volname = s->volname; reqdata->offset = offset; reqdata->size = count; reqdata->bufidx = bufidx; reqdata->aio_cb = aio_cb; reqdata->segreq = segreq; reqdata->op = op; xseg_set_req_data(s->xseg, req, reqdata); if (op == ARCHIP_OP_WRITE) { data = xseg_get_data(s->xseg, req); if (!data) { archipelagolog("Cannot get XSEG data\n"); goto err_exit; } qemu_iovec_to_buf(aio_cb->qiov, bufidx, data, count); } xport p = xseg_submit(s->xseg, req, s->srcport, X_ALLOC); if (p == NoPort) { archipelagolog("Could not submit XSEG request\n"); goto err_exit; } xseg_signal(s->xseg, p); return 0; err_exit: g_free(reqdata); xseg_put_request(s->xseg, req, s->srcport); return -EIO; err_exit2: g_free(reqdata); return -EIO; }