Ensure fragment pointers passed to cleanup
This patch achieves a couple of things as follows: - Undoing the liberasurecode_encode_cleanup specification to expect "fragment" pointers as its arguments. - Ensuring liberasurecode_encode to pass "fratment" pointers to liberasurecode_encode_cleanup. liberasurecode_encode_cleanup is used also in pyeclib so that it is expected that the argument pointers (i.e. encoded_data and encoded_parity) should be the collection of the heads of "fragment" pointers. However, when the backend encode fails, liberasurecode keeps "data" pointers behind of fragment_header, and then, goes to "out:" statement to cleanup its memories. It causes invalid pointer failure. This patch adds a translation function from "data" pointers to "fragment" pointers and ensure liberasurecode_encode to pass correct pointers to libersurecode_encode_cleanup.
This commit is contained in:
parent
c91f5a2f84
commit
712bc80ca7
|
@ -126,6 +126,8 @@ int get_aligned_data_size(ec_backend_t instance, int data_len);
|
|||
char *get_data_ptr_from_fragment(char *buf);
|
||||
int get_data_ptr_array_from_fragments(char **data_array, char **fragments,
|
||||
int num_fragments);
|
||||
int get_fragment_ptr_array_from_data(char **frag_array, char **data,
|
||||
int num_data);
|
||||
char *get_fragment_ptr_from_data_novalidate(char *buf);
|
||||
char *get_fragment_ptr_from_data(char *buf);
|
||||
uint64_t get_fragment_size(char *buf);
|
||||
|
|
|
@ -333,6 +333,7 @@ int liberasurecode_encode_cleanup(int desc,
|
|||
char **encoded_parity)
|
||||
{
|
||||
int i, k, m;
|
||||
|
||||
ec_backend_t instance = liberasurecode_backend_instance_get_by_desc(desc);
|
||||
if (NULL == instance) {
|
||||
return -EBACKENDNOTAVAIL;
|
||||
|
@ -353,7 +354,6 @@ int liberasurecode_encode_cleanup(int desc,
|
|||
for (i = 0; i < m; i++) {
|
||||
free(encoded_parity[i]);
|
||||
}
|
||||
|
||||
free(encoded_parity);
|
||||
}
|
||||
|
||||
|
@ -438,23 +438,33 @@ int liberasurecode_encode(int desc,
|
|||
goto out;
|
||||
}
|
||||
|
||||
// encoded_data/parity -> data_ptrs, here
|
||||
ret = prepare_fragments_for_encode(instance, k, m, orig_data, orig_data_size,
|
||||
*encoded_data, *encoded_parity, &blocksize);
|
||||
if (ret < 0) {
|
||||
// ensure encoded_data/parity point the head of fragment_ptr
|
||||
get_fragment_ptr_array_from_data(*encoded_data, *encoded_data, k);
|
||||
get_fragment_ptr_array_from_data(*encoded_parity, *encoded_parity, m);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* call the backend encode function passing it desc instance */
|
||||
// encoded_data/parity -> data_ptrs, here
|
||||
ret = instance->common.ops->encode(instance->desc.backend_desc,
|
||||
*encoded_data, *encoded_parity, blocksize);
|
||||
if (ret < 0) {
|
||||
// ensure encoded_data/parity point the head of fragment_ptr
|
||||
get_fragment_ptr_array_from_data(*encoded_data, *encoded_data, k);
|
||||
get_fragment_ptr_array_from_data(*encoded_parity, *encoded_parity, m);
|
||||
goto out;
|
||||
}
|
||||
|
||||
// encoded_data, encoded_parity -> fragment_ptrs, here
|
||||
ret = finalize_fragments_after_encode(instance, k, m, blocksize, orig_data_size,
|
||||
*encoded_data, *encoded_parity);
|
||||
|
||||
*fragment_len = get_fragment_size((*encoded_data)[0]);
|
||||
|
||||
out:
|
||||
if (ret) {
|
||||
/* Cleanup the allocations we have done */
|
||||
|
|
|
@ -232,6 +232,22 @@ int get_data_ptr_array_from_fragments(char **data_array, char **fragments,
|
|||
return num;
|
||||
}
|
||||
|
||||
int get_fragment_ptr_array_from_data(char **frag_array, char **data,
|
||||
int num_data)
|
||||
{
|
||||
int i = 0, num = 0;
|
||||
for (i = 0; i < num_data; i++) {
|
||||
char *data_ptr = frag_array[i];
|
||||
if (data_ptr == NULL) {
|
||||
data[i] = NULL;
|
||||
continue;
|
||||
}
|
||||
data[i] = get_fragment_ptr_from_data(data_ptr);
|
||||
num++;
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
char *get_fragment_ptr_from_data_novalidate(char *buf)
|
||||
{
|
||||
buf -= sizeof(fragment_header_t);
|
||||
|
|
|
@ -213,6 +213,12 @@ out:
|
|||
return num_frags;
|
||||
}
|
||||
|
||||
static int encode_failure_stub(void *desc, char **data,
|
||||
char **parity, int blocksize)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void validate_fragment_checksum(struct ec_args *args,
|
||||
fragment_metadata_t *metadata, char *fragment_data)
|
||||
{
|
||||
|
@ -280,6 +286,8 @@ static void test_encode_invalid_args()
|
|||
char *orig_data = create_buffer(orig_data_size, 'x');
|
||||
char **encoded_data = NULL, **encoded_parity = NULL;
|
||||
uint64_t encoded_fragment_len = 0;
|
||||
ec_backend_t instance = NULL;
|
||||
int (*orig_encode_func)(void *, char **, char **, int);
|
||||
|
||||
assert(orig_data != NULL);
|
||||
rc = liberasurecode_encode(desc, orig_data, orig_data_size,
|
||||
|
@ -308,6 +316,15 @@ static void test_encode_invalid_args()
|
|||
rc = liberasurecode_encode(desc, orig_data, orig_data_size,
|
||||
&encoded_data, &encoded_parity, NULL);
|
||||
assert(rc < 0);
|
||||
|
||||
instance = liberasurecode_backend_instance_get_by_desc(desc);
|
||||
orig_encode_func = instance->common.ops->encode;
|
||||
instance->common.ops->encode = encode_failure_stub;
|
||||
rc = liberasurecode_encode(desc, orig_data, orig_data_size,
|
||||
&encoded_data, &encoded_parity, &encoded_fragment_len);
|
||||
assert(rc < 0);
|
||||
instance->common.ops->encode = orig_encode_func;
|
||||
|
||||
free(orig_data);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue