2 * Copyright 2013 GRNET S.A. All rights reserved.
4 * Redistribution and use in source and binary forms, with or
5 * without modification, are permitted provided that the following
8 * 1. Redistributions of source code must retain the above
9 * copyright notice, this list of conditions and the following
11 * 2. Redistributions in binary form must reproduce the above
12 * copyright notice, this list of conditions and the following
13 * disclaimer in the documentation and/or other materials
14 * provided with the distribution.
16 * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
29 * The views and conclusions contained in the software and
30 * documentation are those of the authors and should not be
31 * interpreted as representing official policies, either expressed
32 * or implied, of GRNET S.A.
35 #include <xseg/xseg.h>
36 #include <mapper-version1.h>
40 int read_object_v1(struct map_node *mn, unsigned char *buf)
45 mn->flags |= MF_OBJECT_WRITABLE;
46 mn->flags |= MF_OBJECT_ARCHIP;
47 strcpy(mn->object, MAPPER_PREFIX);
48 hexlify(buf+1, SHA256_DIGEST_SIZE, mn->object + MAPPER_PREFIX_LEN);
49 mn->object[MAX_OBJECT_LEN] = 0;
50 mn->objectlen = strlen(mn->object);
53 mn->flags &= ~MF_OBJECT_WRITABLE;
54 mn->flags &= ~MF_OBJECT_ARCHIP;
55 hexlify(buf+1, SHA256_DIGEST_SIZE, mn->object);
56 mn->object[HEXLIFIED_SHA256_DIGEST_SIZE] = 0;
57 mn->objectlen = strlen(mn->object);
62 void object_to_map_v1(unsigned char* buf, struct map_node *mn)
64 buf[0] = (mn->flags & MF_OBJECT_WRITABLE)? 1 : 0;
65 //assert !(mn->flags & MF_OBJECT_ARCHIP)
67 /* strip common prefix */
68 unhexlify(mn->object+MAPPER_PREFIX_LEN, (unsigned char *)(buf+1));
71 unhexlify(mn->object, (unsigned char *)(buf+1));
73 //if name == zero block, raize MF_OBJECT_ZERO
76 struct xseg_request * prepare_write_object_v1(struct peer_req *pr, struct map *map,
79 struct peerd *peer = pr->peer;
80 struct mapperd *mapper = __get_mapperd(peer);
81 struct xseg_request *req;
84 req = get_request(pr, mapper->mbportno, map->volume, map->volumelen,
85 v1_objectsize_in_map);
87 XSEGLOG2(&lc, E, "Cannot get request for map %s",
93 req->size = v1_objectsize_in_map;
94 req->offset = v1_mapheader_size + mn->objectidx * v1_objectsize_in_map;
96 data = xseg_get_data(pr->peer->xseg, req);
97 object_to_map_v1((unsigned char *)data, mn);
101 int read_map_v1(struct map *m, unsigned char *data)
104 struct map_node *map_node;
107 uint64_t nr_objs = m->nr_objs;
108 char nulls[SHA256_DIGEST_SIZE];
109 memset(nulls, 0, SHA256_DIGEST_SIZE);
111 r = !memcmp(data, nulls, SHA256_DIGEST_SIZE);
113 XSEGLOG2(&lc, E, "Read zeros");
117 map_node = calloc(nr_objs, sizeof(struct map_node));
120 m->objects = map_node;
122 for (i = 0; i < nr_objs; i++) {
124 map_node[i].objectidx = i;
125 map_node[i].waiters = 0;
127 map_node[i].state = 0;
128 map_node[i].cond = st_cond_new(); //FIXME err check;
129 read_object_v1(&map_node[i], data+pos);
130 pos += v1_objectsize_in_map;
135 struct xseg_request * __write_map_data_v1(struct peer_req *pr, struct map *map)
138 struct peerd *peer = pr->peer;
139 struct mapperd *mapper = __get_mapperd(peer);
140 struct xseg_request *req;
145 req = get_request(pr, mapper->mbportno, map->volume, map->volumelen,
146 map->nr_objs * v1_objectsize_in_map);
148 XSEGLOG2(&lc, E, "Cannot get request for map %s",
154 data = xseg_get_data(peer->xseg, req);
157 req->size = req->datalen;
158 req->offset = v1_mapheader_size;
161 for (i = 0; i < map->nr_objs; i++) {
162 mn = &map->objects[i];
163 object_to_map_v1((unsigned char *)(data+pos), mn);
164 pos += v1_objectsize_in_map;
167 r = send_request(pr, req);
169 XSEGLOG2(&lc, E, "Cannot send request %p, pr: %p, map: %s",
170 req, pr, map->volume);
177 put_request(pr, req);
179 XSEGLOG2(&lc, E, "Map write for map %s failed.", map->volume);
183 int write_map_data_v1(struct peer_req *pr, struct map *map)
186 struct xseg_request *req = __write_map_data_v1(pr, map);
189 wait_on_pr(pr, (!(req->state & XS_FAILED || req->state & XS_SERVED)));
190 if (req->state & XS_FAILED)
192 put_request(pr, req);
196 struct xseg_request * __write_map_metadata_v1(struct peer_req *pr, struct map *map)
199 struct peerd *peer = pr->peer;
200 struct mapperd *mapper = __get_mapperd(peer);
201 struct xseg_request *req;
205 req = get_request(pr, mapper->mbportno, map->volume, map->volumelen,
208 XSEGLOG2(&lc, E, "Cannot get request for map %s",
214 data = xseg_get_data(peer->xseg, req);
217 memcpy(data + pos, &map->version, sizeof(map->version));
218 pos += sizeof(map->version);
219 memcpy(data + pos, &map->size, sizeof(map->size));
220 pos += sizeof(map->size);
223 req->size = req->datalen;
226 r = send_request(pr, req);
228 XSEGLOG2(&lc, E, "Cannot send request %p, pr: %p, map: %s",
229 req, pr, map->volume);
236 put_request(pr, req);
238 XSEGLOG2(&lc, E, "Map write for map %s failed.", map->volume);
241 int write_map_metadata_v1(struct peer_req *pr, struct map *map)
244 struct xseg_request *req = __write_map_metadata_v1(pr, map);
247 wait_on_pr(pr, (!(req->state & XS_FAILED || req->state & XS_SERVED)));
248 if (req->state & XS_FAILED)
250 put_request(pr, req);
254 struct xseg_request * __load_map_data_v1(struct peer_req *pr, struct map *map)
257 struct xseg_request *req;
258 struct peerd *peer = pr->peer;
259 struct mapperd *mapper = __get_mapperd(peer);
263 datalen = calc_map_obj(map) * v1_objectsize_in_map;
264 req = get_request(pr, mapper->mbportno, map->volume, map->volumelen,
267 XSEGLOG2(&lc, E, "Cannot get request for map %s", map->volume);
273 req->offset = v1_mapheader_size;
275 r = send_request(pr, req);
277 XSEGLOG2(&lc, E, "Cannot send request %p, pr: %p, map: %s",
278 req, pr, map->volume);
284 put_request(pr, req);
289 int load_map_data_v1(struct peer_req *pr, struct map *map)
292 struct xseg_request *req;
293 struct peerd *peer = pr->peer;
296 req = __load_map_data_v1(pr, map);
299 wait_on_pr(pr, (!(req->state & XS_FAILED || req->state & XS_SERVED)));
301 if (req->state & XS_FAILED){
302 XSEGLOG2(&lc, E, "Map load failed for map %s", map->volume);
303 put_request(pr, req);
306 //assert req->service == req->size
307 data = xseg_get_data(peer->xseg, req);
308 r = read_map_v1(map, (unsigned char *)data);
309 put_request(pr, req);
313 int read_map_metadata_v1(struct map *map, unsigned char *metadata,
314 uint32_t metadata_len)
317 if (metadata_len < v1_mapheader_size) {
318 XSEGLOG2(&lc, E, "Metadata len < v1_mapheader_size");
323 map->version = *(uint32_t *)(metadata + pos);
324 pos += sizeof(uint32_t);
325 map->size = *(uint64_t *)(metadata + pos);
326 pos += sizeof(uint64_t);
332 map->blocksize = MAPPER_DEFAULT_BLOCKSIZE;
333 map->nr_objs = calc_map_obj(map);;