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.
40 #include <xseg/xseg.h>
43 #include <xseg/protocol.h>
45 /* general mapper flags */
46 #define MF_LOAD (1 << 0)
47 #define MF_EXCLUSIVE (1 << 1)
48 #define MF_FORCE (1 << 2)
49 #define MF_ARCHIP (1 << 3)
51 #define MAPPER_DEFAULT_BLOCKSIZE (1<<22)
53 #define MAPPER_PREFIX "archip_"
54 #define MAPPER_PREFIX_LEN 7
56 /* These values come straight from the size of map_node->objectidx and
59 #define HEXLIFIED_EPOCH (sizeof(uint64_t) << 1)
60 #define HEXLIFIED_INDEX (sizeof(uint64_t) << 1)
62 /* should always be the maximum objectlen of all versions */
63 #define MAX_OBJECT_LEN 128
65 /* since object names are cacluclated from the volume names, the limit of the
66 * maximum volume len is calculated from the maximum object len, statically for
69 * How the object name is calculated is reflected in this formula:
73 #define MAX_VOLUME_LEN (MAX_OBJECT_LEN - HEXLIFIED_INDEX - HEXLIFIED_EPOCH - 2)
75 /* Compile time limits */
76 #if MAX_OBJECT_LEN > XSEG_MAX_TARGETLEN
77 #error "XSEG_MAX_TARGETLEN should be at least MAX_OBJECT_LEN"
81 #if MAX_VOLUME_LEN > XSEG_MAX_TARGETLEN
82 #error "XSEG_MAX_TARGETLEN should be at least MAX_VOLUME_LEN"
87 extern char *zero_block;
88 #define ZERO_BLOCK_LEN (64) /* strlen(zero_block) */
90 /* callback function type */
91 typedef void (*cb_t)(struct peer_req *pr, struct xseg_request *req);
94 /* map object flags */
95 #define MF_OBJECT_WRITABLE (1 << 0)
96 #define MF_OBJECT_ARCHIP (1 << 1)
97 #define MF_OBJECT_ZERO (1 << 2)
99 /* run time map object state flags */
100 #define MF_OBJECT_COPYING (1 << 0)
101 #define MF_OBJECT_WRITING (1 << 1)
102 #define MF_OBJECT_DELETING (1 << 2)
103 //#define MF_OBJECT_DESTROYED (1 << 3)
104 #define MF_OBJECT_SNAPSHOTTING (1 << 4)
106 #define MF_OBJECT_NOT_READY (MF_OBJECT_COPYING|MF_OBJECT_WRITING|\
107 MF_OBJECT_DELETING|MF_OBJECT_SNAPSHOTTING)
110 volatile uint32_t state;
111 uint64_t objectidx; /* FIXME this is probably not needed */
113 char object[MAX_OBJECT_LEN + 1]; /* NULL terminated string */
115 volatile uint32_t ref;
116 volatile uint32_t waiters;
122 #define MF_MAP_READONLY (1 << 0)
123 #define MF_MAP_DELETED (1 << 1)
125 /* run time map state flags */
126 #define MF_MAP_LOADING (1 << 0)
127 #define MF_MAP_DESTROYED (1 << 1)
128 #define MF_MAP_WRITING (1 << 2)
129 #define MF_MAP_DELETING (1 << 3)
130 #define MF_MAP_DROPPING_CACHE (1 << 4)
131 #define MF_MAP_EXCLUSIVE (1 << 5)
132 #define MF_MAP_OPENING (1 << 6)
133 #define MF_MAP_CLOSING (1 << 7)
134 //#define MF_MAP_DELETED (1 << 8)
135 #define MF_MAP_SNAPSHOTTING (1 << 9)
136 #define MF_MAP_SERIALIZING (1 << 10)
137 #define MF_MAP_HASHING (1 << 11)
138 #define MF_MAP_NOT_READY (MF_MAP_LOADING|MF_MAP_WRITING|MF_MAP_DELETING|\
139 MF_MAP_DROPPING_CACHE|MF_MAP_OPENING| \
140 MF_MAP_SNAPSHOTTING|MF_MAP_SERIALIZING| \
147 volatile uint32_t state;
152 char volume[MAX_VOLUME_LEN + 1]; /* NULL terminated string */
153 struct map_node *objects;
154 volatile uint32_t ref;
155 volatile uint32_t waiters;
158 volatile uint32_t users;
159 volatile uint32_t waiters_users;
160 st_cond_t users_cond;
164 xport bportno; /* blocker that accesses data */
165 xport mbportno; /* blocker that accesses maps */
166 xhash_t *hashmaps; // hash_function(target) --> struct map
170 xhash_t *copyups_nodes; /* hash map (xseg_request) --> (corresponding map_node of copied up object)*/
171 volatile int err; /* error flag */
175 volatile uint64_t pending_reqs;
178 /* usefull abstraction macros for context switching */
180 #define wait_on_pr(__pr, __condition__) \
183 __get_mapper_io(pr)->active = 0;\
184 XSEGLOG2(&lc, D, "Waiting on pr %lx, ta: %u", pr, ta); \
185 st_cond_wait(__pr->cond); \
186 } while (__condition__)
188 #define wait_on_mapnode(__mn, __condition__) \
192 XSEGLOG2(&lc, D, "Waiting on map node %lx %s, waiters: %u, \
193 ta: %u", __mn, __mn->object, __mn->waiters, ta); \
194 st_cond_wait(__mn->cond); \
195 } while (__condition__)
197 #define wait_on_map(__map, __condition__) \
201 XSEGLOG2(&lc, D, "Waiting on map %lx %s, waiters: %u, ta: %u",\
202 __map, __map->volume, __map->waiters, ta); \
203 st_cond_wait(__map->cond); \
204 } while (__condition__)
206 #define wait_all_objects_ready(__map) \
209 __map->waiters_users++; \
210 XSEGLOG2(&lc, D, "Waiting for objects ready on map %lx %s, waiters: %u, ta: %u",\
211 __map, __map->volume, __map->waiters_users, ta); \
212 st_cond_wait(__map->users_cond); \
213 } while (__map->users)
215 #define signal_pr(__pr) \
217 if (!__get_mapper_io(pr)->active){\
219 XSEGLOG2(&lc, D, "Signaling pr %lx, ta: %u", pr, ta);\
220 __get_mapper_io(pr)->active = 1;\
221 st_cond_signal(__pr->cond); \
225 #define signal_map(__map) \
227 XSEGLOG2(&lc, D, "Checking map %lx %s. Waiters %u, ta: %u", \
228 __map, __map->volume, __map->waiters, ta); \
229 if (__map->waiters) { \
230 ta += __map->waiters; \
231 XSEGLOG2(&lc, D, "Signaling map %lx %s, waiters: %u, \
232 ta: %u", __map, __map->volume, __map->waiters, ta); \
233 __map->waiters = 0; \
234 st_cond_broadcast(__map->cond); \
238 #define signal_all_objects_ready(__map) \
240 /* assert __map->users == 0 */ \
241 if (__map->waiters_users) { \
242 ta += __map->waiters_users; \
243 XSEGLOG2(&lc, D, "Signaling objects ready for map %lx %s, waiters: %u, \
244 ta: %u", __map, __map->volume, __map->waiters_users, ta); \
245 __map->waiters_users = 0; \
246 st_cond_broadcast(__map->users_cond); \
250 #define signal_mapnode(__mn) \
252 if (__mn->waiters) { \
253 ta += __mn->waiters; \
254 XSEGLOG2(&lc, D, "Signaling map node %lx %s, waiters: \
255 %u, ta: %u", __mn, __mn->object, __mn->waiters, ta); \
257 st_cond_broadcast(__mn->cond); \
262 /* Helper functions */
263 static inline struct mapperd * __get_mapperd(struct peerd *peer)
265 return (struct mapperd *) peer->priv;
268 static inline struct mapper_io * __get_mapper_io(struct peer_req *pr)
270 return (struct mapper_io *) pr->priv;
273 static inline uint64_t calc_map_obj(struct map *map)
277 nr_objs = map->size / map->blocksize;
278 if (map->size % map->blocksize)
284 /* map handling functions */
285 struct xseg_request * __open_map(struct peer_req *pr, struct map *m,
287 int open_map(struct peer_req *pr, struct map *map, uint32_t flags);
288 struct xseg_request * __close_map(struct peer_req *pr, struct map *map);
289 int close_map(struct peer_req *pr, struct map *map);
290 struct xseg_request * __write_map(struct peer_req* pr, struct map *map);
291 int write_map(struct peer_req* pr, struct map *map);
292 int write_map_metadata(struct peer_req* pr, struct map *map);
293 struct xseg_request * __load_map(struct peer_req *pr, struct map *m);
294 int read_map(struct map *map, unsigned char *buf);
295 int load_map(struct peer_req *pr, struct map *map);
296 struct xseg_request * __copyup_object(struct peer_req *pr, struct map_node *mn);
297 void copyup_cb(struct peer_req *pr, struct xseg_request *req);
298 struct xseg_request * __object_write(struct peerd *peer, struct peer_req *pr,
299 struct map *map, struct map_node *mn);
300 int __set_node(struct mapper_io *mio, struct xseg_request *req,
301 struct map_node *mn);
302 struct map_node * __get_node(struct mapper_io *mio, struct xseg_request *req);
303 int send_request(struct peer_req *pr, struct xseg_request *req);
304 struct xseg_request * get_request(struct peer_req *pr, xport dst, char * target,
305 uint32_t targetlen, uint64_t datalen);
306 void put_request(struct peer_req *pr, struct xseg_request *req);
307 struct xseg_request * __load_map_metadata(struct peer_req *pr, struct map *map);
308 int load_map_metadata(struct peer_req *pr, struct map *map);
309 int initialize_map_objects(struct map *map);
310 int hash_map(struct peer_req *pr, struct map *map, struct map *hashed_map);
311 struct map_node * get_mapnode(struct map *map, uint64_t objindex);
312 void put_mapnode(struct map_node *mn);
313 #endif /* end MAPPER_H */