diff options
Diffstat (limited to 'xlators')
-rw-r--r-- | xlators/cluster/ec/src/Makefile.am | 1 | ||||
-rw-r--r-- | xlators/cluster/ec/src/ec-code.c | 221 | ||||
-rw-r--r-- | xlators/cluster/ec/src/ec-galois.c | 9 | ||||
-rw-r--r-- | xlators/cluster/ec/src/ec-helpers.h | 4 | ||||
-rw-r--r-- | xlators/cluster/ec/src/ec-inode-read.c | 6 | ||||
-rw-r--r-- | xlators/cluster/ec/src/ec-messages.h | 16 | ||||
-rw-r--r-- | xlators/cluster/ec/src/ec-method.c | 69 | ||||
-rw-r--r-- | xlators/cluster/ec/src/ec-method.h | 25 | ||||
-rw-r--r-- | xlators/cluster/ec/src/ec-types.h | 3 | ||||
-rw-r--r-- | xlators/cluster/ec/src/ec.c | 12 |
10 files changed, 272 insertions, 94 deletions
diff --git a/xlators/cluster/ec/src/Makefile.am b/xlators/cluster/ec/src/Makefile.am index 0cd34b58f3c..406a636bbc2 100644 --- a/xlators/cluster/ec/src/Makefile.am +++ b/xlators/cluster/ec/src/Makefile.am @@ -70,6 +70,7 @@ AM_CPPFLAGS += -I$(top_srcdir)/xlators/lib/src AM_CPPFLAGS += -I$(top_srcdir)/rpc/rpc-lib/src AM_CPPFLAGS += -I$(top_srcdir)/rpc/xdr/src AM_CPPFLAGS += -I$(top_builddir)/rpc/xdr/src +AM_CPPFLAGS += -DGLUSTERFS_LIBEXECDIR=\"$(GLUSTERFS_LIBEXECDIR)\" AM_CFLAGS = -Wall $(GF_CFLAGS) diff --git a/xlators/cluster/ec/src/ec-code.c b/xlators/cluster/ec/src/ec-code.c index a1f652779f3..9647a08287c 100644 --- a/xlators/cluster/ec/src/ec-code.c +++ b/xlators/cluster/ec/src/ec-code.c @@ -20,6 +20,7 @@ #include "ec-code.h" #include "ec-messages.h" #include "ec-code-c.h" +#include "ec-helpers.h" #ifdef USE_EC_DYNAMIC_X64 #include "ec-code-x64.h" @@ -33,6 +34,11 @@ #include "ec-code-avx.h" #endif +#define EC_CODE_SIZE (1024 * 64) +#define EC_CODE_ALIGN 4096 + +#define EC_CODE_CHUNK_MIN_SIZE 512 + #define EC_PROC_BUFFER_SIZE 4096 #define PROC_CPUINFO "/proc/cpuinfo" @@ -282,7 +288,7 @@ ec_code_prepare(ec_code_t *code, uint32_t count, uint32_t width, builder = GF_MALLOC(sizeof(ec_code_builder_t) + sizeof(ec_code_op_t) * count, ec_mt_ec_code_builder_t); if (builder == NULL) { - return NULL; + return EC_ERR(ENOMEM); } builder->address = 0; @@ -323,15 +329,39 @@ ec_code_chunk_from_space(ec_code_space_t *space) } static void * -ec_code_func_from_chunk(ec_code_chunk_t *chunk) +ec_code_to_executable(ec_code_space_t *space, void *addr) +{ + return (void *)((uintptr_t)addr - (uintptr_t)space + + (uintptr_t)space->exec); +} + +static void * +ec_code_from_executable(ec_code_space_t *space, void *addr) { - return (void *)((uintptr_t)chunk + ec_code_chunk_size()); + return (void *)((uintptr_t)addr - (uintptr_t)space->exec + + (uintptr_t)space); +} + +static void * +ec_code_func_from_chunk(ec_code_chunk_t *chunk, void **exec) +{ + void *addr; + + addr = (void *)((uintptr_t)chunk + ec_code_chunk_size()); + + *exec = ec_code_to_executable(chunk->space, addr); + + return addr; } static ec_code_chunk_t * ec_code_chunk_from_func(ec_code_func_linear_t func) { - return (ec_code_chunk_t *)((uintptr_t)func - ec_code_chunk_size()); + ec_code_chunk_t *chunk; + + chunk = (ec_code_chunk_t *)((uintptr_t)func - ec_code_chunk_size()); + + return ec_code_from_executable(chunk->space, chunk); } static ec_code_chunk_t * @@ -343,6 +373,7 @@ ec_code_chunk_split(ec_code_chunk_t *chunk, size_t size) avail = chunk->size - size - ec_code_chunk_size(); if (avail > 0) { extra = (ec_code_chunk_t *)((uintptr_t)chunk + chunk->size - avail); + extra->space = chunk->space; extra->size = avail; list_add(&extra->list, &chunk->list); chunk->size = size; @@ -361,18 +392,115 @@ ec_code_chunk_touch(ec_code_chunk_t *prev, ec_code_chunk_t *next) return (end == (uintptr_t)next); } +static ec_code_space_t * +ec_code_space_create(ec_code_t *code, size_t size) +{ + char path[] = GLUSTERFS_LIBEXECDIR "/ec-code-dynamic.XXXXXX"; + ec_code_space_t *space; + void *exec; + int32_t fd, err; + + /* We need to create memory areas to store the generated dynamic code. + * Obviously these areas need to be written to be able to create the + * code and they also need to be executable to execute it. + * + * However it's a bad practice to have a memory region that is both + * writable *and* executable. In fact, selinux forbids this and causes + * attempts to do so to fail (unless specifically configured). + * + * To solve the problem we'll use two distinct memory areas mapped to + * the same physical storage. One of the memory areas will have write + * permission, and the other will have execute permission. Both areas + * will have the same contents. The physical storage will be a regular + * file that will be mmapped to both areas. + */ + + /* We need to create a temporary file as the backend storage for the + * memory mapped areas. */ + fd = mkstemp(path); + if (fd < 0) { + err = errno; + gf_msg(THIS->name, GF_LOG_ERROR, err, EC_MSG_DYN_CREATE_FAILED, + "Unable to create a temporary file for the ec dynamic " + "code"); + space = EC_ERR(err); + goto done; + } + /* Once created we don't need to keep it in the file system. It will + * still exist until we close the last file descriptor or unmap the + * memory areas bound to the file. */ + sys_unlink(path); + + size = (size + EC_CODE_ALIGN - 1) & ~(EC_CODE_ALIGN - 1); + if (sys_ftruncate(fd, size) < 0) { + err = errno; + gf_msg(THIS->name, GF_LOG_ERROR, err, EC_MSG_DYN_CREATE_FAILED, + "Unable to resize the file for the ec dynamic code"); + space = EC_ERR(err); + goto done_close; + } + + /* This creates an executable memory area to be able to run the + * generated fragments of code. */ + exec = mmap(NULL, size, PROT_READ | PROT_EXEC, MAP_SHARED, fd, 0); + if (exec == MAP_FAILED) { + err = errno; + gf_msg(THIS->name, GF_LOG_ERROR, err, EC_MSG_DYN_CREATE_FAILED, + "Unable to map the executable area for the ec dynamic " + "code"); + space = EC_ERR(err); + goto done_close; + } + /* It's not important to check the return value of mlock(). If it fails + * everything will continue to work normally. */ + mlock(exec, size); + + /* This maps a read/write memory area to be able to create the dynamici + * code. */ + space = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (space == MAP_FAILED) { + err = errno; + gf_msg(THIS->name, GF_LOG_ERROR, err, EC_MSG_DYN_CREATE_FAILED, + "Unable to map the writable area for the ec dynamic " + "code"); + space = EC_ERR(err); + + munmap(exec, size); + + goto done_close; + } + + space->exec = exec; + space->size = size; + space->code = code; + list_add_tail(&space->list, &code->spaces); + INIT_LIST_HEAD(&space->chunks); + +done_close: + /* If everything has succeeded, we already have the memory areas + * mapped. We don't need the file descriptor anymore because the + * backend storage will be there until the mmaped regions are + * unmapped. */ + sys_close(fd); +done: + return space; +} + static void -ec_code_chunk_merge(ec_code_chunk_t *chunk) +ec_code_space_destroy(ec_code_space_t *space) { - ec_code_chunk_t *item; + list_del_init(&space->list); - list_for_each_entry(item, &chunk->space->chunks, list) { - if (ec_code_chunk_touch(item, chunk)) { - item->size += chunk->size + ec_code_chunk_size(); - chunk = item; + munmap(space->exec, space->size); + munmap(space, space->size); +} - goto check; - } +static void +ec_code_chunk_merge(ec_code_chunk_t *chunk) +{ + ec_code_chunk_t *item, *tmp; + + list_for_each_entry_safe(item, tmp, &chunk->space->chunks, list) { if ((uintptr_t)item > (uintptr_t)chunk) { list_add_tail(&chunk->list, &item->list); if (ec_code_chunk_touch(chunk, item)) { @@ -382,15 +510,18 @@ ec_code_chunk_merge(ec_code_chunk_t *chunk) goto check; } + if (ec_code_chunk_touch(item, chunk)) { + item->size += chunk->size + ec_code_chunk_size(); + list_del_init(&item->list); + chunk = item; + } } list_add_tail(&chunk->list, &chunk->space->chunks); check: - if (chunk->size == EC_CODE_SIZE - ec_code_space_size() - - ec_code_chunk_size()) { - list_del_init(&chunk->space->list); - - munmap(chunk->space, chunk->space->size); + if (chunk->size == chunk->space->size - ec_code_space_size() - + ec_code_chunk_size()) { + ec_code_space_destroy(chunk->space); } } @@ -401,7 +532,10 @@ ec_code_space_alloc(ec_code_t *code, size_t size) ec_code_chunk_t *chunk; size_t map_size; - size = (size + 15) & ~15; + /* To minimize fragmentation, we only allocate chunks of sizes multiples + * of EC_CODE_CHUNK_MIN_SIZE. */ + size = ((size + ec_code_chunk_size() + EC_CODE_CHUNK_MIN_SIZE - 1) & + ~(EC_CODE_CHUNK_MIN_SIZE - 1)) - ec_code_chunk_size(); list_for_each_entry(space, &code->spaces, list) { list_for_each_entry(chunk, &space->chunks, list) { if (chunk->size >= size) { @@ -410,26 +544,17 @@ ec_code_space_alloc(ec_code_t *code, size_t size) } } - map_size = EC_CODE_SIZE; + map_size = EC_CODE_SIZE - ec_code_space_size() - ec_code_chunk_size(); if (map_size < size) { map_size = size; } - space = mmap(NULL, map_size, PROT_EXEC | PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - if (space == NULL) { - return NULL; + space = ec_code_space_create(code, map_size); + if (EC_IS_ERR(space)) { + return (ec_code_chunk_t *)space; } - /* It's not important to check the return value of mlock(). If it fails - * everything will continue to work normally. */ - mlock(space, map_size); - - space->code = code; - space->size = map_size; - list_add_tail(&space->list, &code->spaces); - INIT_LIST_HEAD(&space->chunks); chunk = ec_code_chunk_from_space(space); - chunk->size = EC_CODE_SIZE - ec_code_space_size() - ec_code_chunk_size(); + chunk->size = map_size - ec_code_space_size() - ec_code_chunk_size(); list_add(&chunk->list, &space->chunks); out: @@ -465,7 +590,7 @@ ec_code_free(ec_code_chunk_t *chunk) UNLOCK(lock); } -static gf_boolean_t +static int32_t ec_code_write(ec_code_builder_t *builder) { ec_code_gen_t *gen; @@ -506,7 +631,7 @@ ec_code_write(ec_code_builder_t *builder) } gen->epilog(builder); - return builder->error == 0; + return builder->error; } static void * @@ -514,22 +639,24 @@ ec_code_compile(ec_code_builder_t *builder) { ec_code_chunk_t *chunk; void *func; + int32_t err; - if (!ec_code_write(builder)) { - return NULL; + err = ec_code_write(builder); + if (err != 0) { + return EC_ERR(err); } chunk = ec_code_alloc(builder->code, builder->size); - if (chunk == NULL) { - return NULL; + if (EC_IS_ERR(chunk)) { + return chunk; } - func = ec_code_func_from_chunk(chunk); - builder->data = (uint8_t *)func; + builder->data = ec_code_func_from_chunk(chunk, &func); - if (!ec_code_write(builder)) { + err = ec_code_write(builder); + if (err != 0) { ec_code_free(chunk); - return NULL; + return EC_ERR(err); } GF_FREE(builder); @@ -544,7 +671,7 @@ ec_code_create(ec_gf_t *gf, ec_code_gen_t *gen) code = GF_MALLOC(sizeof(ec_code_t), ec_mt_ec_code_t); if (code == NULL) { - return NULL; + return EC_ERR(ENOMEM); } memset(code, 0, sizeof(ec_code_t)); INIT_LIST_HEAD(&code->spaces); @@ -589,7 +716,7 @@ ec_code_value_next(uint32_t *values, uint32_t count, uint32_t *offset) return next; } -void * +static void * ec_code_build(ec_code_t *code, uint32_t width, uint32_t *values, uint32_t count, gf_boolean_t linear) { @@ -606,8 +733,8 @@ ec_code_build(ec_code_t *code, uint32_t width, uint32_t *values, } builder = ec_code_prepare(code, count, width, linear); - if (builder == NULL) { - return NULL; + if (EC_IS_ERR(builder)) { + return builder; } offset = -1; @@ -659,6 +786,8 @@ void ec_code_error(ec_code_builder_t *builder, int32_t error) { if (builder->error == 0) { + gf_msg(THIS->name, GF_LOG_ERROR, error, EC_MSG_DYN_CODEGEN_FAILED, + "Failed to generate dynamic code"); builder->error = error; } } diff --git a/xlators/cluster/ec/src/ec-galois.c b/xlators/cluster/ec/src/ec-galois.c index 7dbbac09713..8cb4dc2e4e3 100644 --- a/xlators/cluster/ec/src/ec-galois.c +++ b/xlators/cluster/ec/src/ec-galois.c @@ -15,6 +15,7 @@ #include "ec-mem-types.h" #include "ec-gf8.h" +#include "ec-helpers.h" static ec_gf_t * ec_gf_alloc(uint32_t bits, uint32_t mod) @@ -48,7 +49,7 @@ failed_log: failed_gf: GF_FREE(gf); failed: - return NULL; + return EC_ERR(ENOMEM); } static void @@ -79,7 +80,7 @@ ec_gf_prepare(uint32_t bits, uint32_t mod) uint32_t i, j; if (bits != 8) { - return NULL; + return EC_ERR(EINVAL); } tbl = ec_gf8_mul; @@ -88,8 +89,8 @@ ec_gf_prepare(uint32_t bits, uint32_t mod) } gf = ec_gf_alloc(bits, mod); - if (gf == NULL) { - return NULL; + if (EC_IS_ERR(gf)) { + return gf; } ec_gf_init_tables(gf); diff --git a/xlators/cluster/ec/src/ec-helpers.h b/xlators/cluster/ec/src/ec-helpers.h index dfea6fef537..0b355bd440e 100644 --- a/xlators/cluster/ec/src/ec-helpers.h +++ b/xlators/cluster/ec/src/ec-helpers.h @@ -13,6 +13,10 @@ #include "ec-types.h" +#define EC_ERR(_x) ((void *)-(intptr_t)(_x)) +#define EC_IS_ERR(_x) (((uintptr_t)(_x) & ~0xfffULL) == ~0xfffULL) +#define EC_GET_ERR(_x) ((int32_t)(intptr_t)(_x)) + #define EC_ALIGN_CHECK(_ptr, _align) \ ((((uintptr_t)(_ptr)) & ((_align) - 1)) == 0) diff --git a/xlators/cluster/ec/src/ec-inode-read.c b/xlators/cluster/ec/src/ec-inode-read.c index 6752b675273..775b2baa043 100644 --- a/xlators/cluster/ec/src/ec-inode-read.c +++ b/xlators/cluster/ec/src/ec-inode-read.c @@ -1186,7 +1186,11 @@ int32_t ec_readv_rebuild(ec_t * ec, ec_fop_data_t * fop, ec_cbk_data_t * cbk) goto out; } - ec_method_decode(&ec->matrix, fsize, cbk->mask, values, blocks, ptr); + err = ec_method_decode(&ec->matrix, fsize, cbk->mask, values, blocks, + ptr); + if (err != 0) { + goto out; + } vector[0].iov_base = ptr + fop->head; vector[0].iov_len = size - fop->head; diff --git a/xlators/cluster/ec/src/ec-messages.h b/xlators/cluster/ec/src/ec-messages.h index dcdf50b9503..b034e9f203a 100644 --- a/xlators/cluster/ec/src/ec-messages.h +++ b/xlators/cluster/ec/src/ec-messages.h @@ -45,7 +45,7 @@ */ #define GLFS_EC_COMP_BASE GLFS_MSGID_COMP_EC -#define GLFS_NUM_MESSAGES 73 +#define GLFS_NUM_MESSAGES 75 #define GLFS_MSGID_END (GLFS_EC_COMP_BASE + GLFS_NUM_MESSAGES + 1) /* Messaged with message IDs */ #define glfs_msg_start_x GLFS_EC_COMP_BASE, "Invalid: Start of messages" @@ -569,6 +569,20 @@ */ #define EC_MSG_MATRIX_FAILED (GLFS_EC_COMP_BASE + 73) +/*! + * @messageid + * @diagnosis + * @recommendedaction + */ +#define EC_MSG_DYN_CREATE_FAILED (GLFS_EC_COMP_BASE + 74) + +/*! + * @messageid + * @diagnosis + * @recommendedaction + */ +#define EC_MSG_DYN_CODEGEN_FAILED (GLFS_EC_COMP_BASE + 75) + /*------------*/ #define glfs_msg_end_x GLFS_MSGID_END, "Invalid: End of messages" diff --git a/xlators/cluster/ec/src/ec-method.c b/xlators/cluster/ec/src/ec-method.c index d1b122fb6a4..41bf0406ecb 100644 --- a/xlators/cluster/ec/src/ec-method.c +++ b/xlators/cluster/ec/src/ec-method.c @@ -16,6 +16,7 @@ #include "ec-galois.h" #include "ec-code.h" #include "ec-method.h" +#include "ec-helpers.h" static void ec_method_matrix_normal(ec_gf_t *gf, uint32_t *matrix, uint32_t columns, @@ -69,11 +70,12 @@ ec_method_matrix_inverse(ec_gf_t *gf, uint32_t *matrix, uint32_t *values, } } -static gf_boolean_t +static int32_t ec_method_matrix_init(ec_matrix_list_t *list, ec_matrix_t *matrix, uintptr_t mask, uint32_t *rows, gf_boolean_t inverse) { uint32_t i; + int32_t err = 0; matrix->refs = 1; matrix->mask = mask; @@ -92,8 +94,10 @@ ec_method_matrix_init(ec_matrix_list_t *list, ec_matrix_t *matrix, EC_METHOD_WORD_SIZE, matrix->row_data[i].values, matrix->columns); - if (matrix->row_data[i].func.interleaved == NULL) { - return _gf_false; + if (EC_IS_ERR(matrix->row_data[i].func.interleaved)) { + err = EC_GET_ERR(matrix->row_data[i].func.interleaved); + matrix->row_data[i].func.interleaved = NULL; + break; } } } else { @@ -106,13 +110,15 @@ ec_method_matrix_init(ec_matrix_list_t *list, ec_matrix_t *matrix, ec_code_build_linear(matrix->code, EC_METHOD_WORD_SIZE, matrix->row_data[i].values, matrix->columns); - if (matrix->row_data[i].func.linear == NULL) { - return _gf_false; + if (EC_IS_ERR(matrix->row_data[i].func.linear)) { + err = EC_GET_ERR(matrix->row_data[i].func.linear); + matrix->row_data[i].func.linear = NULL; + break; } } } - return _gf_true; + return err; } static void @@ -212,6 +218,7 @@ ec_method_matrix_get(ec_matrix_list_t *list, uintptr_t mask, uint32_t *rows) { ec_matrix_t *matrix; uint32_t pos; + int32_t err = 0; LOCK(&list->lock); @@ -233,16 +240,17 @@ ec_method_matrix_get(ec_matrix_list_t *list, uintptr_t mask, uint32_t *rows) } else { matrix = mem_get0(list->pool); if (matrix == NULL) { + matrix = EC_ERR(ENOMEM); goto out; } matrix->values = (uint32_t *)((uintptr_t)matrix + sizeof(ec_matrix_t) + sizeof(ec_matrix_row_t) * list->columns); } - if (!ec_method_matrix_init(list, matrix, mask, rows, _gf_true)) { + err = ec_method_matrix_init(list, matrix, mask, rows, _gf_true); + if (err != 0) { ec_method_matrix_unref(list, matrix); - - matrix = NULL; + matrix = EC_ERR(err); goto out; } @@ -269,18 +277,20 @@ ec_method_matrix_put(ec_matrix_list_t *list, ec_matrix_t *matrix) UNLOCK(&list->lock); } -static gf_boolean_t +static int32_t ec_method_setup(xlator_t *xl, ec_matrix_list_t *list, const char *gen) { ec_matrix_t *matrix; uint32_t values[list->rows]; uint32_t i; + int32_t err; matrix = GF_MALLOC(sizeof(ec_matrix_t) + sizeof(ec_matrix_row_t) * list->rows + sizeof(uint32_t) * list->columns * list->rows, ec_mt_ec_matrix_t); if (matrix == NULL) { + err = -ENOMEM; goto failed; } memset(matrix, 0, sizeof(ec_matrix_t)); @@ -288,7 +298,9 @@ ec_method_setup(xlator_t *xl, ec_matrix_list_t *list, const char *gen) sizeof(ec_matrix_row_t) * list->rows); list->code = ec_code_create(list->gf, ec_code_detect(xl, gen)); - if (list->code == NULL) { + if (EC_IS_ERR(list->code)) { + err = EC_GET_ERR(list->code); + list->code = NULL; goto failed_matrix; } list->width = list->code->width; @@ -296,23 +308,24 @@ ec_method_setup(xlator_t *xl, ec_matrix_list_t *list, const char *gen) for (i = 0; i < list->rows; i++) { values[i] = i + 1; } - if (!ec_method_matrix_init(list, matrix, 0, values, _gf_false)) { + err = ec_method_matrix_init(list, matrix, 0, values, _gf_false); + if (err != 0) { goto failed_code; } list->encode = matrix; - return _gf_true; + return 0; failed_code: ec_code_destroy(list->code); failed_matrix: GF_FREE(matrix); failed: - return _gf_false; + return err; } -gf_boolean_t +int32_t ec_method_init(xlator_t *xl, ec_matrix_list_t *list, uint32_t columns, uint32_t rows, uint32_t max, const char *gen) { @@ -321,32 +334,37 @@ ec_method_init(xlator_t *xl, ec_matrix_list_t *list, uint32_t columns, list->max = max; list->stripe = EC_METHOD_CHUNK_SIZE * list->columns; INIT_LIST_HEAD(&list->lru); + int32_t err; list->pool = mem_pool_new_fn(sizeof(ec_matrix_t) + sizeof(ec_matrix_row_t) * columns + sizeof(uint32_t) * columns * columns, 128, "ec_matrix_t"); if (list->pool == NULL) { + err = -ENOMEM; goto failed; } list->objects = GF_MALLOC(sizeof(ec_matrix_t *) * max, ec_mt_ec_matrix_t); if (list->objects == NULL) { + err = -ENOMEM; goto failed_pool; } list->gf = ec_gf_prepare(EC_GF_BITS, EC_GF_MOD); - if (list->gf == NULL) { + if (EC_IS_ERR(list->gf)) { + err = EC_GET_ERR(list->gf); goto failed_objects; } - if (!ec_method_setup(xl, list, gen)) { + err = ec_method_setup(xl, list, gen); + if (err != 0) { goto failed_gf; } LOCK_INIT(&list->lock); - return _gf_true; + return 0; failed_gf: ec_gf_destroy(list->gf); @@ -358,7 +376,8 @@ failed: list->pool = NULL; list->objects = NULL; list->gf = NULL; - return _gf_false; + + return err; } void @@ -389,12 +408,12 @@ ec_method_fini(ec_matrix_list_t *list) mem_pool_destroy(list->pool); } -gf_boolean_t +int32_t ec_method_update(xlator_t *xl, ec_matrix_list_t *list, const char *gen) { /* TODO: Allow changing code generator */ - return _gf_true; + return 0; } void @@ -415,7 +434,7 @@ ec_method_encode(ec_matrix_list_t *list, size_t size, void *in, void **out) } } -gf_boolean_t +int32_t ec_method_decode(ec_matrix_list_t *list, size_t size, uintptr_t mask, uint32_t *rows, void **in, void *out) { @@ -424,8 +443,8 @@ ec_method_decode(ec_matrix_list_t *list, size_t size, uintptr_t mask, uint32_t i; matrix = ec_method_matrix_get(list, mask, rows); - if (matrix == NULL) { - return _gf_false; + if (EC_IS_ERR(matrix)) { + return EC_GET_ERR(matrix); } for (pos = 0; pos < size; pos += EC_METHOD_CHUNK_SIZE) { for (i = 0; i < matrix->rows; i++) { @@ -438,5 +457,5 @@ ec_method_decode(ec_matrix_list_t *list, size_t size, uintptr_t mask, ec_method_matrix_put(list, matrix); - return _gf_true; + return 0; } diff --git a/xlators/cluster/ec/src/ec-method.h b/xlators/cluster/ec/src/ec-method.h index 818b54de872..9ba5069ff0e 100644 --- a/xlators/cluster/ec/src/ec-method.h +++ b/xlators/cluster/ec/src/ec-method.h @@ -30,17 +30,20 @@ #define EC_METHOD_CHUNK_SIZE (EC_METHOD_WORD_SIZE * EC_GF_BITS) -gf_boolean_t ec_method_init(xlator_t *xl, ec_matrix_list_t *list, - uint32_t columns, uint32_t rows, uint32_t max, - const char *gen); +int32_t +ec_method_init(xlator_t *xl, ec_matrix_list_t *list, uint32_t columns, + uint32_t rows, uint32_t max, const char *gen); + void ec_method_fini(ec_matrix_list_t *list); -gf_boolean_t ec_method_update(xlator_t *xl, ec_matrix_list_t *list, - const char *gen); - -void ec_method_encode(ec_matrix_list_t *list, size_t size, void *in, - void **out); -gf_boolean_t ec_method_decode(ec_matrix_list_t *list, size_t size, - uintptr_t mask, uint32_t *rows, void **in, - void *out); + +int32_t +ec_method_update(xlator_t *xl, ec_matrix_list_t *list, const char *gen); + +void +ec_method_encode(ec_matrix_list_t *list, size_t size, void *in, void **out); + +int32_t +ec_method_decode(ec_matrix_list_t *list, size_t size, uintptr_t mask, + uint32_t *rows, void **in, void *out); #endif /* __EC_METHOD_H__ */ diff --git a/xlators/cluster/ec/src/ec-types.h b/xlators/cluster/ec/src/ec-types.h index de13b2562f1..751652c20b1 100644 --- a/xlators/cluster/ec/src/ec-types.h +++ b/xlators/cluster/ec/src/ec-types.h @@ -17,8 +17,6 @@ #define EC_GF_MAX_REGS 16 -#define EC_CODE_SIZE (1024 * 64) - enum _ec_read_policy; typedef enum _ec_read_policy ec_read_policy_t; @@ -453,6 +451,7 @@ struct _ec_code_space { struct list_head list; struct list_head chunks; ec_code_t *code; + void *exec; size_t size; }; diff --git a/xlators/cluster/ec/src/ec.c b/xlators/cluster/ec/src/ec.c index 7b16f8fd255..e467fea28b8 100644 --- a/xlators/cluster/ec/src/ec.c +++ b/xlators/cluster/ec/src/ec.c @@ -266,6 +266,7 @@ reconfigure (xlator_t *this, dict_t *options) uint32_t heal_wait_qlen = 0; uint32_t background_heals = 0; int32_t ret = -1; + int32_t err; GF_OPTION_RECONF ("cpu-extensions", extensions, options, str, failed); @@ -295,7 +296,8 @@ reconfigure (xlator_t *this, dict_t *options) ret = -1; } - if (!ec_method_update(this, &ec->matrix, extensions)) { + err = ec_method_update(this, &ec->matrix, extensions); + if (err != 0) { ret = -1; } @@ -588,6 +590,7 @@ init (xlator_t *this) ec_t *ec = NULL; char *read_policy = NULL; char *extensions = NULL; + int32_t err; if (this->parents == NULL) { @@ -644,9 +647,10 @@ init (xlator_t *this) GF_OPTION_INIT("cpu-extensions", extensions, str, failed); - if (!ec_method_init(this, &ec->matrix, ec->fragments, ec->nodes, - ec->nodes * 2, extensions)) { - gf_msg (this->name, GF_LOG_ERROR, 0, EC_MSG_MATRIX_FAILED, + err = ec_method_init(this, &ec->matrix, ec->fragments, ec->nodes, + ec->nodes * 2, extensions); + if (err != 0) { + gf_msg (this->name, GF_LOG_ERROR, -err, EC_MSG_MATRIX_FAILED, "Failed to initialize matrix management"); goto failed; |