liberasurecode 1.6.3
Erasure Code API library
Loading...
Searching...
No Matches
libphazr.c
Go to the documentation of this file.
1/*
2 * Copyright 2016 Phazr.IO Inc
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * Redistributions of source code must retain the above copyright notice, this
8 * list of conditions and the following disclaimer.
9 *
10 * Redistributions in binary form must reproduce the above copyright notice, this
11 * list of conditions and the following disclaimer in the documentation and/or
12 * other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY
13 * THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
14 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
16 * EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
17 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
18 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
20 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
21 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23 *
24 * Phazr.IO libphazr backend
25 *
26 * vi: set noai tw=79 ts=4 sw=4:
27 */
28
29#include <stdio.h>
30#include <stdlib.h>
31
32#include "erasurecode.h"
33#include "erasurecode_backend.h"
34#include "erasurecode_helpers.h"
35
36#define LIBPHAZR_LIB_MAJOR 1
37#define LIBPHAZR_LIB_MINOR 0
38#define LIBPHAZR_LIB_REV 0
39#define LIBPHAZR_LIB_VER_STR "1.0.0"
40#define LIBPHAZR_LIB_NAME "libphazr"
41#if defined(__MACOS__) || defined(__MACOSX__) || defined(__OSX__) || defined(__APPLE__)
42#define LIBPHAZR_SO_NAME "libphazr" LIBERASURECODE_SO_SUFFIX ".dylib"
43#else
44#define LIBPHAZR_SO_NAME "libphazr" LIBERASURECODE_SO_SUFFIX ".so.1"
45#endif
46
47/* Forward declarations */
48struct ec_backend libphazr;
49struct ec_backend_op_stubs libphazr_ops;
50struct ec_backend_common backend_libphazr;
51
52typedef int (*pio_matrix_encode_func)(char *, char *, char **, int, int, int, int, int, int);
53typedef int (*pio_matrix_decode_func)(char *, char *, char **, int *, int, int, int, int, int, int);
54typedef int (*pio_matrix_reconstruct_func)(char *, char **, int *, int, int, int, int, int, int);
55typedef char* (*pio_create_precoding_matrix_func)(int);
56typedef char* (*pio_create_inverse_precoding_matrix_func)(int);
57typedef char* (*pio_create_kmux_matrix_func)(int, int, int);
58
60 /* calls required for init */
64
65 /* calls required for encode */
67
68 /* calls required for decode */
70
71 /* calls required for reconstruct */
73
74 /* fields needed to hold state */
75 char *matrix;
78 int k;
79 int m;
80 int w;
81 int hd;
82};
83
84#define DEFAULT_W 64
85
86#define DEFAULT_HD 1
87
88static int get_padded_blocksize(int w, int hd, int blocksize)
89{
90 int word_size = w / 8;
91 return ((blocksize + ((word_size - hd) - 1)) / (word_size - hd)) * word_size;
92}
93
94static int pio_matrix_encode(void *desc, char **data, char **parity, int blocksize)
95{
96 int i, ret = 0;
97 struct libphazr_descriptor *xdesc = (struct libphazr_descriptor *) desc;
98 int padding_size = get_padded_blocksize(xdesc->w, xdesc->hd, blocksize) - blocksize;
99 char **encoded = malloc(sizeof(char*) * (xdesc->k + xdesc->m));
100
101 if (NULL == encoded) {
102 ret = -ENOMEM;
103 goto out;
104 }
105
106 for (i = 0; i < xdesc->k; i++) {
107 encoded[i] = data[i];
108 }
109
110 for (i = 0; i < xdesc->m; i++) {
111 encoded[i + xdesc->k] = parity[i];
112 }
113
114 ret = xdesc->matrix_encode(xdesc->precoding_matrix, xdesc->matrix, encoded,
115 xdesc->k, xdesc->m, xdesc->w, xdesc->hd, blocksize, padding_size);
116
117out:
118 free(encoded);
119
120 return ret;
121}
122
123static int pio_matrix_decode(void *desc, char **data, char **parity,
124 int *missing_idxs, int blocksize)
125{
126 int i, ret = 0;
127 struct libphazr_descriptor *xdesc = (struct libphazr_descriptor *) desc;
128 int padding_size = get_padded_blocksize(xdesc->w, xdesc->hd, blocksize) - blocksize;
129 char **decoded = malloc(sizeof(char*) * (xdesc->k + xdesc->m));
130
131 if (NULL == decoded) {
132 ret = -ENOMEM;
133 goto out;
134 }
135
136 for (i = 0; i < xdesc->k; i++) {
137 decoded[i] = data[i];
138 }
139
140 for (i = 0; i < xdesc->m; i++) {
141 decoded[i + xdesc->k] = parity[i];
142 }
143
144 ret = xdesc->matrix_decode(xdesc->inverse_precoding_matrix, xdesc->matrix, decoded,
145 missing_idxs, xdesc->k, xdesc->m, xdesc->w, xdesc->hd, blocksize, padding_size);
146
147out:
148 free(decoded);
149
150 return ret;
151}
152
153static int pio_matrix_reconstruct(void *desc, char **data, char **parity,
154 int *missing_idxs, int destination_idx, int blocksize)
155{
156 int i, ret = 0;
157 struct libphazr_descriptor *xdesc = (struct libphazr_descriptor *) desc;
158 int padding_size = get_padded_blocksize(xdesc->w, xdesc->hd, blocksize) - blocksize;
159 char **encoded = malloc(sizeof(char*) * (xdesc->k + xdesc->m));
160
161 if (NULL == encoded) {
162 ret = -ENOMEM;
163 goto out;
164 }
165
166 for (i = 0; i < xdesc->k; i++) {
167 encoded[i] = data[i];
168 }
169
170 for (i = 0; i < xdesc->m; i++) {
171 encoded[i + xdesc->k] = parity[i];
172 }
173
174 ret = xdesc->matrix_reconstruct(xdesc->matrix, encoded, missing_idxs,
175 destination_idx, xdesc->k, xdesc->m, xdesc->w, blocksize, padding_size);
176
177out:
178 free(encoded);
179
180 return ret;
181}
182
183static int pio_min_fragments(void *desc, int *missing_idxs,
184 int *fragments_to_exclude, int *fragments_needed)
185{
186 struct libphazr_descriptor *xdesc = (struct libphazr_descriptor *)desc;
187 uint64_t exclude_bm = convert_list_to_bitmap(fragments_to_exclude);
188 uint64_t missing_bm = convert_list_to_bitmap(missing_idxs) | exclude_bm;
189 int i;
190 int j = 0;
191 int ret = -1;
192
193 for (i = 0; i < (xdesc->k + xdesc->m); i++) {
194 if (!(missing_bm & (1 << i))) {
195 fragments_needed[j] = i;
196 j++;
197 }
198 if (j == xdesc->k) {
199 ret = 0;
200 fragments_needed[j] = -1;
201 break;
202 }
203 }
204
205 return ret;
206}
207
212static int pio_element_size(void *desc)
213{
214 struct libphazr_descriptor *xdesc = (struct libphazr_descriptor *)desc;
215
216 return xdesc->w;
217}
218
219static void * pio_init(struct ec_backend_args *args, void *backend_sohandle)
220{
221 struct libphazr_descriptor *desc = NULL;
222
223 /* allocate and fill in libphazr_descriptor */
224 desc = (struct libphazr_descriptor *)malloc(sizeof(struct libphazr_descriptor));
225 if (NULL == desc) {
226 return NULL;
227 }
228 memset(desc, 0, sizeof(struct libphazr_descriptor));
229
230 desc->k = args->uargs.k;
231 desc->m = args->uargs.m;
232 desc->w = args->uargs.w;
233 desc->hd = args->uargs.hd;
234
235 if (desc->w <= 0)
236 desc->w = DEFAULT_W;
237 args->uargs.w = desc->w;
238
239 if (desc->hd <= 0)
240 desc->hd = DEFAULT_HD;
241 args->uargs.hd = desc->hd;
242
243 /*
244 * ISO C forbids casting a void* to a function pointer.
245 * Since dlsym return returns a void*, we use this union to
246 * "transform" the void* to a function pointer.
247 */
248 union {
249 pio_create_precoding_matrix_func create_precoding_matrix_ptr;
250 pio_create_inverse_precoding_matrix_func create_inverse_precoding_matrix_ptr;
251 pio_create_kmux_matrix_func create_kmux_matrix_ptr;
252 pio_matrix_encode_func matrix_encode_ptr;
253 pio_matrix_decode_func matrix_decode_ptr;
254 pio_matrix_reconstruct_func matrix_reconstruct_ptr;
255 void *vptr;
256 } func_handle = {.vptr = NULL};
257
258 /* fill in function addresses */
259 func_handle.vptr = NULL;
260 func_handle.vptr = dlsym(backend_sohandle, "create_precoding_matrix");
261 desc->create_precoding_matrix = func_handle.create_precoding_matrix_ptr;
262 if (NULL == desc->create_precoding_matrix) {
263 goto error;
264 }
265
266 func_handle.vptr = NULL;
267 func_handle.vptr = dlsym(backend_sohandle, "create_inverse_precoding_matrix");
268 desc->create_inverse_precoding_matrix = func_handle.create_inverse_precoding_matrix_ptr;
269 if (NULL == desc->create_inverse_precoding_matrix) {
270 goto error;
271 }
272
273 func_handle.vptr = NULL;
274 func_handle.vptr = dlsym(backend_sohandle, "create_kmux_matrix");
275 desc->create_kmux_matrix = func_handle.create_kmux_matrix_ptr;
276 if (NULL == desc->create_kmux_matrix) {
277 goto error;
278 }
279
280 func_handle.vptr = NULL;
281 func_handle.vptr = dlsym(backend_sohandle, "matrix_encode");
282 desc->matrix_encode = func_handle.matrix_encode_ptr;
283 if (NULL == desc->matrix_encode) {
284 goto error;
285 }
286
287 func_handle.vptr = NULL;
288 func_handle.vptr = dlsym(backend_sohandle, "matrix_decode");
289 desc->matrix_decode = func_handle.matrix_decode_ptr;
290 if (NULL == desc->matrix_decode) {
291 goto error;
292 }
293
294 func_handle.vptr = NULL;
295 func_handle.vptr = dlsym(backend_sohandle, "matrix_reconstruct");
296 desc->matrix_reconstruct = func_handle.matrix_reconstruct_ptr;
297 if (NULL == desc->matrix_reconstruct) {
298 goto error;
299 }
300
301 if (NULL == desc->precoding_matrix) {
302 desc->precoding_matrix = desc->create_precoding_matrix(desc->k);
303 if (NULL == desc->precoding_matrix) {
304 goto error;
305 }
306 }
307
308 if (NULL == desc->inverse_precoding_matrix) {
310 if (NULL == desc->inverse_precoding_matrix) {
311 goto error;
312 }
313 }
314
315 if (NULL == desc->matrix) {
316 desc->matrix = desc->create_kmux_matrix(desc->k, desc->m, desc->w);
317 if (NULL == desc->create_kmux_matrix) {
318 goto error;
319 }
320 }
321
322 return (void *) desc;
323
324error:
325 free(desc->matrix);
326
327 free(desc->precoding_matrix);
328
329 free(desc->inverse_precoding_matrix);
330
331 free(desc);
332
333 return NULL;
334}
335
336static int pio_exit(void *desc)
337{
338 struct libphazr_descriptor *xdesc = (struct libphazr_descriptor*)desc;
339
340 free(xdesc->matrix);
341
342 free(xdesc->precoding_matrix);
343
344 free(xdesc->inverse_precoding_matrix);
345
346 free(xdesc);
347
348 return 0;
349}
350
351static bool pio_is_compatible_with(uint32_t version)
352{
353 return version == backend_libphazr.ec_backend_version;
354}
355
356static size_t pio_get_backend_metadata_size(void *desc, int blocksize)
357{
358 struct libphazr_descriptor *xdesc = (struct libphazr_descriptor *) desc;
359 int padded_blocksize = get_padded_blocksize(xdesc->w, xdesc->hd, blocksize);
360 return padded_blocksize - blocksize;
361}
362
363static size_t pio_get_encode_offset(void *desc, int metadata_size)
364{
365 return metadata_size;
366}
367
368
369struct ec_backend_op_stubs libphazr_op_stubs = {
370 .INIT = pio_init,
371 .EXIT = pio_exit,
372 .ENCODE = pio_matrix_encode,
373 .DECODE = pio_matrix_decode,
374 .FRAGSNEEDED = pio_min_fragments,
375 .RECONSTRUCT = pio_matrix_reconstruct,
376 .ELEMENTSIZE = pio_element_size,
377 .ISCOMPATIBLEWITH = pio_is_compatible_with,
378 .GETMETADATASIZE = pio_get_backend_metadata_size,
379 .GETENCODEOFFSET = pio_get_encode_offset,
380};
381
382struct ec_backend_common backend_libphazr = {
383 .id = EC_BACKEND_LIBPHAZR,
384 .name = LIBPHAZR_LIB_NAME,
385 .soname = LIBPHAZR_SO_NAME,
386 .soversion = LIBPHAZR_LIB_VER_STR,
387 .ops = &libphazr_op_stubs,
388 .ec_backend_version = _VERSION(LIBPHAZR_LIB_MAJOR, LIBPHAZR_LIB_MINOR,
390};
391
static void * pio_init(struct ec_backend_args *args, void *backend_sohandle)
Definition libphazr.c:219
static int pio_matrix_decode(void *desc, char **data, char **parity, int *missing_idxs, int blocksize)
Definition libphazr.c:123
#define LIBPHAZR_LIB_VER_STR
Definition libphazr.c:39
static int pio_matrix_reconstruct(void *desc, char **data, char **parity, int *missing_idxs, int destination_idx, int blocksize)
Definition libphazr.c:153
struct ec_backend libphazr
Definition libphazr.c:48
static int pio_element_size(void *desc)
Return the element-size, which is the number of bits stored on a given device, per codeword.
Definition libphazr.c:212
char *(* pio_create_inverse_precoding_matrix_func)(int)
Definition libphazr.c:56
static int pio_matrix_encode(void *desc, char **data, char **parity, int blocksize)
Definition libphazr.c:94
#define LIBPHAZR_SO_NAME
Definition libphazr.c:44
static int pio_min_fragments(void *desc, int *missing_idxs, int *fragments_to_exclude, int *fragments_needed)
Definition libphazr.c:183
static bool pio_is_compatible_with(uint32_t version)
Definition libphazr.c:351
#define LIBPHAZR_LIB_REV
Definition libphazr.c:38
struct ec_backend_op_stubs libphazr_ops
Definition libphazr.c:49
#define DEFAULT_HD
Definition libphazr.c:86
int(* pio_matrix_decode_func)(char *, char *, char **, int *, int, int, int, int, int, int)
Definition libphazr.c:53
static size_t pio_get_backend_metadata_size(void *desc, int blocksize)
Definition libphazr.c:356
int(* pio_matrix_encode_func)(char *, char *, char **, int, int, int, int, int, int)
Definition libphazr.c:52
char *(* pio_create_kmux_matrix_func)(int, int, int)
Definition libphazr.c:57
#define LIBPHAZR_LIB_NAME
Definition libphazr.c:40
static int get_padded_blocksize(int w, int hd, int blocksize)
Definition libphazr.c:88
struct ec_backend_common backend_libphazr
Definition libphazr.c:50
static size_t pio_get_encode_offset(void *desc, int metadata_size)
Definition libphazr.c:363
#define LIBPHAZR_LIB_MINOR
Definition libphazr.c:37
char *(* pio_create_precoding_matrix_func)(int)
Definition libphazr.c:55
int(* pio_matrix_reconstruct_func)(char *, char **, int *, int, int, int, int, int, int)
Definition libphazr.c:54
static int pio_exit(void *desc)
Definition libphazr.c:336
#define LIBPHAZR_LIB_MAJOR
Definition libphazr.c:36
struct ec_backend_op_stubs libphazr_op_stubs
Definition libphazr.c:369
#define DEFAULT_W
Definition libphazr.c:84
pio_matrix_decode_func matrix_decode
Definition libphazr.c:69
pio_create_kmux_matrix_func create_kmux_matrix
Definition libphazr.c:63
pio_create_inverse_precoding_matrix_func create_inverse_precoding_matrix
Definition libphazr.c:62
char * inverse_precoding_matrix
Definition libphazr.c:77
pio_matrix_reconstruct_func matrix_reconstruct
Definition libphazr.c:72
pio_create_precoding_matrix_func create_precoding_matrix
Definition libphazr.c:61
pio_matrix_encode_func matrix_encode
Definition libphazr.c:66
char * precoding_matrix
Definition libphazr.c:76