summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJim Cheung <jim.cheung@phazr.io>2017-01-23 13:55:24 -0800
committerjimcheung <jim.cheung@phazr.io>2017-02-28 11:14:11 -0800
commit06e50ea86b6de729fa5dbc23ef41af87b19e636a (patch)
treeace75bea1a47a5a380af8913923956fdcd693679 /src
parent0794b31c623e4cede76d66be730719d24debcca9 (diff)
downloadliberasurecode-06e50ea86b6de729fa5dbc23ef41af87b19e636a.tar.gz
Add Phazr.IO libphazr backend to liberasurecode
Currently, there are several implementations of erasure codes that are available within OpenStack Swift. Most, if not all, of which are based on the Reed Solomon coding algorithm. Phazr.IO’s Erasure Coding technology uses a patented algorithm which are significantly more efficient and improves the speed of coding, decoding and reconstruction. In addition, Phazr.IO Erasure Code use a non-systematic algorithm which provides data protection at rest and in transport without the need to use encryption. Please contact support@phazr.io for more info on our technology. Change-Id: I4e40d02a8951e38409ad3c604c5dd6f050fa7ea0
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am6
-rw-r--r--src/backends/isa-l/isa_l_rs_cauchy.c3
-rw-r--r--src/backends/isa-l/isa_l_rs_vand.c3
-rw-r--r--src/backends/jerasure/jerasure_rs_cauchy.c5
-rw-r--r--src/backends/jerasure/jerasure_rs_vand.c3
-rw-r--r--src/backends/null/null.c5
-rw-r--r--src/backends/phazrio/libphazr.c391
-rw-r--r--src/backends/rs_vand/liberasurecode_rs_vand.c3
-rw-r--r--src/backends/shss/shss.c7
-rw-r--r--src/backends/xor/flat_xor_hd.c3
-rw-r--r--src/erasurecode.c12
-rw-r--r--src/erasurecode_postprocessing.c4
-rw-r--r--src/erasurecode_preprocessing.c12
13 files changed, 437 insertions, 20 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index eb2f89f..7b704f4 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -26,7 +26,8 @@ liberasurecode_la_SOURCES = \
backends/isa-l/isa_l_rs_cauchy.c \
backends/rs_vand/liberasurecode_rs_vand.c \
builtin/rs_vand/rs_galois.c \
- backends/shss/shss.c
+ backends/shss/shss.c \
+ backends/phazrio/libphazr.c
liberasurecode_la_CPPFLAGS = -Werror @GCOV_FLAGS@
liberasurecode_la_LIBADD = \
@@ -42,4 +43,5 @@ MOSTLYCLEANFILES = *.gcda *.gcno *.gcov utils/chksum/*.gcda utils/chksum/*.gcno
backends/xor/*.gcda backends/xor/*.gcno backends/xor/*.gcov \
backends/jerasure/*.gcda backends/jerasure/*.gcno backends/jerasure/*.gcov \
backends/shss/*.gcda backends/shss/*.gcno backends/shss/*.gcov \
- backends/rs_vand/*.gcda backends/rs_vand/*.gcno backends/rs_vand/*.gcov
+ backends/rs_vand/*.gcda backends/rs_vand/*.gcno backends/rs_vand/*.gcov \
+ backends/phazrio/*.gcda backends/phazrio/*.gcno backends/phazrio/*.gcov
diff --git a/src/backends/isa-l/isa_l_rs_cauchy.c b/src/backends/isa-l/isa_l_rs_cauchy.c
index 11bac53..3ab927e 100644
--- a/src/backends/isa-l/isa_l_rs_cauchy.c
+++ b/src/backends/isa-l/isa_l_rs_cauchy.c
@@ -71,6 +71,8 @@ struct ec_backend_op_stubs isa_l_rs_cauchy_op_stubs = {
.RECONSTRUCT = isa_l_reconstruct,
.ELEMENTSIZE = isa_l_element_size,
.ISCOMPATIBLEWITH = isa_l_rs_cauchy_is_compatible_with,
+ .GETMETADATASIZE = get_backend_metadata_size_zero,
+ .GETENCODEOFFSET = get_encode_offset_zero,
};
struct ec_backend_common backend_isa_l_rs_cauchy = {
@@ -79,7 +81,6 @@ struct ec_backend_common backend_isa_l_rs_cauchy = {
.soname = ISA_L_RS_CAUCHY_SO_NAME,
.soversion = ISA_L_RS_CAUCHY_LIB_VER_STR,
.ops = &isa_l_rs_cauchy_op_stubs,
- .backend_metadata_size = 0,
.ec_backend_version = _VERSION(ISA_L_RS_CAUCHY_LIB_MAJOR,
ISA_L_RS_CAUCHY_LIB_MINOR,
ISA_L_RS_CAUCHY_LIB_REV),
diff --git a/src/backends/isa-l/isa_l_rs_vand.c b/src/backends/isa-l/isa_l_rs_vand.c
index a084beb..ca176cb 100644
--- a/src/backends/isa-l/isa_l_rs_vand.c
+++ b/src/backends/isa-l/isa_l_rs_vand.c
@@ -70,6 +70,8 @@ struct ec_backend_op_stubs isa_l_rs_vand_op_stubs = {
.RECONSTRUCT = isa_l_reconstruct,
.ELEMENTSIZE = isa_l_element_size,
.ISCOMPATIBLEWITH = isa_l_rs_vand_is_compatible_with,
+ .GETMETADATASIZE = get_backend_metadata_size_zero,
+ .GETENCODEOFFSET = get_encode_offset_zero,
};
struct ec_backend_common backend_isa_l_rs_vand = {
@@ -78,7 +80,6 @@ struct ec_backend_common backend_isa_l_rs_vand = {
.soname = ISA_L_RS_VAND_SO_NAME,
.soversion = ISA_L_RS_VAND_LIB_VER_STR,
.ops = &isa_l_rs_vand_op_stubs,
- .backend_metadata_size = 0,
.ec_backend_version = _VERSION(ISA_L_RS_VAND_LIB_MAJOR,
ISA_L_RS_VAND_LIB_MINOR,
ISA_L_RS_VAND_LIB_REV),
diff --git a/src/backends/jerasure/jerasure_rs_cauchy.c b/src/backends/jerasure/jerasure_rs_cauchy.c
index 816b45d..da94aff 100644
--- a/src/backends/jerasure/jerasure_rs_cauchy.c
+++ b/src/backends/jerasure/jerasure_rs_cauchy.c
@@ -426,7 +426,6 @@ static bool jerasure_rs_cauchy_is_compatible_with(uint32_t version) {
return version == backend_jerasure_rs_cauchy.ec_backend_version;
}
-
struct ec_backend_op_stubs jerasure_rs_cauchy_op_stubs = {
.INIT = jerasure_rs_cauchy_init,
.EXIT = jerasure_rs_cauchy_exit,
@@ -436,7 +435,8 @@ struct ec_backend_op_stubs jerasure_rs_cauchy_op_stubs = {
.RECONSTRUCT = jerasure_rs_cauchy_reconstruct,
.ELEMENTSIZE = jerasure_rs_cauchy_element_size,
.ISCOMPATIBLEWITH = jerasure_rs_cauchy_is_compatible_with,
-
+ .GETMETADATASIZE = get_backend_metadata_size_zero,
+ .GETENCODEOFFSET = get_encode_offset_zero,
};
struct ec_backend_common backend_jerasure_rs_cauchy = {
@@ -445,7 +445,6 @@ struct ec_backend_common backend_jerasure_rs_cauchy = {
.soname = JERASURE_RS_CAUCHY_SO_NAME,
.soversion = JERASURE_RS_CAUCHY_LIB_VER_STR,
.ops = &jerasure_rs_cauchy_op_stubs,
- .backend_metadata_size = 0,
.ec_backend_version = _VERSION(JERASURE_RS_CAUCHY_LIB_MAJOR,
JERASURE_RS_CAUCHY_LIB_MINOR,
JERASURE_RS_CAUCHY_LIB_REV),
diff --git a/src/backends/jerasure/jerasure_rs_vand.c b/src/backends/jerasure/jerasure_rs_vand.c
index 0c337a0..3e48e38 100644
--- a/src/backends/jerasure/jerasure_rs_vand.c
+++ b/src/backends/jerasure/jerasure_rs_vand.c
@@ -346,6 +346,8 @@ struct ec_backend_op_stubs jerasure_rs_vand_op_stubs = {
.RECONSTRUCT = jerasure_rs_vand_reconstruct,
.ELEMENTSIZE = jerasure_rs_vand_element_size,
.ISCOMPATIBLEWITH = jerasure_rs_vand_is_compatible_with,
+ .GETMETADATASIZE = get_backend_metadata_size_zero,
+ .GETENCODEOFFSET = get_encode_offset_zero,
};
struct ec_backend_common backend_jerasure_rs_vand = {
@@ -354,7 +356,6 @@ struct ec_backend_common backend_jerasure_rs_vand = {
.soname = JERASURE_RS_VAND_SO_NAME,
.soversion = JERASURE_RS_VAND_LIB_VER_STR,
.ops = &jerasure_rs_vand_op_stubs,
- .backend_metadata_size = 0,
.ec_backend_version = _VERSION(JERASURE_RS_VAND_LIB_MAJOR,
JERASURE_RS_VAND_LIB_MINOR,
JERASURE_RS_VAND_LIB_REV),
diff --git a/src/backends/null/null.c b/src/backends/null/null.c
index 8c7a31b..abc925b 100644
--- a/src/backends/null/null.c
+++ b/src/backends/null/null.c
@@ -50,7 +50,6 @@ typedef int (*null_code_encode_func)(void *, char **, char **, int);
typedef int (*null_code_decode_func)(void *, char **, char **, int *, int, int);
typedef int (*null_reconstruct_func)(char **, int, uint64_t, int, char *);
typedef int (*null_code_fragments_needed_func)(void *, int *, int *, int *);
-
struct null_descriptor {
/* calls required for init */
init_null_code_func init_null_code;
@@ -215,6 +214,7 @@ static int null_exit(void *desc)
static bool null_is_compatible_with(uint32_t version) {
return true;
}
+
struct ec_backend_op_stubs null_op_stubs = {
.INIT = null_init,
.EXIT = null_exit,
@@ -224,6 +224,8 @@ struct ec_backend_op_stubs null_op_stubs = {
.RECONSTRUCT = null_reconstruct,
.ELEMENTSIZE = null_element_size,
.ISCOMPATIBLEWITH = null_is_compatible_with,
+ .GETMETADATASIZE = get_backend_metadata_size_zero,
+ .GETENCODEOFFSET = get_encode_offset_zero,
};
struct ec_backend_common backend_null = {
@@ -232,7 +234,6 @@ struct ec_backend_common backend_null = {
.soname = NULL_SO_NAME,
.soversion = NULL_LIB_VER_STR,
.ops = &null_op_stubs,
- .backend_metadata_size = 0,
.ec_backend_version = _VERSION(NULL_LIB_MAJOR, NULL_LIB_MINOR,
NULL_LIB_REV),
};
diff --git a/src/backends/phazrio/libphazr.c b/src/backends/phazrio/libphazr.c
new file mode 100644
index 0000000..74ad8ad
--- /dev/null
+++ b/src/backends/phazrio/libphazr.c
@@ -0,0 +1,391 @@
+/*
+ * Copyright 2016 Phazr.IO Inc
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice, this
+ * list of conditions and the following disclaimer in the documentation and/or
+ * other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY
+ * THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Phazr.IO libphazr backend
+ *
+ * vi: set noai tw=79 ts=4 sw=4:
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "erasurecode.h"
+#include "erasurecode_backend.h"
+#include "erasurecode_helpers.h"
+
+#define LIBPHAZR_LIB_MAJOR 1
+#define LIBPHAZR_LIB_MINOR 0
+#define LIBPHAZR_LIB_REV 0
+#define LIBPHAZR_LIB_VER_STR "1.0.0"
+#define LIBPHAZR_LIB_NAME "libphazr"
+#if defined(__MACOS__) || defined(__MACOSX__) || defined(__OSX__) || defined(__APPLE__)
+#define LIBPHAZR_SO_NAME "libphazr.dylib"
+#else
+#define LIBPHAZR_SO_NAME "libphazr.so.1"
+#endif
+
+/* Forward declarations */
+struct ec_backend libphazr;
+struct ec_backend_op_stubs libphazr_ops;
+struct ec_backend_common backend_libphazr;
+
+typedef int (*pio_matrix_encode_func)(char *, char *, char **, int, int, int, int, int, int);
+typedef int (*pio_matrix_decode_func)(char *, char *, char **, int *, int, int, int, int, int, int);
+typedef int (*pio_matrix_reconstruct_func)(char *, char **, int *, int, int, int, int, int, int);
+typedef char* (*pio_create_precoding_matrix_func)(int);
+typedef char* (*pio_create_inverse_precoding_matrix_func)(int);
+typedef char* (*pio_create_kmux_matrix_func)(int, int, int);
+
+struct libphazr_descriptor {
+ /* calls required for init */
+ pio_create_precoding_matrix_func create_precoding_matrix;
+ pio_create_inverse_precoding_matrix_func create_inverse_precoding_matrix;
+ pio_create_kmux_matrix_func create_kmux_matrix;
+
+ /* calls required for encode */
+ pio_matrix_encode_func matrix_encode;
+
+ /* calls required for decode */
+ pio_matrix_decode_func matrix_decode;
+
+ /* calls required for reconstruct */
+ pio_matrix_reconstruct_func matrix_reconstruct;
+
+ /* fields needed to hold state */
+ char *matrix;
+ char *precoding_matrix;
+ char *inverse_precoding_matrix;
+ int k;
+ int m;
+ int w;
+ int hd;
+};
+
+#define DEFAULT_W 64
+
+#define DEFAULT_HD 1
+
+static int get_padded_blocksize(int w, int hd, int blocksize)
+{
+ int word_size = w / 8;
+ return (int) ceill((double) blocksize / (word_size - hd)) * word_size;
+}
+
+static int pio_matrix_encode(void *desc, char **data, char **parity, int blocksize)
+{
+ int i, ret = 0;
+ struct libphazr_descriptor *xdesc = (struct libphazr_descriptor *) desc;
+ int padding_size = get_padded_blocksize(xdesc->w, xdesc->hd, blocksize) - blocksize;
+ char **encoded = malloc(sizeof(char*) * (xdesc->k + xdesc->m));
+
+ if (NULL == encoded) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ for (i = 0; i < xdesc->k; i++) {
+ encoded[i] = data[i];
+ }
+
+ for (i = 0; i < xdesc->m; i++) {
+ encoded[i + xdesc->k] = parity[i];
+ }
+
+ ret = xdesc->matrix_encode(xdesc->precoding_matrix, xdesc->matrix, encoded,
+ xdesc->k, xdesc->m, xdesc->w, xdesc->hd, blocksize, padding_size);
+
+out:
+ free(encoded);
+
+ return ret;
+}
+
+static int pio_matrix_decode(void *desc, char **data, char **parity,
+ int *missing_idxs, int blocksize)
+{
+ int i, ret = 0;
+ struct libphazr_descriptor *xdesc = (struct libphazr_descriptor *) desc;
+ int padding_size = get_padded_blocksize(xdesc->w, xdesc->hd, blocksize) - blocksize;
+ char **decoded = malloc(sizeof(char*) * (xdesc->k + xdesc->m));
+
+ if (NULL == decoded) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ for (i = 0; i < xdesc->k; i++) {
+ decoded[i] = data[i];
+ }
+
+ for (i = 0; i < xdesc->m; i++) {
+ decoded[i + xdesc->k] = parity[i];
+ }
+
+ ret = xdesc->matrix_decode(xdesc->inverse_precoding_matrix, xdesc->matrix, decoded,
+ missing_idxs, xdesc->k, xdesc->m, xdesc->w, xdesc->hd, blocksize, padding_size);
+
+out:
+ free(decoded);
+
+ return ret;
+}
+
+static int pio_matrix_reconstruct(void *desc, char **data, char **parity,
+ int *missing_idxs, int destination_idx, int blocksize)
+{
+ int i, ret = 0;
+ struct libphazr_descriptor *xdesc = (struct libphazr_descriptor *) desc;
+ int padding_size = get_padded_blocksize(xdesc->w, xdesc->hd, blocksize) - blocksize;
+ char **encoded = malloc(sizeof(char*) * (xdesc->k + xdesc->m));
+
+ if (NULL == encoded) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ for (i = 0; i < xdesc->k; i++) {
+ encoded[i] = data[i];
+ }
+
+ for (i = 0; i < xdesc->m; i++) {
+ encoded[i + xdesc->k] = parity[i];
+ }
+
+ ret = xdesc->matrix_reconstruct(xdesc->matrix, encoded, missing_idxs,
+ destination_idx, xdesc->k, xdesc->m, xdesc->w, blocksize, padding_size);
+
+out:
+ free(encoded);
+
+ return ret;
+}
+
+static int pio_min_fragments(void *desc, int *missing_idxs,
+ int *fragments_to_exclude, int *fragments_needed)
+{
+ struct libphazr_descriptor *xdesc = (struct libphazr_descriptor *)desc;
+ uint64_t exclude_bm = convert_list_to_bitmap(fragments_to_exclude);
+ uint64_t missing_bm = convert_list_to_bitmap(missing_idxs) | exclude_bm;
+ int i;
+ int j = 0;
+ int ret = -1;
+
+ for (i = 0; i < (xdesc->k + xdesc->m); i++) {
+ if (!(missing_bm & (1 << i))) {
+ fragments_needed[j] = i;
+ j++;
+ }
+ if (j == xdesc->k) {
+ ret = 0;
+ fragments_needed[j] = -1;
+ break;
+ }
+ }
+
+ return ret;
+}
+
+/**
+ * Return the element-size, which is the number of bits stored
+ * on a given device, per codeword.
+ */
+static int pio_element_size(void *desc)
+{
+ struct libphazr_descriptor *xdesc = (struct libphazr_descriptor *)desc;
+
+ return xdesc->w;
+}
+
+static void * pio_init(struct ec_backend_args *args, void *backend_sohandle)
+{
+ struct libphazr_descriptor *desc = NULL;
+
+ /* allocate and fill in libphazr_descriptor */
+ desc = (struct libphazr_descriptor *)malloc(sizeof(struct libphazr_descriptor));
+ if (NULL == desc) {
+ return NULL;
+ }
+ memset(desc, 0, sizeof(struct libphazr_descriptor));
+
+ desc->k = args->uargs.k;
+ desc->m = args->uargs.m;
+ desc->w = args->uargs.w;
+ desc->hd = args->uargs.hd;
+
+ if (desc->w <= 0)
+ desc->w = DEFAULT_W;
+ args->uargs.w = desc->w;
+
+ if (desc->hd <= 0)
+ desc->hd = DEFAULT_HD;
+ args->uargs.hd = desc->hd;
+
+ /*
+ * ISO C forbids casting a void* to a function pointer.
+ * Since dlsym return returns a void*, we use this union to
+ * "transform" the void* to a function pointer.
+ */
+ union {
+ pio_create_precoding_matrix_func create_precoding_matrix_ptr;
+ pio_create_inverse_precoding_matrix_func create_inverse_precoding_matrix_ptr;
+ pio_create_kmux_matrix_func create_kmux_matrix_ptr;
+ pio_matrix_encode_func matrix_encode_ptr;
+ pio_matrix_decode_func matrix_decode_ptr;
+ pio_matrix_reconstruct_func matrix_reconstruct_ptr;
+ void *vptr;
+ } func_handle = {.vptr = NULL};
+
+ /* fill in function addresses */
+ func_handle.vptr = NULL;
+ func_handle.vptr = dlsym(backend_sohandle, "create_precoding_matrix");
+ desc->create_precoding_matrix = func_handle.create_precoding_matrix_ptr;
+ if (NULL == desc->create_precoding_matrix) {
+ goto error;
+ }
+
+ func_handle.vptr = NULL;
+ func_handle.vptr = dlsym(backend_sohandle, "create_inverse_precoding_matrix");
+ desc->create_inverse_precoding_matrix = func_handle.create_inverse_precoding_matrix_ptr;
+ if (NULL == desc->create_inverse_precoding_matrix) {
+ goto error;
+ }
+
+ func_handle.vptr = NULL;
+ func_handle.vptr = dlsym(backend_sohandle, "create_kmux_matrix");
+ desc->create_kmux_matrix = func_handle.create_kmux_matrix_ptr;
+ if (NULL == desc->create_kmux_matrix) {
+ goto error;
+ }
+
+ func_handle.vptr = NULL;
+ func_handle.vptr = dlsym(backend_sohandle, "matrix_encode");
+ desc->matrix_encode = func_handle.matrix_encode_ptr;
+ if (NULL == desc->matrix_encode) {
+ goto error;
+ }
+
+ func_handle.vptr = NULL;
+ func_handle.vptr = dlsym(backend_sohandle, "matrix_decode");
+ desc->matrix_decode = func_handle.matrix_decode_ptr;
+ if (NULL == desc->matrix_decode) {
+ goto error;
+ }
+
+ func_handle.vptr = NULL;
+ func_handle.vptr = dlsym(backend_sohandle, "matrix_reconstruct");
+ desc->matrix_reconstruct = func_handle.matrix_reconstruct_ptr;
+ if (NULL == desc->matrix_reconstruct) {
+ goto error;
+ }
+
+ if (NULL == desc->precoding_matrix) {
+ desc->precoding_matrix = desc->create_precoding_matrix(desc->k);
+ if (NULL == desc->precoding_matrix) {
+ goto error;
+ }
+ }
+
+ if (NULL == desc->inverse_precoding_matrix) {
+ desc->inverse_precoding_matrix = desc->create_inverse_precoding_matrix(desc->k);
+ if (NULL == desc->inverse_precoding_matrix) {
+ goto error;
+ }
+ }
+
+ if (NULL == desc->matrix) {
+ desc->matrix = desc->create_kmux_matrix(desc->k, desc->m, desc->w);
+ if (NULL == desc->create_kmux_matrix) {
+ goto error;
+ }
+ }
+
+ return (void *) desc;
+
+error:
+ free(desc->matrix);
+
+ free(desc->precoding_matrix);
+
+ free(desc->inverse_precoding_matrix);
+
+ free(desc);
+
+ return NULL;
+}
+
+static int pio_exit(void *desc)
+{
+ struct libphazr_descriptor *xdesc = (struct libphazr_descriptor*)desc;
+
+ free(xdesc->matrix);
+
+ free(xdesc->precoding_matrix);
+
+ free(xdesc->inverse_precoding_matrix);
+
+ free(xdesc);
+
+ return 0;
+}
+
+static bool pio_is_compatible_with(uint32_t version)
+{
+ return version == backend_libphazr.ec_backend_version;
+}
+
+static size_t pio_get_backend_metadata_size(void *desc, int blocksize)
+{
+ struct libphazr_descriptor *xdesc = (struct libphazr_descriptor *) desc;
+ int padded_blocksize = get_padded_blocksize(xdesc->w, xdesc->hd, blocksize);
+ return padded_blocksize - blocksize;
+}
+
+static size_t pio_get_encode_offset(void *desc, int metadata_size)
+{
+ return metadata_size;
+}
+
+
+struct ec_backend_op_stubs libphazr_op_stubs = {
+ .INIT = pio_init,
+ .EXIT = pio_exit,
+ .ENCODE = pio_matrix_encode,
+ .DECODE = pio_matrix_decode,
+ .FRAGSNEEDED = pio_min_fragments,
+ .RECONSTRUCT = pio_matrix_reconstruct,
+ .ELEMENTSIZE = pio_element_size,
+ .ISCOMPATIBLEWITH = pio_is_compatible_with,
+ .GETMETADATASIZE = pio_get_backend_metadata_size,
+ .GETENCODEOFFSET = pio_get_encode_offset,
+};
+
+struct ec_backend_common backend_libphazr = {
+ .id = EC_BACKEND_LIBPHAZR,
+ .name = LIBPHAZR_LIB_NAME,
+ .soname = LIBPHAZR_SO_NAME,
+ .soversion = LIBPHAZR_LIB_VER_STR,
+ .ops = &libphazr_op_stubs,
+ .ec_backend_version = _VERSION(LIBPHAZR_LIB_MAJOR, LIBPHAZR_LIB_MINOR,
+ LIBPHAZR_LIB_REV),
+};
+
diff --git a/src/backends/rs_vand/liberasurecode_rs_vand.c b/src/backends/rs_vand/liberasurecode_rs_vand.c
index 10f3f9b..cc84b65 100644
--- a/src/backends/rs_vand/liberasurecode_rs_vand.c
+++ b/src/backends/rs_vand/liberasurecode_rs_vand.c
@@ -298,6 +298,8 @@ struct ec_backend_op_stubs liberasurecode_rs_vand_op_stubs = {
.RECONSTRUCT = liberasurecode_rs_vand_reconstruct,
.ELEMENTSIZE = liberasurecode_rs_vand_element_size,
.ISCOMPATIBLEWITH = liberasurecode_rs_vand_is_compatible_with,
+ .GETMETADATASIZE = get_backend_metadata_size_zero,
+ .GETENCODEOFFSET = get_encode_offset_zero,
};
struct ec_backend_common backend_liberasurecode_rs_vand = {
@@ -306,7 +308,6 @@ struct ec_backend_common backend_liberasurecode_rs_vand = {
.soname = LIBERASURECODE_RS_VAND_SO_NAME,
.soversion = LIBERASURECODE_RS_VAND_LIB_VER_STR,
.ops = &liberasurecode_rs_vand_op_stubs,
- .backend_metadata_size = 0,
.ec_backend_version = _VERSION(LIBERASURECODE_RS_VAND_LIB_MAJOR,
LIBERASURECODE_RS_VAND_LIB_MINOR,
LIBERASURECODE_RS_VAND_LIB_REV),
diff --git a/src/backends/shss/shss.c b/src/backends/shss/shss.c
index a7a8f3f..51622f2 100644
--- a/src/backends/shss/shss.c
+++ b/src/backends/shss/shss.c
@@ -286,6 +286,10 @@ static bool shss_is_compatible_with(uint32_t version) {
return version == backend_shss.ec_backend_version;
}
+static size_t shss_get_backend_metadata_size(void *desc, int blocksize) {
+ return METADATA;
+}
+
struct ec_backend_op_stubs shss_op_stubs = {
.INIT = shss_init,
.EXIT = shss_exit,
@@ -295,6 +299,8 @@ struct ec_backend_op_stubs shss_op_stubs = {
.RECONSTRUCT = shss_reconstruct,
.ELEMENTSIZE = shss_element_size,
.ISCOMPATIBLEWITH = shss_is_compatible_with,
+ .GETMETADATASIZE = shss_get_backend_metadata_size,
+ .GETENCODEOFFSET = get_encode_offset_zero,
};
struct ec_backend_common backend_shss = {
@@ -303,5 +309,4 @@ struct ec_backend_common backend_shss = {
.soname = SHSS_SO_NAME,
.soversion = SHSS_LIB_VER_STR,
.ops = &shss_op_stubs,
- .backend_metadata_size = METADATA,
};
diff --git a/src/backends/xor/flat_xor_hd.c b/src/backends/xor/flat_xor_hd.c
index b597bea..dbc1d7f 100644
--- a/src/backends/xor/flat_xor_hd.c
+++ b/src/backends/xor/flat_xor_hd.c
@@ -178,6 +178,8 @@ struct ec_backend_op_stubs flat_xor_hd_op_stubs = {
.RECONSTRUCT = flat_xor_hd_reconstruct,
.ELEMENTSIZE = flar_xor_hd_element_size,
.ISCOMPATIBLEWITH = flat_xor_is_compatible_with,
+ .GETMETADATASIZE = get_backend_metadata_size_zero,
+ .GETENCODEOFFSET = get_encode_offset_zero,
};
struct ec_backend_common backend_flat_xor_hd = {
@@ -186,7 +188,6 @@ struct ec_backend_common backend_flat_xor_hd = {
.soname = FLAT_XOR_SO_NAME,
.soversion = FLAT_XOR_LIB_VER_STR,
.ops = &flat_xor_hd_op_stubs,
- .backend_metadata_size = 0,
.ec_backend_version = _VERSION(FLAT_XOR_LIB_MAJOR,
FLAT_XOR_LIB_MINOR,
FLAT_XOR_LIB_REV),
diff --git a/src/erasurecode.c b/src/erasurecode.c
index a63bc25..542fdb1 100644
--- a/src/erasurecode.c
+++ b/src/erasurecode.c
@@ -50,6 +50,7 @@ extern struct ec_backend_common backend_isa_l_rs_vand;
extern struct ec_backend_common backend_shss;
extern struct ec_backend_common backend_liberasurecode_rs_vand;
extern struct ec_backend_common backend_isa_l_rs_cauchy;
+extern struct ec_backend_common backend_libphazr;
ec_backend_t ec_backends_supported[] = {
(ec_backend_t) &backend_null,
@@ -60,6 +61,7 @@ ec_backend_t ec_backends_supported[] = {
(ec_backend_t) &backend_shss,
(ec_backend_t) &backend_liberasurecode_rs_vand,
(ec_backend_t) &backend_isa_l_rs_cauchy,
+ (ec_backend_t) &backend_libphazr,
NULL,
};
@@ -597,8 +599,8 @@ int liberasurecode_decode(int desc,
}
}
- if (instance->common.id != EC_BACKEND_SHSS) {
- /* shss (ntt_backend) must force to decode */
+ if (instance->common.id != EC_BACKEND_SHSS && instance->common.id != EC_BACKEND_LIBPHAZR) {
+ /* shss (ntt_backend) & libphazr backend must force to decode */
// TODO: Add a frag and function to handle whether the backend want to decode or not.
/*
* Try to re-assebmle the original data before attempting a decode
@@ -1232,7 +1234,11 @@ int liberasurecode_get_fragment_size(int desc, int data_len)
if (NULL == instance)
return -EBACKENDNOTAVAIL;
int aligned_data_len = get_aligned_data_size(instance, data_len);
- int size = (aligned_data_len / instance->args.uargs.k) + instance->common.backend_metadata_size;
+ int blocksize = aligned_data_len / instance->args.uargs.k;
+ int metadata_size = instance->common.ops->get_backend_metadata_size(
+ instance->desc.backend_desc,
+ blocksize);
+ int size = blocksize + metadata_size;
return size;
}
diff --git a/src/erasurecode_postprocessing.c b/src/erasurecode_postprocessing.c
index 18097e1..7d121d4 100644
--- a/src/erasurecode_postprocessing.c
+++ b/src/erasurecode_postprocessing.c
@@ -42,7 +42,9 @@ void add_fragment_metadata(ec_backend_t be, char *fragment,
set_fragment_payload_size(fragment, blocksize);
set_backend_id(fragment, be->common.id);
set_backend_version(fragment, be->common.ec_backend_version);
- set_fragment_backend_metadata_size(fragment, be->common.backend_metadata_size);
+ set_fragment_backend_metadata_size(fragment, be->common.ops->get_backend_metadata_size(
+ be->desc.backend_desc,
+ blocksize));
if (add_chksum) {
set_checksum(ct, fragment, blocksize);
diff --git a/src/erasurecode_preprocessing.c b/src/erasurecode_preprocessing.c
index 8492184..26ad261 100644
--- a/src/erasurecode_preprocessing.c
+++ b/src/erasurecode_preprocessing.c
@@ -43,12 +43,19 @@ int prepare_fragments_for_encode(ec_backend_t instance,
int data_len; /* data len to write to fragment headers */
int aligned_data_len; /* EC algorithm compatible data length */
int buffer_size, payload_size = 0;
+ int metadata_size, data_offset = 0;
/* Calculate data sizes, aligned_data_len guaranteed to be divisible by k*/
data_len = orig_data_size;
aligned_data_len = get_aligned_data_size(instance, orig_data_size);
*blocksize = payload_size = (aligned_data_len / k);
- buffer_size = payload_size + instance->common.backend_metadata_size;
+ metadata_size = instance->common.ops->get_backend_metadata_size(
+ instance->desc.backend_desc,
+ *blocksize);
+ data_offset = instance->common.ops->get_encode_offset(
+ instance->desc.backend_desc,
+ metadata_size);
+ buffer_size = payload_size + metadata_size;
for (i = 0; i < k; i++) {
int copy_size = data_len > payload_size ? payload_size : data_len;
@@ -62,7 +69,7 @@ int prepare_fragments_for_encode(ec_backend_t instance,
encoded_data[i] = get_data_ptr_from_fragment(fragment);
if (data_len > 0) {
- memcpy(encoded_data[i], orig_data, copy_size);
+ memcpy(encoded_data[i] + data_offset, orig_data, copy_size);
}
orig_data += copy_size;
@@ -357,7 +364,6 @@ int fragments_to_string(int k, int m,
char* fragment_data = get_data_ptr_from_fragment(data[i]);
int fragment_size = get_fragment_payload_size(data[i]);
int payload_size = orig_data_size > fragment_size ? fragment_size : orig_data_size;
-
memcpy(internal_payload + string_off, fragment_data, payload_size);
orig_data_size -= payload_size;
string_off += payload_size;