Skip to content

Commit

Permalink
fix: proper support of more than 32 fragments
Browse files Browse the repository at this point in the history
The code already has some logic to support more than 32 fragments (bitvalues)
but it is currently not fully functional. This changeset brings full support
to backends supporting more than 32 fragments, especially by changing from
bitmaps to bitvalues in some specific functions.
  • Loading branch information
vrancurel committed Feb 7, 2019
1 parent 15b84e4 commit 4c6da7d
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 39 deletions.
2 changes: 1 addition & 1 deletion include/erasurecode/erasurecode_preprocessing.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ int prepare_fragments_for_decode(
char **data, char **parity,
int *missing_idxs,
int *orig_size, int *fragment_payload_size, int fragment_size,
uint64_t *realloc_bm);
int *realloc_bv);

int get_fragment_partition(
int k, int m,
Expand Down
61 changes: 33 additions & 28 deletions src/erasurecode.c
Original file line number Diff line number Diff line change
Expand Up @@ -555,8 +555,7 @@ int liberasurecode_decode(int desc,
char **data_segments = NULL;
char **parity_segments = NULL;
int *missing_idxs = NULL;

uint64_t realloc_bm = 0;
int *realloc_bv = NULL;

ec_backend_t instance = liberasurecode_backend_instance_get_by_desc(desc);
if (NULL == instance) {
Expand Down Expand Up @@ -585,6 +584,9 @@ int liberasurecode_decode(int desc,
k = instance->args.uargs.k;
m = instance->args.uargs.m;

realloc_bv = alloca((k + m) * sizeof (int));
memset(realloc_bv, 0, (k + m) * sizeof (int));

if (num_fragments < k) {
log_error("Not enough fragments to decode, got %d, need %d!",
num_fragments, k);
Expand Down Expand Up @@ -677,13 +679,13 @@ int liberasurecode_decode(int desc,
* Preparing the fragments for decode. This will alloc aligned buffers
* when unaligned buffers were passed in available_fragments. It passes
* back a bitmap telling us which buffers need to be freed by us
* (realloc_bm).
* (realloc_bv).
*
*/
ret = prepare_fragments_for_decode(k, m,
data, parity, missing_idxs,
&orig_data_size, &blocksize,
fragment_len, &realloc_bm);
fragment_len, realloc_bv);
if (ret < 0) {
log_error("Could not prepare fragments for decode!");
goto out;
Expand Down Expand Up @@ -732,18 +734,18 @@ int liberasurecode_decode(int desc,

out:
/* Free the buffers allocated in prepare_fragments_for_decode */
if (realloc_bm != 0) {
for (i = 0; i < k; i++) {
if (realloc_bm & (1 << i)) {
free(data[i]);
}
if (realloc_bv) {
for (i = 0; i < k; i++) {
if (realloc_bv[i]) {
free(data[i]);
}

for (i = 0; i < m; i++) {
if (realloc_bm & (1 << (i + k))) {
free(parity[i]);
}
}

for (i = 0; i < m; i++) {
if (realloc_bv[i + k]) {
free(parity[i]);
}
}
}

free(data);
Expand Down Expand Up @@ -784,11 +786,11 @@ int liberasurecode_reconstruct_fragment(int desc,
int k = -1;
int m = -1;
int i;
uint64_t realloc_bm = 0;
char **data_segments = NULL;
char **parity_segments = NULL;
int set_chksum = 1;

int *realloc_bv = NULL;

ec_backend_t instance = liberasurecode_backend_instance_get_by_desc(desc);
if (NULL == instance) {
ret = -EBACKENDNOTAVAIL;
Expand All @@ -810,6 +812,9 @@ int liberasurecode_reconstruct_fragment(int desc,
k = instance->args.uargs.k;
m = instance->args.uargs.m;

realloc_bv = alloca((k + m) * sizeof (int));
memset(realloc_bv, 0, (k + m) * sizeof (int));

for (i = 0; i < num_fragments; i++) {
/* Verify metadata checksum */
if (is_invalid_fragment_header(
Expand Down Expand Up @@ -887,11 +892,11 @@ int liberasurecode_reconstruct_fragment(int desc,
* Preparing the fragments for reconstruction. This will alloc aligned
* buffers when unaligned buffers were passed in available_fragments.
* It passes back a bitmap telling us which buffers need to be freed by
* us (realloc_bm).
* us (realloc_bv).
*/
ret = prepare_fragments_for_decode(k, m, data, parity, missing_idxs,
&orig_data_size, &blocksize,
fragment_len, &realloc_bm);
fragment_len, realloc_bv);
if (ret < 0) {
log_error("Could not prepare fragments for reconstruction!");
goto out;
Expand Down Expand Up @@ -935,18 +940,18 @@ int liberasurecode_reconstruct_fragment(int desc,

out:
/* Free the buffers allocated in prepare_fragments_for_decode */
if (realloc_bm != 0) {
for (i = 0; i < k; i++) {
if (realloc_bm & (1 << i)) {
free(data[i]);
}
if (realloc_bv) {
for (i = 0; i < k; i++) {
if (realloc_bv[i]) {
free(data[i]);
}

for (i = 0; i < m; i++) {
if (realloc_bm & (1 << (i + k))) {
free(parity[i]);
}
}

for (i = 0; i < m; i++) {
if (realloc_bv[i + k]) {
free(parity[i]);
}
}
}

free(data);
Expand Down
20 changes: 10 additions & 10 deletions src/erasurecode_preprocessing.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ int prepare_fragments_for_encode(ec_backend_t instance,
}

/*
* Note that the caller should always check realloc_bm during success or
* Note that the caller should always check realloc_bv during success or
* failure to free buffers allocated here. We could free up in this function,
* but it is internal to this library and only used in a few places. In any
* case, the caller has to free up in the success case, so it may as well do
Expand All @@ -122,14 +122,14 @@ int prepare_fragments_for_decode(
char **data, char **parity,
int *missing_idxs,
int *orig_size, int *fragment_payload_size, int fragment_size,
uint64_t *realloc_bm)
int *realloc_bv)
{
int i; /* a counter */
unsigned long long missing_bm; /* bitmap form of missing indexes list */
int missing_bv[k + m]; /* bitvalues form of missing indexes list */
int orig_data_size = -1;
int payload_size = -1;

missing_bm = convert_list_to_bitmap(missing_idxs);
convert_idx_list_to_bitvalues(missing_idxs, missing_bv, k + m);

/*
* Determine if each data fragment is:
Expand All @@ -150,7 +150,7 @@ int prepare_fragments_for_decode(
log_error("Could not allocate data buffer!");
return -ENOMEM;
}
*realloc_bm = *realloc_bm | (1 << i);
realloc_bv[i] = 1;
} else if (!is_addr_aligned((unsigned long)data[i], 16)) {
char *tmp_buf = alloc_fragment_buffer(fragment_size - sizeof(fragment_header_t));
if (NULL == tmp_buf) {
Expand All @@ -159,11 +159,11 @@ int prepare_fragments_for_decode(
}
memcpy(tmp_buf, data[i], fragment_size);
data[i] = tmp_buf;
*realloc_bm = *realloc_bm | (1 << i);
realloc_bv[i] = 1;
}

/* Need to determine the size of the original data */
if (((missing_bm & (1 << i)) == 0) && orig_data_size < 0) {
if (!missing_bv[i] && orig_data_size < 0) {
orig_data_size = get_orig_data_size(data[i]);
if (orig_data_size < 0) {
log_error("Invalid orig_data_size in fragment header!");
Expand All @@ -189,7 +189,7 @@ int prepare_fragments_for_decode(
log_error("Could not allocate parity buffer!");
return -ENOMEM;
}
*realloc_bm = *realloc_bm | (1 << (k + i));
realloc_bv[k + i] = 1;
} else if (!is_addr_aligned((unsigned long)parity[i], 16)) {
char *tmp_buf = alloc_fragment_buffer(fragment_size-sizeof(fragment_header_t));
if (NULL == tmp_buf) {
Expand All @@ -198,11 +198,11 @@ int prepare_fragments_for_decode(
}
memcpy(tmp_buf, parity[i], fragment_size);
parity[i] = tmp_buf;
*realloc_bm = *realloc_bm | (1 << (k + i));
realloc_bv[k + i] = 1;
}

/* Need to determine the size of the original data */
if (((missing_bm & (1 << (k + i))) == 0) && orig_data_size < 0) {
if (!missing_bv[k + i] && orig_data_size < 0) {
orig_data_size = get_orig_data_size(parity[i]);
if (orig_data_size < 0) {
log_error("Invalid orig_data_size in fragment header!");
Expand Down

0 comments on commit 4c6da7d

Please sign in to comment.