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-version0.h>
38 /* version 0 functions */
39 #define v0_chunked_read_size (512*1024)
41 int read_object_v0(struct map_node *mn, unsigned char *buf)
43 hexlify(buf, SHA256_DIGEST_SIZE, mn->object);
44 mn->object[HEXLIFIED_SHA256_DIGEST_SIZE] = 0;
45 mn->objectlen = HEXLIFIED_SHA256_DIGEST_SIZE;
46 mn->flags = 0; //MF_OBJECT_WRITABLE;
51 void object_to_map_v0(unsigned char *data, struct map_node *mn)
53 unhexlify(mn->object, data);
54 //if name == zero block, raize MF_OBJECT_ZERO
57 struct xseg_request * prepare_write_object_v0(struct peer_req *pr, struct map *map,
60 struct peerd *peer = pr->peer;
61 struct mapperd *mapper = __get_mapperd(peer);
62 struct xseg_request *req;
64 req = get_request(pr, mapper->mbportno, map->volume, map->volumelen,
65 v0_objectsize_in_map);
67 XSEGLOG2(&lc, E, "Cannot get request for map %s",
73 req->size = v0_objectsize_in_map;
74 req->offset = v0_mapheader_size + mn->objectidx * v0_objectsize_in_map;
76 data = xseg_get_data(pr->peer->xseg, req);
77 object_to_map_v0((unsigned char *)data, mn);
81 int read_map_v0(struct map *m, unsigned char * data)
84 struct map_node *map_node;
86 uint64_t pos = 0, limit;
87 uint64_t max_read_obj = v0_chunked_read_size / v0_objectsize_in_map;
88 char nulls[SHA256_DIGEST_SIZE];
89 memset(nulls, 0, SHA256_DIGEST_SIZE);
91 r = !memcmp(data, nulls, SHA256_DIGEST_SIZE);
93 XSEGLOG2(&lc, E, "Read zeros");
98 map_node = realloc(m->objects,
99 (m->nr_objs + max_read_obj) * sizeof(struct map_node));
102 m->objects = map_node;
103 limit = m->nr_objs + max_read_obj;
104 for (i = m->nr_objs; i < limit; i++) {
105 if (!memcmp(data+pos, nulls, v0_objectsize_in_map))
107 map_node[i].objectidx = i;
109 map_node[i].waiters = 0;
110 map_node[i].state = 0;
112 map_node[i].cond = st_cond_new(); //FIXME err check;
113 read_object_v0(&map_node[i], data+pos);
114 pos += v0_objectsize_in_map;
116 XSEGLOG2(&lc, D, "Found %llu objects", i);
117 m->size = i * MAPPER_DEFAULT_BLOCKSIZE;
119 return (limit - m->nr_objs);
123 struct xseg_request * __write_map_data_v0(struct peer_req *pr, struct map *map)
126 struct peerd *peer = pr->peer;
127 struct mapperd *mapper = __get_mapperd(peer);
128 struct xseg_request *req;
130 uint64_t datalen, pos, i;
133 datalen = v0_mapheader_size + map->nr_objs * v0_objectsize_in_map;
134 req = get_request(pr, mapper->mbportno, map->volume, map->volumelen,
137 XSEGLOG2(&lc, E, "Cannot get request for map %s",
143 data = xseg_get_data(peer->xseg, req);
150 for (i = 0; i < map->nr_objs; i++) {
151 mn = &map->objects[i];
152 object_to_map_v0((unsigned char *)(data+pos), mn);
153 pos += v0_objectsize_in_map;
156 r = send_request(pr, req);
158 XSEGLOG2(&lc, E, "Cannot send request %p, pr: %p, map: %s",
159 req, pr, map->volume);
166 put_request(pr, req);
168 XSEGLOG2(&lc, E, "Map write for map %s failed.", map->volume);
172 int write_map_data_v0(struct peer_req *pr, struct map *map)
175 struct xseg_request *req = __write_map_data_v0(pr, map);
178 wait_on_pr(pr, (!(req->state & XS_FAILED || req->state & XS_SERVED)));
179 if (req->state & XS_FAILED)
181 put_request(pr, req);
186 int write_map_metadata_v0(struct peer_req *pr, struct map *map)
192 struct xseg_request * __load_map_data_v0(struct peer_req *pr, struct map *map)
195 struct xseg_request *req;
196 struct peerd *peer = pr->peer;
197 struct mapperd *mapper = __get_mapperd(peer);
200 if (v0_chunked_read_size % v0_objectsize_in_map) {
201 XSEGLOG2(&lc, E, "v0_chunked_read_size should be a multiple of",
202 "v0_objectsize_in_map");
206 datalen = v0_chunked_read_size;
208 req = get_request(pr, mapper->mbportno, map->volume, map->volumelen,
211 XSEGLOG2(&lc, E, "Cannot get request for map %s", map->volume);
217 req->offset = v0_mapheader_size + map->nr_objs * v0_objectsize_in_map;
219 r = send_request(pr, req);
221 XSEGLOG2(&lc, E, "Cannot send request %p, pr: %p, map: %s",
222 req, pr, map->volume);
228 put_request(pr, req);
233 int load_map_data_v0(struct peer_req *pr, struct map *map)
236 struct xseg_request *req;
237 struct peerd *peer = pr->peer;
241 req = __load_map_data_v0(pr, map);
244 wait_on_pr(pr, (!(req->state & XS_FAILED || req->state & XS_SERVED)));
246 if (req->state & XS_FAILED){
247 XSEGLOG2(&lc, E, "Map load failed for map %s", map->volume);
248 put_request(pr, req);
251 //assert req->service == req->size
252 data = xseg_get_data(peer->xseg, req);
253 r = read_map_v0(map, (unsigned char *)data);
254 put_request(pr, req);
260 int read_map_metadata_v0(struct map *map, unsigned char *metadata,
261 uint32_t metadata_len)
263 /* No header. Just set defaults */
266 map->blocksize = MAPPER_DEFAULT_BLOCKSIZE;
268 map->flags = MF_MAP_READONLY;