32#include "erasurecode.h"
33#include "erasurecode_backend.h"
34#include "erasurecode_helpers.h"
35#include "erasurecode_helpers_ext.h"
36#include "erasurecode_preprocessing.h"
37#include "erasurecode_postprocessing.h"
38#include "erasurecode_stdinc.h"
41#include "erasurecode_log.h"
76static SLIST_HEAD(backend_list, ec_backend) active_instances =
77 SLIST_HEAD_INITIALIZER(active_instances);
86static rwlock_t active_instances_rwlock = RWLOCK_INITIALIZER;
89static int next_backend_desc = 0;
97ec_backend_t liberasurecode_backend_instance_get_by_desc(
int desc)
99 struct ec_backend *b = NULL;
100 SLIST_FOREACH(b, &active_instances, link) {
101 if (b->idesc == desc)
116 if (++next_backend_desc <= 0)
117 next_backend_desc = 1;
118 if (!liberasurecode_backend_instance_get_by_desc(next_backend_desc))
119 return next_backend_desc;
127 char *msg = dlerror();
129 log_error(
"%s: unknown dynamic linking error\n", caller);
131 log_error(
"%s: dynamic linking error %s\n", caller, msg);
137 if (NULL == instance)
140 return dlopen(instance->common.soname, RTLD_LAZY | RTLD_LOCAL);
145 if (NULL == instance || NULL == instance->desc.backend_sohandle)
148 dlclose(instance->desc.backend_sohandle);
151 instance->desc.backend_sohandle = NULL;
158liberasurecode_init(
void) {
160 openlog(
"liberasurecode", LOG_PID | LOG_CONS, LOG_USER);
164liberasurecode_exit(
void) {
178 struct ec_backend backend;
179 if (backend_id >= EC_BACKENDS_MAX)
184 if (!backend.desc.backend_sohandle) {
212 struct ec_args *args)
214 ec_backend_t instance = NULL;
215 struct ec_backend_args bargs;
219 return -EINVALIDPARAMS;
221 if (
id >= EC_BACKENDS_MAX)
222 return -EBACKENDNOTSUPP;
224 if (args->k < 0 || args->m < 0)
225 return -EINVALIDPARAMS;
226 if ((args->k + args->m) > EC_MAX_FRAGMENTS) {
227 log_error(
"Total number of fragments (k + m) must be less than %d\n",
229 return -EINVALIDPARAMS;
233 instance = calloc(1,
sizeof(*instance));
234 if (NULL == instance)
239 memcpy(&(bargs.uargs), args, sizeof (
struct ec_args));
240 instance->args = bargs;
244 if (!instance->desc.backend_sohandle) {
246 if (!instance->desc.backend_sohandle) {
251 return -EBACKENDNOTAVAIL;
255 rc = rwlock_wrlock(&active_instances_rwlock);
258 instance->desc.backend_desc = instance->common.ops->init(
259 &instance->args, instance->desc.backend_sohandle);
260 if (NULL == instance->desc.backend_desc) {
262 desc = -EBACKENDINITERR;
267 if (instance->idesc <= 0) {
268 instance->common.ops->exit(instance->desc.backend_desc);
274 desc = instance->idesc;
275 SLIST_INSERT_HEAD(&active_instances, instance, link);
282 rwlock_unlock(&active_instances_rwlock);
294 ec_backend_t instance = NULL;
297 rc = rwlock_wrlock(&active_instances_rwlock);
299 instance = liberasurecode_backend_instance_get_by_desc(desc);
300 if (NULL == instance) {
301 rwlock_unlock(&active_instances_rwlock);
302 return -EBACKENDNOTAVAIL;
306 instance->common.ops->exit(instance->desc.backend_desc);
312 SLIST_REMOVE(&active_instances, instance, ec_backend, link);
314 rwlock_unlock(&active_instances_rwlock);
336 char **encoded_parity)
340 int rc = rwlock_rdlock(&active_instances_rwlock);
345 ec_backend_t instance = liberasurecode_backend_instance_get_by_desc(desc);
346 if (NULL == instance) {
347 rwlock_unlock(&active_instances_rwlock);
348 return -EBACKENDNOTAVAIL;
351 k = instance->args.uargs.k;
352 m = instance->args.uargs.m;
353 rwlock_unlock(&active_instances_rwlock);
356 for (i = 0; i < k; i++) {
357 free(encoded_data[i]);
363 if (encoded_parity) {
364 for (i = 0; i < m; i++) {
365 free(encoded_parity[i]);
367 free(encoded_parity);
390 const char *orig_data, uint64_t orig_data_size,
391 char ***encoded_data,
char ***encoded_parity,
392 uint64_t *fragment_len)
399 if (orig_data == NULL) {
400 log_error(
"Pointer to data buffer is null!");
401 ret = -EINVALIDPARAMS;
405 if (encoded_data == NULL) {
406 log_error(
"Pointer to encoded data buffers is null!");
407 return -EINVALIDPARAMS;
410 if (encoded_parity == NULL) {
411 log_error(
"Pointer to encoded parity buffers is null!");
412 return -EINVALIDPARAMS;
415 if (fragment_len == NULL) {
416 log_error(
"Pointer to fragment length is null!");
417 ret = -EINVALIDPARAMS;
421 int rc = rwlock_rdlock(&active_instances_rwlock);
424 ret = rc < 0 ? rc : -rc;
427 ec_backend_t instance = liberasurecode_backend_instance_get_by_desc(desc);
428 if (NULL == instance) {
429 ret = -EBACKENDNOTAVAIL;
433 k = instance->args.uargs.k;
434 m = instance->args.uargs.m;
439 *encoded_data = (
char **) alloc_zeroed_buffer(
sizeof(
char *) * k);
440 if (NULL == *encoded_data) {
441 log_error(
"Could not allocate data buffer!");
445 *encoded_parity = (
char **) alloc_zeroed_buffer(
sizeof(
char *) * m);
446 if (NULL == *encoded_parity) {
447 log_error(
"Could not allocate parity buffer!");
451 ret = prepare_fragments_for_encode(instance, k, m, orig_data, orig_data_size,
452 *encoded_data, *encoded_parity, &blocksize);
455 get_fragment_ptr_array_from_data(*encoded_data, *encoded_data, k);
456 get_fragment_ptr_array_from_data(*encoded_parity, *encoded_parity, m);
461 ret = instance->common.ops->encode(instance->desc.backend_desc,
462 *encoded_data, *encoded_parity, blocksize);
465 get_fragment_ptr_array_from_data(*encoded_data, *encoded_data, k);
466 get_fragment_ptr_array_from_data(*encoded_parity, *encoded_parity, m);
470 ret = finalize_fragments_after_encode(instance, k, m, blocksize, orig_data_size,
471 *encoded_data, *encoded_parity);
473 *fragment_len = get_fragment_size((*encoded_data)[0]);
476 rwlock_unlock(&active_instances_rwlock);
481 log_error(
"Error in liberasurecode_encode %d", ret);
501 int rc = rwlock_rdlock(&active_instances_rwlock);
506 ec_backend_t instance = liberasurecode_backend_instance_get_by_desc(desc);
507 rwlock_unlock(&active_instances_rwlock);
508 if (NULL == instance) {
509 return -EBACKENDNOTAVAIL;
531 char **available_fragments,
532 int num_fragments, uint64_t fragment_len,
533 int force_metadata_checks,
534 char **out_data, uint64_t *out_data_len)
540 int orig_data_size = 0;
544 char **parity = NULL;
545 char **data_segments = NULL;
546 char **parity_segments = NULL;
547 int *missing_idxs = NULL;
549 struct ec_bm realloc_bm = NEW_BM;
551 int rc = rwlock_rdlock(&active_instances_rwlock);
556 ec_backend_t instance = liberasurecode_backend_instance_get_by_desc(desc);
557 if (NULL == instance) {
558 ret = -EBACKENDNOTAVAIL;
562 if (NULL == available_fragments) {
563 log_error(
"Pointer to encoded fragments buffer is null!");
564 ret = -EINVALIDPARAMS;
568 if (NULL == out_data) {
569 log_error(
"Pointer to decoded data buffer is null!");
570 ret = -EINVALIDPARAMS;
574 if (NULL == out_data_len) {
575 log_error(
"Pointer to decoded data length variable is null!");
576 ret = -EINVALIDPARAMS;
580 k = instance->args.uargs.k;
581 m = instance->args.uargs.m;
583 if (num_fragments < k) {
584 log_error(
"Not enough fragments to decode, got %d, need %d!",
590 if (fragment_len <
sizeof(fragment_header_t)) {
591 log_error(
"Fragments not long enough to include headers! "
592 "Need %zu, but got %lu.",
sizeof(fragment_header_t),
593 (
unsigned long)fragment_len);
597 for (i = 0; i < num_fragments; ++i) {
600 (fragment_header_t *) available_fragments[i])) {
601 log_error(
"Invalid fragment header information!");
607 if (instance->common.ops->is_systematic) {
611 ret = fragments_to_string(k, m,
612 available_fragments, num_fragments,
613 out_data, out_data_len);
624 data = alloc_zeroed_buffer(
sizeof(
char*) * k);
626 log_error(
"Could not allocate data buffer!");
630 parity = alloc_zeroed_buffer(
sizeof(
char*) * m);
631 if (NULL == parity) {
632 log_error(
"Could not allocate parity buffer!");
637 if (NULL == missing_idxs) {
638 log_error(
"Could not allocate missing_idxs buffer!");
643 if (force_metadata_checks) {
644 int num_invalid_fragments = 0;
645 for (i = 0; i < num_fragments; ++i) {
647 ++num_invalid_fragments;
650 if ((num_fragments - num_invalid_fragments) < k) {
652 log_error(
"Not enough valid fragments available for decode!");
662 data, parity, missing_idxs);
665 log_error(
"Could not properly partition the fragments!");
676 ret = prepare_fragments_for_decode(k, m,
677 data, parity, missing_idxs,
678 &orig_data_size, &blocksize,
679 fragment_len, &realloc_bm);
681 log_error(
"Could not prepare fragments for decode!");
685 data_segments = alloc_zeroed_buffer(k *
sizeof(
char *));
686 parity_segments = alloc_zeroed_buffer(m *
sizeof(
char *));
687 get_data_ptr_array_from_fragments(data_segments, data, k);
688 get_data_ptr_array_from_fragments(parity_segments, parity, m);
691 ret = instance->common.ops->decode(instance->desc.backend_desc,
692 data_segments, parity_segments,
693 missing_idxs, blocksize);
696 log_error(
"Encountered error in backend decode function!");
705 while (missing_idxs[j] >= 0) {
707 int missing_idx = missing_idxs[j];
708 if (missing_idx < k) {
710 char *fragment_ptr = data[missing_idx];
711 init_fragment_header(fragment_ptr);
712 add_fragment_metadata(instance, fragment_ptr, missing_idx,
713 orig_data_size, blocksize, instance->args.uargs.ct,
720 ret = fragments_to_string(k, m, data, k, out_data, out_data_len);
723 log_error(
"Could not convert decoded fragments to a string!");
727 rwlock_unlock(&active_instances_rwlock);
729 if (bm_any(&realloc_bm)) {
730 for (i = 0; i < k; i++) {
731 if (bm_get_value(&realloc_bm, i)) {
736 for (i = 0; i < m; i++) {
737 if (bm_get_value(&realloc_bm, i + k)) {
747 free(parity_segments);
765 char **available_fragments,
766 int num_fragments, uint64_t fragment_len,
772 int orig_data_size = 0;
774 char **parity = NULL;
775 int *missing_idxs = NULL;
776 char *fragment_ptr = NULL;
777 int is_destination_missing = 0;
781 struct ec_bm realloc_bm = NEW_BM;
782 char **data_segments = NULL;
783 char **parity_segments = NULL;
786 int rc = rwlock_rdlock(&active_instances_rwlock);
791 ec_backend_t instance = liberasurecode_backend_instance_get_by_desc(desc);
792 if (NULL == instance) {
793 ret = -EBACKENDNOTAVAIL;
797 if (NULL == available_fragments) {
798 log_error(
"Can not reconstruct fragment, available fragments pointer is NULL");
799 ret = -EINVALIDPARAMS;
803 if (NULL == out_fragment) {
804 log_error(
"Can not reconstruct fragment, output fragment pointer is NULL");
805 ret = -EINVALIDPARAMS;
809 k = instance->args.uargs.k;
810 m = instance->args.uargs.m;
812 for (i = 0; i < num_fragments; i++) {
815 (fragment_header_t *) available_fragments[i])) {
816 log_error(
"Invalid fragment header information!");
825 data = alloc_zeroed_buffer(
sizeof(
char*) * k);
827 log_error(
"Could not allocate data buffer!");
832 parity = alloc_zeroed_buffer(
sizeof(
char*) * m);
833 if (NULL == parity) {
834 log_error(
"Could not allocate parity buffer!");
840 if (NULL == missing_idxs) {
841 log_error(
"Could not allocate missing_idxs buffer!");
851 data, parity, missing_idxs);
854 log_error(
"Could not properly partition the fragments!");
868 while (missing_idxs[i] > -1) {
869 if (missing_idxs[i] == destination_idx) {
870 is_destination_missing = 1;
875 if (!is_destination_missing) {
876 if (destination_idx < k) {
877 fragment_ptr = data[destination_idx];
879 fragment_ptr = parity[destination_idx - k];
881 log_warn(
"Dest idx for reconstruction was supplied as available buffer!");
882 goto destination_available;
885 if (instance->common.ops->check_reconstruct_fragments == NULL) {
886 if (num_fragments < k) {
891 ret = instance->common.ops->check_reconstruct_fragments(
892 instance->desc.backend_desc,
907 ret = prepare_fragments_for_decode(k, m, data, parity, missing_idxs,
908 &orig_data_size, &blocksize,
909 fragment_len, &realloc_bm);
911 log_error(
"Could not prepare fragments for reconstruction!");
914 data_segments = alloc_zeroed_buffer(k *
sizeof(
char *));
915 parity_segments = alloc_zeroed_buffer(m *
sizeof(
char *));
916 get_data_ptr_array_from_fragments(data_segments, data, k);
917 get_data_ptr_array_from_fragments(parity_segments, parity, m);
921 ret = instance->common.ops->reconstruct(instance->desc.backend_desc,
922 data_segments, parity_segments,
923 missing_idxs, destination_idx,
926 log_error(
"Could not reconstruct fragment!");
933 if (destination_idx < k) {
934 fragment_ptr = data[destination_idx];
936 fragment_ptr = parity[destination_idx - k];
938 init_fragment_header(fragment_ptr);
939 add_fragment_metadata(instance, fragment_ptr, destination_idx,
940 orig_data_size, blocksize, instance->args.uargs.ct,
943destination_available:
949 memcpy(out_fragment, fragment_ptr, fragment_len);
952 rwlock_unlock(&active_instances_rwlock);
954 if (bm_any(&realloc_bm)) {
955 for (i = 0; i < k; i++) {
956 if (bm_get_value(&realloc_bm, i)) {
961 for (i = 0; i < m; i++) {
962 if (bm_get_value(&realloc_bm, i + k)) {
972 free(parity_segments);
992 int *fragments_to_reconstruct,
993 int *fragments_to_exclude,
994 int *fragments_needed)
998 int rc = rwlock_rdlock(&active_instances_rwlock);
1003 ec_backend_t instance = liberasurecode_backend_instance_get_by_desc(desc);
1004 if (NULL == instance) {
1005 ret = -EBACKENDNOTAVAIL;
1008 if (NULL == fragments_to_reconstruct) {
1009 log_error(
"Unable to determine list of fragments needed, pointer to list of indexes to reconstruct is NULL.");
1010 ret = -EINVALIDPARAMS;
1014 if (NULL == fragments_to_exclude) {
1015 log_error(
"Unable to determine list of fragments needed, pointer to list of fragments to exclude is NULL.");
1016 ret = -EINVALIDPARAMS;
1020 if (NULL == fragments_needed) {
1021 log_error(
"Unable to determine list of fragments needed, pointer to list of fragments to reconstruct is NULL.");
1022 ret = -EINVALIDPARAMS;
1029 ret = instance->common.ops->fragments_needed(
1030 instance->desc.backend_desc,
1031 fragments_to_reconstruct, fragments_to_exclude, fragments_needed);
1034 rwlock_unlock(&active_instances_rwlock);
1051 fragment_metadata_t *fragment_metadata)
1054 fragment_header_t *fragment_hdr = NULL;
1056 if (NULL == fragment) {
1057 log_error(
"Need valid fragment object to get metadata for");
1058 ret = -EINVALIDPARAMS;
1062 if (NULL == fragment_metadata) {
1063 log_error(
"Need valid fragment_metadata object for return value");
1064 ret = -EINVALIDPARAMS;
1070 log_error(
"Invalid fragment header information!");
1075 memcpy(fragment_metadata, fragment,
sizeof(
struct fragment_metadata));
1076 fragment_hdr = (fragment_header_t *) fragment;
1077 if (LIBERASURECODE_FRAG_HEADER_MAGIC != fragment_hdr->magic) {
1078 if (LIBERASURECODE_FRAG_HEADER_MAGIC != bswap_32(fragment_hdr->magic)) {
1079 log_error(
"Invalid fragment, illegal magic value");
1080 ret = -EINVALIDPARAMS;
1085 fragment_metadata->idx = bswap_32(fragment_metadata->idx);
1086 fragment_metadata->size = bswap_32(fragment_metadata->size);
1087 fragment_metadata->frag_backend_metadata_size =
1088 bswap_32(fragment_metadata->frag_backend_metadata_size);
1089 fragment_metadata->orig_data_size =
1090 bswap_64(fragment_metadata->orig_data_size);
1091 fragment_metadata->chksum_type =
1092 bswap_32(fragment_metadata->chksum_type);
1093 for (
int i = 0; i < LIBERASURECODE_MAX_CHECKSUM_LEN; i++) {
1094 fragment_metadata->chksum[i] =
1095 bswap_32(fragment_metadata->chksum[i]);
1097 fragment_metadata->backend_version =
1098 bswap_32(fragment_metadata->backend_version);
1102 switch(fragment_metadata->chksum_type) {
1103 case CHKSUM_CRC32: {
1104 uint32_t computed_chksum = 0;
1105 uint32_t stored_chksum = fragment_metadata->chksum[0];
1107 uint64_t fragment_size = fragment_metadata->size;
1108 computed_chksum = crc32(0, (
unsigned char *) fragment_data, fragment_size);
1109 if (stored_chksum != computed_chksum) {
1113 0, fragment_data, fragment_size);
1114 if (stored_chksum != computed_chksum) {
1115 fragment_metadata->chksum_mismatch = 1;
1117 fragment_metadata->chksum_mismatch = 0;
1120 fragment_metadata->chksum_mismatch = 0;
1137 uint32_t csum = 0, metadata_chksum = 0, libec_version = 0;
1138 assert (NULL != header);
1139 if (header->libec_version == 0)
1142 metadata_chksum = header->metadata_chksum;
1143 libec_version = header->libec_version;
1144 if (header->magic != LIBERASURECODE_FRAG_HEADER_MAGIC) {
1145 if (bswap_32(header->magic) != LIBERASURECODE_FRAG_HEADER_MAGIC) {
1146 log_error(
"Invalid fragment header (get meta chksum)!");
1153 metadata_chksum = bswap_32(metadata_chksum);
1154 libec_version = bswap_32(libec_version);
1158 if (libec_version < _VERSION(1,2,0))
1162 csum = crc32(0, (
unsigned char *) &header->meta,
sizeof(fragment_metadata_t));
1163 if (metadata_chksum == csum) {
1169 return (metadata_chksum != csum);
1173 fragment_metadata_t *md)
1175 int k = be->args.uargs.k;
1176 int m = be->args.uargs.m;
1177 if (md->idx >= (k + m)) {
1180 if (md->backend_id != be->common.id) {
1183 if (!be->common.ops->is_compatible_with(md->backend_version)) {
1192 int rc = rwlock_rdlock(&active_instances_rwlock);
1197 ec_backend_t be = liberasurecode_backend_instance_get_by_desc(desc);
1199 log_error(
"Unable to verify fragment metadata: invalid backend id %d.",
1201 ret = -EINVALIDPARAMS;
1205 fragment_metadata) != 0) {
1209 if (!be->common.ops->is_compatible_with(fragment_metadata->backend_version)) {
1213 if (fragment_metadata->chksum_mismatch == 1) {
1218 rwlock_unlock(&active_instances_rwlock);
1226 fragment_metadata_t fragment_metadata;
1227 int rc = rwlock_rdlock(&active_instances_rwlock);
1232 ec_backend_t be = liberasurecode_backend_instance_get_by_desc(desc);
1234 log_error(
"Unable to verify fragment metadata: invalid backend id %d.",
1240 log_error(
"Unable to verify fragment validity: fragments missing.");
1245 ver > LIBERASURECODE_VERSION) {
1258 rwlock_unlock(&active_instances_rwlock);
1263 char **fragments,
int num_fragments)
1267 log_error(
"Unable to verify stripe metadata: fragments missing.");
1268 return -EINVALIDPARAMS;
1270 if (num_fragments <= 0) {
1271 log_error(
"Unable to verify stripe metadata: "
1272 "number of fragments must be greater than 0.");
1273 return -EINVALIDPARAMS;
1277 int rc = rwlock_rdlock(&active_instances_rwlock);
1282 for (i = 0; i < num_fragments; i++) {
1283 fragment_metadata_t *fragment_metadata = (fragment_metadata_t*)fragments[i];
1290 rwlock_unlock(&active_instances_rwlock);
1308 int alignment_multiple;
1310 int rc = rwlock_rdlock(&active_instances_rwlock);
1313 return rc < 0 ? rc : -rc;
1315 ec_backend_t instance = liberasurecode_backend_instance_get_by_desc(desc);
1316 if (NULL == instance) {
1317 ret = -EBACKENDNOTAVAIL;
1321 k = instance->args.uargs.k;
1323 word_size = instance->common.ops->element_size(
1324 instance->desc.backend_desc) / 8;
1326 alignment_multiple = k * word_size;
1328 ret = ((data_len + alignment_multiple - 1) / alignment_multiple)
1329 * alignment_multiple;
1332 rwlock_unlock(&active_instances_rwlock);
1347 int rc = rwlock_rdlock(&active_instances_rwlock);
1350 return rc < 0 ? rc : -rc;
1352 ec_backend_t instance = liberasurecode_backend_instance_get_by_desc(desc);
1354 if (NULL == instance) {
1355 rwlock_unlock(&active_instances_rwlock);
1356 return -EBACKENDNOTAVAIL;
1358 int aligned_data_len = get_aligned_data_size(instance, data_len);
1359 int blocksize = aligned_data_len / instance->args.uargs.k;
1360 int metadata_size = instance->common.ops->get_backend_metadata_size(
1361 instance->desc.backend_desc,
1363 int size = blocksize + metadata_size;
1365 rwlock_unlock(&active_instances_rwlock);
1376 return LIBERASURECODE_VERSION;
1383int liberasurecode_backend_validate(ec_backend_t backend)
1392ec_backend_t liberasurecode_backend_get(
const char *name)
1394 ec_backend_t b = liberasurecode_backend_lookup_by_name(name);
1401void liberasurecode_backend_put(ec_backend_t backend)
1403 if (backend->users > 0)
1408ec_backend_t liberasurecode_backend_instance_active(ec_backend_t instance)
1412 SLIST_FOREACH(b, &active_instances, link) {
1413 if (strcmp(b->name, name) == 0)
1420ec_backend_t liberasurecode_backend_lookup_by_soname(
const char *soname)
1424 SLIST_FOREACH(b, &active_instances, link) {
1425 if (strcmp(b->soname, soname) == 0)
int liberasurecode_crc32_alt(int crc, const void *buf, size_t size)
int liberasurecode_verify_fragment_metadata(ec_backend_t be, fragment_metadata_t *md)
int liberasurecode_decode(int desc, char **available_fragments, int num_fragments, uint64_t fragment_len, int force_metadata_checks, char **out_data, uint64_t *out_data_len)
Reconstruct original data from a set of k encoded fragments.
int liberasurecode_encode(int desc, const char *orig_data, uint64_t orig_data_size, char ***encoded_data, char ***encoded_parity, uint64_t *fragment_len)
Erasure encode a data buffer.
int is_invalid_fragment_header(fragment_header_t *header)
struct ec_backend_common backend_flat_xor_hd
static void print_dlerror(const char *caller)
int liberasurecode_decode_cleanup(int desc, char *data)
Cleanup structures allocated by librasurecode_decode.
int liberasurecode_fragments_needed(int desc, int *fragments_to_reconstruct, int *fragments_to_exclude, int *fragments_needed)
Return a list of lists with valid rebuild indexes given a list of missing indexes.
struct ec_backend_common backend_null
struct ec_backend_common backend_shss
static int liberasurecode_backend_close(ec_backend_t instance)
struct ec_backend_common backend_isa_l_rs_vand
int liberasurecode_instance_create(const ec_backend_id_t id, struct ec_args *args)
Create a liberasurecode instance and return a descriptor for use with EC operations (encode,...
struct ec_backend_common backend_liberasurecode_rs_vand
struct ec_backend_common backend_isa_l_rs_cauchy
static ec_backend_t ec_backends_supported[]
int liberasurecode_get_fragment_metadata(char *fragment, fragment_metadata_t *fragment_metadata)
Get opaque metadata for a fragment.
struct ec_backend_common backend_isa_l_rs_lrc
static int is_invalid_fragment_metadata(int desc, fragment_metadata_t *fragment_metadata)
int liberasurecode_get_minimum_encode_size(int desc)
This will return the minumum encode size, which is the minimum buffer size that can be encoded.
int liberasurecode_get_aligned_data_size(int desc, uint64_t data_len)
This computes the aligned size of a buffer passed into the encode function.
int is_invalid_fragment(int desc, char *fragment)
int liberasurecode_reconstruct_fragment(int desc, char **available_fragments, int num_fragments, uint64_t fragment_len, int destination_idx, char *out_fragment)
Reconstruct a missing fragment from a subset of available fragments.
int liberasurecode_verify_stripe_metadata(int desc, char **fragments, int num_fragments)
struct ec_backend_common backend_libphazr
static void * liberasurecode_backend_open(ec_backend_t instance)
struct ec_backend_common backend_isa_l_rs_vand_inv
int liberasurecode_encode_cleanup(int desc, char **encoded_data, char **encoded_parity)
Cleanup structures allocated by librasurecode_encode.
static int liberasurecode_backend_alloc_desc(void)
Allocated backend instance descriptor.
int liberasurecode_backend_available(const ec_backend_id_t backend_id)
Checks if a given backend is available.
struct ec_backend_common backend_jerasure_rs_cauchy
int liberasurecode_instance_destroy(int desc)
Close a liberasurecode instance.
static SLIST_HEAD(backend_list, ec_backend)
Look up a backend instance by descriptor.
struct ec_backend_common backend_jerasure_rs_vand
int liberasurecode_get_fragment_size(int desc, int data_len)
uint32_t liberasurecode_get_version(void)
This will return the liberasurecode version for the descriptor.
void __attribute__((constructor))
void * alloc_and_set_buffer(int size, int value)
Allocate a buffer of a specific size and set its' contents to the specified value.
char * get_data_ptr_from_fragment(char *buf)
int get_libec_version(char *buf, uint32_t *ver)
int get_fragment_partition(int k, int m, char **fragments, int num_fragments, char **data, char **parity, int *missing)