+static int load_map(struct peer_req *pr, struct map *map)
+{
+ int r = 0;
+ struct xseg_request *req;
+ struct peerd *peer = pr->peer;
+ map->flags |= MF_MAP_LOADING;
+ req = __load_map(pr, map);
+ if (!req)
+ return -1;
+ wait_on_pr(pr, (!(req->state & XS_FAILED || req->state & XS_SERVED)));
+ map->flags &= ~MF_MAP_LOADING;
+ if (req->state & XS_FAILED){
+ XSEGLOG2(&lc, E, "Map load failed for map %s", map->volume);
+ xseg_put_request(peer->xseg, req, pr->portno);
+ return -1;
+ }
+ r = read_map(map, xseg_get_data(peer->xseg, req));
+ xseg_put_request(peer->xseg, req, pr->portno);
+ return r;
+}
+
+static struct xseg_request * __open_map(struct peer_req *pr, struct map *m)
+{
+ int r;
+ xport p;
+ struct xseg_request *req;
+ struct peerd *peer = pr->peer;
+ struct mapperd *mapper = __get_mapperd(peer);
+ void *dummy;
+
+ XSEGLOG2(&lc, I, "Opening map %s", m->volume);
+
+ req = xseg_get_request(peer->xseg, pr->portno, mapper->mbportno, X_ALLOC);
+ if (!req){
+ XSEGLOG2(&lc, E, "Cannot allocate request for map %s",
+ m->volume);
+ goto out_fail;
+ }
+
+ r = xseg_prep_request(peer->xseg, req, m->volumelen, block_size);
+ if (r < 0){
+ XSEGLOG2(&lc, E, "Cannot prepare request for map %s",
+ m->volume);
+ goto out_put;
+ }
+
+ char *reqtarget = xseg_get_target(peer->xseg, req);
+ if (!reqtarget)
+ goto out_put;
+ strncpy(reqtarget, m->volume, req->targetlen);
+ req->op = X_OPEN;
+ req->size = block_size;
+ req->offset = 0;
+ r = xseg_set_req_data(peer->xseg, req, pr);
+ if (r < 0){
+ XSEGLOG2(&lc, E, "Cannot set request data for map %s",
+ m->volume);
+ goto out_put;
+ }
+ p = xseg_submit(peer->xseg, req, pr->portno, X_ALLOC);
+ if (p == NoPort){
+ XSEGLOG2(&lc, E, "Cannot submit request for map %s",
+ m->volume);
+ goto out_unset;
+ }
+ r = xseg_signal(peer->xseg, p);
+
+ XSEGLOG2(&lc, I, "Map %s opening", m->volume);
+ return req;
+
+out_unset:
+ xseg_get_req_data(peer->xseg, req, &dummy);
+out_put:
+ xseg_put_request(peer->xseg, req, pr->portno);
+out_fail:
+ return NULL;
+}
+
+static int open_map(struct peer_req *pr, struct map *map)
+{
+ int err;
+ struct xseg_request *req;
+ struct peerd *peer = pr->peer;
+
+ map->flags |= MF_MAP_OPENING;
+ req = __open_map(pr, map);
+ if (!req)
+ return -1;
+ wait_on_pr(pr, (!((req->state & XS_FAILED)||(req->state & XS_SERVED))));
+ map->flags &= ~MF_MAP_OPENING;
+ err = req->state & XS_FAILED;
+ xseg_put_request(peer->xseg, req, pr->portno);
+ if (err)
+ return -1;
+ else
+ map->flags |= MF_MAP_EXCLUSIVE;
+ return 0;
+}
+