summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJenkins <jenkins@review.openstack.org>2017-03-01 02:21:14 +0000
committerGerrit Code Review <review@openstack.org>2017-03-01 02:21:14 +0000
commit26e47421407634a270806ff396d99c69f3fa861c (patch)
tree1797c57c4b6af34cb0cf766d6de48f443b8ef16e /src
parent4ab1336cabe0c1f5d7fc18c21b78f5d21aca5b60 (diff)
parent06e50ea86b6de729fa5dbc23ef41af87b19e636a (diff)
downloadliberasurecode-26e47421407634a270806ff396d99c69f3fa861c.tar.gz
Merge "Add Phazr.IO libphazr backend to liberasurecode"
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 6400ca2..3a0365a 100644
--- a/src/backends/jerasure/jerasure_rs_cauchy.c
+++ b/src/backends/jerasure/jerasure_rs_cauchy.c
@@ -447,7 +447,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,
@@ -457,7 +456,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 = {
@@ -466,7 +466,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 b0257a7..9395046 100644
--- a/src/backends/jerasure/jerasure_rs_vand.c
+++ b/src/backends/jerasure/jerasure_rs_vand.c
@@ -368,6 +368,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 = {
@@ -376,7 +378,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 6206b47..fb6d5de 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,
};
@@ -604,8 +606,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
@@ -1239,7 +1241,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;