diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 6 | ||||
-rw-r--r-- | src/backends/isa-l/isa_l_common.c | 28 | ||||
-rw-r--r-- | src/backends/isa-l/isa_l_rs_cauchy.c | 3 | ||||
-rw-r--r-- | src/backends/isa-l/isa_l_rs_vand.c | 3 | ||||
-rw-r--r-- | src/backends/jerasure/jerasure_rs_cauchy.c | 5 | ||||
-rw-r--r-- | src/backends/jerasure/jerasure_rs_vand.c | 3 | ||||
-rw-r--r-- | src/backends/null/null.c | 5 | ||||
-rw-r--r-- | src/backends/phazrio/libphazr.c | 391 | ||||
-rw-r--r-- | src/backends/rs_vand/liberasurecode_rs_vand.c | 3 | ||||
-rw-r--r-- | src/backends/shss/shss.c | 7 | ||||
-rw-r--r-- | src/backends/xor/flat_xor_hd.c | 3 | ||||
-rw-r--r-- | src/erasurecode.c | 12 | ||||
-rw-r--r-- | src/erasurecode_postprocessing.c | 4 | ||||
-rw-r--r-- | src/erasurecode_preprocessing.c | 12 |
14 files changed, 455 insertions, 30 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_common.c b/src/backends/isa-l/isa_l_common.c index b7fb05e..63e7cca 100644 --- a/src/backends/isa-l/isa_l_common.c +++ b/src/backends/isa-l/isa_l_common.c @@ -41,22 +41,13 @@ int isa_l_encode(void *desc, char **data, char **parity, { isa_l_descriptor *isa_l_desc = (isa_l_descriptor*) desc; - unsigned char *g_tbls = NULL; + unsigned char *g_tbls = isa_l_desc->encode_tables; int k = isa_l_desc->k; int m = isa_l_desc->m; - // Generate g_tbls from encode matrix encode_matrix - g_tbls = malloc(sizeof(unsigned char) * (k * m * 32)); - if (NULL == g_tbls) { - return -1; - } - - isa_l_desc->ec_init_tables(k, m, &isa_l_desc->matrix[k * k], g_tbls); - /* FIXME - make ec_encode_data return a value */ isa_l_desc->ec_encode_data(blocksize, k, m, g_tbls, (unsigned char**)data, (unsigned char**)parity); - free(g_tbls); return 0; } @@ -444,6 +435,7 @@ int isa_l_exit(void *desc) isa_l_desc = (isa_l_descriptor*) desc; + free(isa_l_desc->encode_tables); free(isa_l_desc->matrix); free(isa_l_desc); @@ -536,8 +528,24 @@ void * isa_l_common_init(struct ec_backend_args *args, void *backend_sohandle, */ desc->gf_gen_encoding_matrix(desc->matrix, desc->k + desc->m, desc->k); + + /** + * Generate the tables for encoding + */ + desc->encode_tables = malloc(sizeof(unsigned char) * + (desc->k * desc->m * 32)); + if (NULL == desc->encode_tables) { + goto error_free; + } + + desc->ec_init_tables(desc->k, desc->m, + &desc->matrix[desc->k * desc->k], + desc->encode_tables); + return desc; +error_free: + free(desc->matrix); error: free(desc); 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 d5787ef..82d796a 100644 --- a/src/backends/jerasure/jerasure_rs_cauchy.c +++ b/src/backends/jerasure/jerasure_rs_cauchy.c @@ -451,7 +451,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, @@ -461,7 +460,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 = { @@ -470,7 +470,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; |