+ /* FIXME */
+ /* For every mapped segment, issue a request to blockd */
+ /* FIXME: what if we run out of xseg requests? */
+ always_assert(xreq == io->mreq);
+ always_assert(!(xreq->state & XS_FAILED) && xreq->state & XS_SERVED); /* FIXME: This is too harsh */
+ if (xreq->op == X_INFO) {
+ *(off_t *)io->vreq->data = *(off_t *)io->mreq->data;
+ io->vreq->state |= XS_SERVED;
+
+ ret = xseg_respond(vlmcd->xseg, io->vreq->portno, io->vreq);
+ always_assert(ret != NoSerial);
+ ret = xseg_signal(vlmcd->xseg, io->vreq->portno);
+ always_assert(ret == 0);
+ io->state = CONCLUDED;
+ always_assert(xseg_put_request(xseg, vportno, io->mreq) != NoSerial);
+ free_io(vlmcd, io);
+ } else {
+ struct xseg_reply_map *mreply = (void *)io->mreq->data;
+ always_assert(mreply->cnt > 0);
+ //perr(PE, 0, "%llu %llu %llu mreply->target = %d\n", mreply->cnt, mreply->segs[0].size, mreply->segs[0].offset, mreply->segs[0].target[0]);
+
+ io->breqs_len = mreply->cnt;
+ io->breqs = calloc(io->breqs_len, sizeof(struct xseg_request *));
+ always_assert(io->breqs);
+ for (i = 0, pos = 0; i < mreply->cnt; i++) {
+ uint64_t datalen, offset, targetlen;
+ struct xseg_request *breq;
+
+ datalen = mreply->segs[i].size;
+ offset = mreply->segs[i].offset;
+ targetlen = strlen(mreply->segs[i].target);
+
+ breq = xseg_get_request(xseg, vportno);
+ always_assert(breq);
+ always_assert(datalen + targetlen <= breq->bufferlen);
+
+ ret = xseg_prep_request(xseg, breq, targetlen, datalen);
+ breq->datalen = datalen;
+ breq->offset = offset;
+ breq->size = datalen;
+ breq->op = io->vreq->op;
+ breq->priv = __idx_from_io(vlmcd, io); /* use the io's idx for tracking */
+ strncpy(breq->target, mreply->segs[i].target, targetlen);
+ /*
+ * Get the blocker to place data directly into vreq's
+ * buffer. FIXME: Manipulate ->data by hand?
+ */
+ breq->data = io->vreq->data + pos;
+ pos += datalen;
+
+ ret = xseg_submit(xseg, vlmcd->bportno, breq);
+ always_assert(ret != NoSerial);
+ /* possible race? */
+ io->breqs[i] = breq;
+ always_assert(xseg_signal(xseg, vlmcd->bportno) == 0);
+ }
+ io->breq_cnt = i;
+ ret = xseg_put_request(xseg, vportno, io->mreq);
+ always_assert(ret == 0);
+
+ io->state = SERVING;
+ }