liberasurecode  1.6.2
Erasure Code API library
liberasurecode_rs_vand.c
Go to the documentation of this file.
1 /*
2  * Copyright 2015 Kevin M Greenan
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  * vi: set noai tw=79 ts=4 sw=4:
25  */
26 
27 #include <stdio.h>
28 #include <stdlib.h>
29 
30 #include "erasurecode.h"
31 #include "erasurecode_backend.h"
32 #include "erasurecode_helpers.h"
33 #include "erasurecode_helpers_ext.h"
34 
35 #define LIBERASURECODE_RS_VAND_LIB_MAJOR 1
36 #define LIBERASURECODE_RS_VAND_LIB_MINOR 0
37 #define LIBERASURECODE_RS_VAND_LIB_REV 0
38 #define LIBERASURECODE_RS_VAND_LIB_VER_STR "1.0"
39 #define LIBERASURECODE_RS_VAND_LIB_NAME "liberasurecode_rs_vand"
40 #if defined(__MACOS__) || defined(__MACOSX__) || defined(__OSX__) || defined(__APPLE__)
41 #define LIBERASURECODE_RS_VAND_SO_NAME "liberasurecode_rs_vand.dylib"
42 #else
43 #define LIBERASURECODE_RS_VAND_SO_NAME "liberasurecode_rs_vand.so.1"
44 #endif
45 
46 /* Forward declarations */
47 struct ec_backend_op_stubs liberasurecode_rs_vand_ops;
48 struct ec_backend liberasurecode_rs_vand;
49 struct ec_backend_common backend_liberasurecode_rs_vand;
50 
51 typedef int (*liberasurecode_rs_vand_encode_func)(int *, char **, char **, int, int, int);
52 typedef int (*liberasurecode_rs_vand_decode_func)(int *, char **, char **, int, int, int *, int, int);
53 typedef int (*liberasurecode_rs_vand_reconstruct_func)(int *, char **, char **, int, int, int *, int, int);
54 typedef void (*init_liberasurecode_rs_vand_func)(int, int);
56 typedef void (*free_systematic_matrix_func)(int *);
57 typedef int* (*make_systematic_matrix_func)(int, int);
58 
59 
61  /* calls required for init */
66 
67  /* calls required for encode */
69 
70  /* calls required for decode */
72 
73  /* calls required for reconstruct */
75 
76  /* fields needed to hold state */
77  int *matrix;
78  int k;
79  int m;
80  int w;
81 };
82 
83 static int liberasurecode_rs_vand_encode(void *desc, char **data, char **parity,
84  int blocksize)
85 {
86  struct liberasurecode_rs_vand_descriptor *rs_vand_desc =
87  (struct liberasurecode_rs_vand_descriptor*) desc;
88 
89  /* FIXME: Should this return something? */
90  rs_vand_desc->liberasurecode_rs_vand_encode(rs_vand_desc->matrix, data, parity,
91  rs_vand_desc->k, rs_vand_desc->m, blocksize);
92  return 0;
93 }
94 
95 static int liberasurecode_rs_vand_decode(void *desc, char **data, char **parity,
96  int *missing_idxs, int blocksize)
97 {
98  struct liberasurecode_rs_vand_descriptor *rs_vand_desc =
99  (struct liberasurecode_rs_vand_descriptor*) desc;
100 
101  /* FIXME: Should this return something? */
102  rs_vand_desc->liberasurecode_rs_vand_decode(rs_vand_desc->matrix, data, parity,
103  rs_vand_desc->k, rs_vand_desc->m, missing_idxs, blocksize, 1);
104 
105  return 0;
106 }
107 
108 static int liberasurecode_rs_vand_reconstruct(void *desc, char **data, char **parity,
109  int *missing_idxs, int destination_idx, int blocksize)
110 {
111  struct liberasurecode_rs_vand_descriptor *rs_vand_desc =
112  (struct liberasurecode_rs_vand_descriptor*) desc;
113 
114  /* FIXME: Should this return something? */
115  rs_vand_desc->liberasurecode_rs_vand_reconstruct(rs_vand_desc->matrix, data, parity,
116  rs_vand_desc->k, rs_vand_desc->m, missing_idxs, destination_idx, blocksize);
117 
118  return 0;
119 }
120 
121 static int liberasurecode_rs_vand_min_fragments(void *desc, int *missing_idxs,
122  int *fragments_to_exclude, int *fragments_needed)
123 {
124  struct liberasurecode_rs_vand_descriptor *rs_vand_desc =
125  (struct liberasurecode_rs_vand_descriptor*)desc;
126 
127  uint64_t exclude_bm = convert_list_to_bitmap(fragments_to_exclude);
128  uint64_t missing_bm = convert_list_to_bitmap(missing_idxs) | exclude_bm;
129  int i;
130  int j = 0;
131  int ret = -1;
132 
133  for (i = 0; i < (rs_vand_desc->k + rs_vand_desc->m); i++) {
134  if (!(missing_bm & (1 << i))) {
135  fragments_needed[j] = i;
136  j++;
137  }
138  if (j == rs_vand_desc->k) {
139  ret = 0;
140  fragments_needed[j] = -1;
141  break;
142  }
143  }
144 
145  return ret;
146 }
147 
148 static void * liberasurecode_rs_vand_init(struct ec_backend_args *args,
149  void *backend_sohandle)
150 {
151  struct liberasurecode_rs_vand_descriptor *desc = NULL;
152 
153  desc = (struct liberasurecode_rs_vand_descriptor *)
154  malloc(sizeof(struct liberasurecode_rs_vand_descriptor));
155  if (NULL == desc) {
156  return NULL;
157  }
158 
159  desc->k = args->uargs.k;
160  desc->m = args->uargs.m;
161 
162  /* store w back in args so upper layer can get to it */
163  args->uargs.w = desc->w = 16; // w is currently hard-coded at 16
164 
165  // This check should not matter, since 64K is way higher
166  // than anyone should ever use
167  if ((desc->k + desc->m) > 65536) {
168  goto error;
169  }
170 
171  /*
172  * ISO C forbids casting a void* to a function pointer.
173  * Since dlsym return returns a void*, we use this union to
174  * "transform" the void* to a function pointer.
175  */
176  union {
179  free_systematic_matrix_func freematrixp;
180  make_systematic_matrix_func makematrixp;
184  void *vptr;
185  } func_handle = {.vptr = NULL};
186 
187 
188  /* fill in function addresses */
189  func_handle.vptr = NULL;
190  func_handle.vptr = dlsym(backend_sohandle, "init_liberasurecode_rs_vand");
191  desc->init_liberasurecode_rs_vand = func_handle.initp;
192  if (NULL == desc->init_liberasurecode_rs_vand) {
193  goto error;
194  }
195 
196  func_handle.vptr = NULL;
197  func_handle.vptr = dlsym(backend_sohandle, "deinit_liberasurecode_rs_vand");
198  desc->deinit_liberasurecode_rs_vand = func_handle.deinitp;
199  if (NULL == desc->deinit_liberasurecode_rs_vand) {
200  goto error;
201  }
202 
203  func_handle.vptr = NULL;
204  func_handle.vptr = dlsym(backend_sohandle, "make_systematic_matrix");
205  desc->make_systematic_matrix = func_handle.makematrixp;
206  if (NULL == desc->make_systematic_matrix) {
207  goto error;
208  }
209 
210  func_handle.vptr = NULL;
211  func_handle.vptr = dlsym(backend_sohandle, "free_systematic_matrix");
212  desc->free_systematic_matrix = func_handle.freematrixp;
213  if (NULL == desc->free_systematic_matrix) {
214  goto error;
215  }
216 
217  func_handle.vptr = NULL;
218  func_handle.vptr = dlsym(backend_sohandle, "liberasurecode_rs_vand_encode");
219  desc->liberasurecode_rs_vand_encode = func_handle.encodep;
220  if (NULL == desc->liberasurecode_rs_vand_encode) {
221  goto error;
222  }
223 
224  func_handle.vptr = NULL;
225  func_handle.vptr = dlsym(backend_sohandle, "liberasurecode_rs_vand_decode");
226  desc->liberasurecode_rs_vand_decode = func_handle.decodep;
227  if (NULL == desc->liberasurecode_rs_vand_decode) {
228  goto error;
229  }
230 
231  func_handle.vptr = NULL;
232  func_handle.vptr = dlsym(backend_sohandle, "liberasurecode_rs_vand_reconstruct");
233  desc->liberasurecode_rs_vand_reconstruct = func_handle.reconstructp;
234  if (NULL == desc->liberasurecode_rs_vand_reconstruct) {
235  goto error;
236  }
237 
238  desc->init_liberasurecode_rs_vand(desc->k, desc->m);
239 
240  desc->matrix = desc->make_systematic_matrix(desc->k, desc->m);
241 
242  if (NULL == desc->matrix) {
243  goto error;
244  }
245 
246  return desc;
247 
248 error:
249  free(desc);
250 
251  return NULL;
252 }
253 
261 static int
263 {
264  struct liberasurecode_rs_vand_descriptor *rs_vand_desc = NULL;
265 
266  rs_vand_desc = (struct liberasurecode_rs_vand_descriptor*) desc;
267 
268  return rs_vand_desc->w;
269 }
270 
271 static int liberasurecode_rs_vand_exit(void *desc)
272 {
273  struct liberasurecode_rs_vand_descriptor *rs_vand_desc = NULL;
274 
275  rs_vand_desc = (struct liberasurecode_rs_vand_descriptor*) desc;
276 
277  rs_vand_desc->free_systematic_matrix(rs_vand_desc->matrix);
278  rs_vand_desc->deinit_liberasurecode_rs_vand();
279  free(rs_vand_desc);
280 
281  return 0;
282 }
283 
284 /*
285  * For the time being, we only claim compatibility with versions that
286  * match exactly
287  */
288 static bool liberasurecode_rs_vand_is_compatible_with(uint32_t version) {
289  return version == backend_liberasurecode_rs_vand.ec_backend_version;
290 }
291 
292 struct ec_backend_op_stubs liberasurecode_rs_vand_op_stubs = {
298  .RECONSTRUCT = liberasurecode_rs_vand_reconstruct,
300  .ISCOMPATIBLEWITH = liberasurecode_rs_vand_is_compatible_with,
301  .GETMETADATASIZE = get_backend_metadata_size_zero,
302  .GETENCODEOFFSET = get_encode_offset_zero,
303 };
304 
305 struct ec_backend_common backend_liberasurecode_rs_vand = {
306  .id = EC_BACKEND_LIBERASURECODE_RS_VAND,
311  .ec_backend_version = _VERSION(LIBERASURECODE_RS_VAND_LIB_MAJOR,
314 };
liberasurecode_rs_vand_descriptor::matrix
int * matrix
Definition: liberasurecode_rs_vand.c:77
liberasurecode_rs_vand_descriptor::w
int w
Definition: liberasurecode_rs_vand.c:80
liberasurecode_rs_vand_descriptor::m
int m
Definition: liberasurecode_rs_vand.c:79
liberasurecode_rs_vand_min_fragments
static int liberasurecode_rs_vand_min_fragments(void *desc, int *missing_idxs, int *fragments_to_exclude, int *fragments_needed)
Definition: liberasurecode_rs_vand.c:121
liberasurecode_rs_vand_encode
static int liberasurecode_rs_vand_encode(void *desc, char **data, char **parity, int blocksize)
Definition: liberasurecode_rs_vand.c:83
free_systematic_matrix_func
void(* free_systematic_matrix_func)(int *)
Definition: liberasurecode_rs_vand.c:56
LIBERASURECODE_RS_VAND_LIB_MAJOR
#define LIBERASURECODE_RS_VAND_LIB_MAJOR
Definition: liberasurecode_rs_vand.c:35
LIBERASURECODE_RS_VAND_LIB_MINOR
#define LIBERASURECODE_RS_VAND_LIB_MINOR
Definition: liberasurecode_rs_vand.c:36
LIBERASURECODE_RS_VAND_LIB_VER_STR
#define LIBERASURECODE_RS_VAND_LIB_VER_STR
Definition: liberasurecode_rs_vand.c:38
LIBERASURECODE_RS_VAND_LIB_NAME
#define LIBERASURECODE_RS_VAND_LIB_NAME
Definition: liberasurecode_rs_vand.c:39
liberasurecode_rs_vand_encode_func
int(* liberasurecode_rs_vand_encode_func)(int *, char **, char **, int, int, int)
Definition: liberasurecode_rs_vand.c:51
liberasurecode_rs_vand_reconstruct_func
int(* liberasurecode_rs_vand_reconstruct_func)(int *, char **, char **, int, int, int *, int, int)
Definition: liberasurecode_rs_vand.c:53
liberasurecode_rs_vand_ops
struct ec_backend_op_stubs liberasurecode_rs_vand_ops
Definition: liberasurecode_rs_vand.c:47
make_systematic_matrix_func
int *(* make_systematic_matrix_func)(int, int)
Definition: liberasurecode_rs_vand.c:57
liberasurecode_rs_vand_descriptor::make_systematic_matrix
make_systematic_matrix_func make_systematic_matrix
Definition: liberasurecode_rs_vand.c:65
liberasurecode_rs_vand_reconstruct
static int liberasurecode_rs_vand_reconstruct(void *desc, char **data, char **parity, int *missing_idxs, int destination_idx, int blocksize)
Definition: liberasurecode_rs_vand.c:108
liberasurecode_rs_vand_descriptor
Definition: liberasurecode_rs_vand.c:60
liberasurecode_rs_vand_is_compatible_with
static bool liberasurecode_rs_vand_is_compatible_with(uint32_t version)
Definition: liberasurecode_rs_vand.c:288
liberasurecode_rs_vand_op_stubs
struct ec_backend_op_stubs liberasurecode_rs_vand_op_stubs
Definition: liberasurecode_rs_vand.c:292
liberasurecode_rs_vand_descriptor::deinit_liberasurecode_rs_vand
deinit_liberasurecode_rs_vand_func deinit_liberasurecode_rs_vand
Definition: liberasurecode_rs_vand.c:63
liberasurecode_rs_vand_descriptor::k
int k
Definition: liberasurecode_rs_vand.c:78
liberasurecode_rs_vand_descriptor::init_liberasurecode_rs_vand
init_liberasurecode_rs_vand_func init_liberasurecode_rs_vand
Definition: liberasurecode_rs_vand.c:62
init_liberasurecode_rs_vand_func
void(* init_liberasurecode_rs_vand_func)(int, int)
Definition: liberasurecode_rs_vand.c:54
LIBERASURECODE_RS_VAND_SO_NAME
#define LIBERASURECODE_RS_VAND_SO_NAME
Definition: liberasurecode_rs_vand.c:43
liberasurecode_rs_vand_element_size
static int liberasurecode_rs_vand_element_size(void *desc)
Return the element-size, which is the number of bits stored on a given device, per codeword.
Definition: liberasurecode_rs_vand.c:262
liberasurecode_rs_vand_init
static void * liberasurecode_rs_vand_init(struct ec_backend_args *args, void *backend_sohandle)
Definition: liberasurecode_rs_vand.c:148
liberasurecode_rs_vand_decode_func
int(* liberasurecode_rs_vand_decode_func)(int *, char **, char **, int, int, int *, int, int)
Definition: liberasurecode_rs_vand.c:52
liberasurecode_rs_vand_exit
static int liberasurecode_rs_vand_exit(void *desc)
Definition: liberasurecode_rs_vand.c:271
deinit_liberasurecode_rs_vand_func
void(* deinit_liberasurecode_rs_vand_func)()
Definition: liberasurecode_rs_vand.c:55
liberasurecode_rs_vand_decode
static int liberasurecode_rs_vand_decode(void *desc, char **data, char **parity, int *missing_idxs, int blocksize)
Definition: liberasurecode_rs_vand.c:95
backend_liberasurecode_rs_vand
struct ec_backend_common backend_liberasurecode_rs_vand
Definition: liberasurecode_rs_vand.c:49
liberasurecode_rs_vand_descriptor::free_systematic_matrix
free_systematic_matrix_func free_systematic_matrix
Definition: liberasurecode_rs_vand.c:64
liberasurecode_rs_vand
struct ec_backend liberasurecode_rs_vand
Definition: liberasurecode_rs_vand.c:48
liberasurecode_rs_vand_descriptor::liberasurecode_rs_vand_reconstruct
liberasurecode_rs_vand_reconstruct_func liberasurecode_rs_vand_reconstruct
Definition: liberasurecode_rs_vand.c:74
liberasurecode_rs_vand_descriptor::liberasurecode_rs_vand_decode
liberasurecode_rs_vand_decode_func liberasurecode_rs_vand_decode
Definition: liberasurecode_rs_vand.c:71
liberasurecode_rs_vand_descriptor::liberasurecode_rs_vand_encode
liberasurecode_rs_vand_encode_func liberasurecode_rs_vand_encode
Definition: liberasurecode_rs_vand.c:68
LIBERASURECODE_RS_VAND_LIB_REV
#define LIBERASURECODE_RS_VAND_LIB_REV
Definition: liberasurecode_rs_vand.c:37