diff options
| -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;  | 
