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:
Kota Tsuyuzaki 2015-02-05 20:15:57 -08:00
parent aa0c960504
commit 57f5c565e6
4 changed files with 43 additions and 1 deletions

View File

@ -126,6 +126,8 @@ int get_aligned_data_size(ec_backend_t instance, int data_len);
char *get_data_ptr_from_fragment(char *buf); char *get_data_ptr_from_fragment(char *buf);
int get_data_ptr_array_from_fragments(char **data_array, char **fragments, int get_data_ptr_array_from_fragments(char **data_array, char **fragments,
int num_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_novalidate(char *buf);
char *get_fragment_ptr_from_data(char *buf); char *get_fragment_ptr_from_data(char *buf);
uint64_t get_fragment_size(char *buf); uint64_t get_fragment_size(char *buf);

View File

@ -333,6 +333,7 @@ int liberasurecode_encode_cleanup(int desc,
char **encoded_parity) char **encoded_parity)
{ {
int i, k, m; int i, k, m;
ec_backend_t instance = liberasurecode_backend_instance_get_by_desc(desc); ec_backend_t instance = liberasurecode_backend_instance_get_by_desc(desc);
if (NULL == instance) { if (NULL == instance) {
return -EBACKENDNOTAVAIL; return -EBACKENDNOTAVAIL;
@ -353,7 +354,6 @@ int liberasurecode_encode_cleanup(int desc,
for (i = 0; i < m; i++) { for (i = 0; i < m; i++) {
free(encoded_parity[i]); free(encoded_parity[i]);
} }
free(encoded_parity); free(encoded_parity);
} }
@ -441,6 +441,9 @@ int liberasurecode_encode(int desc,
ret = prepare_fragments_for_encode(instance, k, m, orig_data, orig_data_size, ret = prepare_fragments_for_encode(instance, k, m, orig_data, orig_data_size,
*encoded_data, *encoded_parity, &blocksize); *encoded_data, *encoded_parity, &blocksize);
if (ret < 0) { 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; goto out;
} }
@ -448,6 +451,9 @@ int liberasurecode_encode(int desc,
ret = instance->common.ops->encode(instance->desc.backend_desc, ret = instance->common.ops->encode(instance->desc.backend_desc,
*encoded_data, *encoded_parity, blocksize); *encoded_data, *encoded_parity, blocksize);
if (ret < 0) { 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; goto out;
} }
@ -455,6 +461,7 @@ int liberasurecode_encode(int desc,
*encoded_data, *encoded_parity); *encoded_data, *encoded_parity);
*fragment_len = get_fragment_size((*encoded_data)[0]); *fragment_len = get_fragment_size((*encoded_data)[0]);
out: out:
if (ret) { if (ret) {
/* Cleanup the allocations we have done */ /* Cleanup the allocations we have done */

View File

@ -232,6 +232,22 @@ int get_data_ptr_array_from_fragments(char **data_array, char **fragments,
return num; 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) char *get_fragment_ptr_from_data_novalidate(char *buf)
{ {
buf -= sizeof(fragment_header_t); buf -= sizeof(fragment_header_t);

View File

@ -213,6 +213,12 @@ out:
return num_frags; 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, static void validate_fragment_checksum(struct ec_args *args,
fragment_metadata_t *metadata, char *fragment_data) 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 *orig_data = create_buffer(orig_data_size, 'x');
char **encoded_data = NULL, **encoded_parity = NULL; char **encoded_data = NULL, **encoded_parity = NULL;
uint64_t encoded_fragment_len = 0; uint64_t encoded_fragment_len = 0;
ec_backend_t instance = NULL;
int (*orig_encode_func)(void *, char **, char **, int);
assert(orig_data != NULL); assert(orig_data != NULL);
rc = liberasurecode_encode(desc, orig_data, orig_data_size, 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, rc = liberasurecode_encode(desc, orig_data, orig_data_size,
&encoded_data, &encoded_parity, NULL); &encoded_data, &encoded_parity, NULL);
assert(rc < 0); 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); free(orig_data);
} }