summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/erasurecode/erasurecode_helpers.h115
-rw-r--r--src/Makefile.am1
-rw-r--r--src/erasurecode_helpers.c211
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;
+}
+
+/* ==~=*=~==~=*=~==~=*=~==~=*=~==~=*=~==~=*=~==~=*=~==~=*=~==~=*=~==~=*=~== */
+