diff options
-rw-r--r-- | include/erasurecode/erasurecode_helpers.h | 115 | ||||
-rw-r--r-- | src/Makefile.am | 1 | ||||
-rw-r--r-- | src/erasurecode_helpers.c | 211 |
3 files changed, 327 insertions, 0 deletions
diff --git a/include/erasurecode/erasurecode_helpers.h b/include/erasurecode/erasurecode_helpers.h new file mode 100644 index 0000000..7efdffc --- /dev/null +++ b/include/erasurecode/erasurecode_helpers.h @@ -0,0 +1,115 @@ +/* + * <Copyright> + * + * 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. + * + * liberasurecode API helpers header + * + * vi: set noai tw=79 ts=4 sw=4: + */ + +#ifndef _ERASURECODE_HELPERS_H +#define _ERASURECODE_HELPERS_H + +#include "erasurecode_stdinc.h" + +/* ==~=*=~==~=*=~==~=*=~==~=*=~==~=*=~==~=*=~==~=*=~==~=*=~==~=*=~==~=*=~== */ + +#define PYECC_HEADER_MAGIC 0xb0c5ecc + +#define talloc(type, num) (type *) malloc(sizeof(type) * (num)) + +/* + * Prevent the compiler from padding + * this by using the __packed__ keyword + */ +typedef struct __attribute__((__packed__)) fragment_header_s +{ + uint32_t magic; + uint32_t idx; + uint32_t size; + uint32_t orig_data_size; + // FIXME - reserve 16-bytes for md5 + uint32_t chksum; + // We must be aligned to 16-byte boundaries + // So, size this array accordingly + uint32_t aligned_padding[3]; +} fragment_header_t; + +/* ==~=*=~==~=*=~==~=*=~==~=*=~==~=*=~==~=*=~==~=*=~==~=*=~==~=*=~==~=*=~== */ + +/* Determine if an address is aligned to a particular boundary */ +inline int is_addr_aligned(unsigned long addr, int align) +{ + return (addr & (align - 1)) == 0; +} + +/* + * Convert an int list into a bitmap + * Assume the list is '-1' terminated. + */ +inline unsigned long long convert_list_to_bitmap(int *list) +{ + int i = 0; + unsigned long long bm = 0; + + while (list[i] > -1) { + /* + * TODO: Assert list[i] < 64 + */ + bm |= (1 << list[i]); + i++; + } + + return bm; +} + +/* + * Convert an index list int list into a bitmap + * is_idx_in_erasure[] needs to be allocated by the caller + * @returns number of idxs in error + */ +inline int convert_idx_list_to_bitvalues( + int *list_idxs, // input idx_list + int *is_idx_in_erasure, // output idx list as boolean values (1/0) + int num_idxs) // total number of indexes +{ + int i = 0, n = 0; + + for (i = 0; i < num_idxs; i++) + is_idx_in_erasure[i] = 0; + for (i = 0, n = 0; (list_idxs[i] > -1) && (n < num_idxs); i++, n++) + is_idx_in_erasure[list_idxs[i]] = 1; + + return n; +} + +inline void init_fragment_header(char *buf) +{ + fragment_header_t *header = (fragment_header_t *) buf; + + header->magic = PYECC_HEADER_MAGIC; +} + +/* ==~=*=~==~=*=~==~=*=~==~=*=~==~=*=~==~=*=~==~=*=~==~=*=~==~=*=~==~=*=~== */ + +#endif // _ERASURECODE_HELPERS_H + diff --git a/src/Makefile.am b/src/Makefile.am index d7325a5..9f72004 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -9,6 +9,7 @@ INCLUDES = \ # liberasurecode params liberasurecode_la_SOURCES = \ erasurecode.c \ + erasurecode_helpers.c \ utils/chksum/crc32.c \ utils/chksum/alg_sig.c \ utils/chksum/galois.c \ diff --git a/src/erasurecode_helpers.c b/src/erasurecode_helpers.c new file mode 100644 index 0000000..a851efd --- /dev/null +++ b/src/erasurecode_helpers.c @@ -0,0 +1,211 @@ +/* + * <Copyright> + * + * 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. + * + * liberasurecode API helpers implementation + * + * vi: set noai tw=79 ts=4 sw=4: + */ + +#include "erasurecode_helpers.h" + +/* ==~=*=~==~=*=~==~=*=~==~=*=~==~=*=~==~=*=~==~=*=~==~=*=~==~=*=~==~=*=~== */ + +void *get_aligned_buffer16(int size) +{ + void *buf; + + /** + * Ensure all memory is aligned to 16-byte boundaries + * to support 128-bit operations + */ + if (posix_memalign(&buf, 16, size) < 0) { + return NULL; + } + + bzero(buf, size); + + return buf; +} + +char *alloc_fragment_buffer(int size) +{ + char *buf; + fragment_header_t *header = NULL; + + size += sizeof(fragment_header_t); + get_aligned_buffer16(size); + + header = (fragment_header_t *) buf; + header->magic = PYECC_HEADER_MAGIC; + + return buf; +} + +int free_fragment_buffer(char *buf) +{ + fragment_header_t *header; + + if (buf == NULL) { + return -1; + } + + buf -= sizeof(fragment_header_t); + + header = (fragment_header_t *) buf; + if (header->magic != PYECC_HEADER_MAGIC) { + fprintf(stderr, + "Invalid fragment header (free fragment)!"); + return -1; + } + + free(buf); + return 0; +} + +/* ==~=*=~==~=*=~==~=*=~==~=*=~==~=*=~==~=*=~==~=*=~==~=*=~==~=*=~==~=*=~== */ + +char *get_data_ptr_from_fragment(char *buf) +{ + buf += sizeof(fragment_header_t); + + return buf; +} + +char *get_fragment_ptr_from_data_novalidate(char *buf) +{ + buf -= sizeof(fragment_header_t); + + return buf; +} + +char *get_fragment_ptr_from_data(char *buf) +{ + fragment_header_t *header; + + buf -= sizeof(fragment_header_t); + + header = (fragment_header_t *) buf; + + if (header->magic != PYECC_HEADER_MAGIC) { + fprintf(stderr, "Invalid fragment header (get header ptr)!\n"); + return NULL; + } + + return buf; +} + +/* ==~=*=~==~=*=~==~=*=~==~=*=~==~=*=~==~=*=~==~=*=~==~=*=~==~=*=~==~=*=~== */ + +int set_fragment_idx(char *buf, int idx) +{ + fragment_header_t *header = (fragment_header_t *) buf; + + if (header->magic != PYECC_HEADER_MAGIC) { + fprintf(stderr, "Invalid fragment header (idx check)!\n"); + return -1; + } + + header->idx = idx; + + return 0; +} + +int get_fragment_idx(char *buf) +{ + fragment_header_t *header = (fragment_header_t *) buf; + + if (header->magic != PYECC_HEADER_MAGIC) { + fprintf(stderr, "Invalid fragment header (get idx)!"); + return -1; + } + + return header->idx; +} + +int set_fragment_size(char *buf, int size) +{ + fragment_header_t *header = (fragment_header_t *) buf; + + if (header->magic != PYECC_HEADER_MAGIC) { + fprintf(stderr, "Invalid fragment header (size check)!"); + return -1; + } + + header->size = size; + + return 0; +} + +int get_fragment_size(char *buf) +{ + fragment_header_t *header = (fragment_header_t *) buf; + + if (header->magic != PYECC_HEADER_MAGIC) { + fprintf(stderr, "Invalid fragment header (get size)!"); + return -1; + } + + return header->size; +} + +int set_orig_data_size(char *buf, int orig_data_size) +{ + fragment_header_t *header = (fragment_header_t *) buf; + + if (header->magic != PYECC_HEADER_MAGIC) { + fprintf(stderr, "Invalid fragment header (set orig data check)!"); + return -1; + } + + header->orig_data_size = orig_data_size; + + return 0; +} + +int get_orig_data_size(char *buf) +{ + fragment_header_t *header = (fragment_header_t *) buf; + + if (header->magic != PYECC_HEADER_MAGIC) { + fprintf(stderr, "Invalid fragment header (get orig data check)!"); + return -1; + } + + return header->orig_data_size; +} + +/* ==~=*=~==~=*=~==~=*=~==~=*=~==~=*=~==~=*=~==~=*=~==~=*=~==~=*=~==~=*=~== */ + +int validate_fragment(char *buf) +{ + fragment_header_t *header = (fragment_header_t *) buf; + + if (header->magic != PYECC_HEADER_MAGIC) { + return -1; + } + + return 0; +} + +/* ==~=*=~==~=*=~==~=*=~==~=*=~==~=*=~==~=*=~==~=*=~==~=*=~==~=*=~==~=*=~== */ + |