diff options
author | Kota Tsuyuzaki <bloodeagle40234@gmail.com> | 2015-02-05 20:15:57 -0800 |
---|---|---|
committer | Kota Tsuyuzaki <bloodeagle40234@gmail.com> | 2015-02-27 15:44:37 +0900 |
commit | 57f5c565e64f8c33d3e299a8542de6d0f083b840 (patch) | |
tree | 2560935514eaa6b18c9f7752a6f60c2c3ae861e2 | |
parent | aa0c9605048153f640b8b871da9e483347e4b70f (diff) | |
download | liberasurecode-57f5c565e64f8c33d3e299a8542de6d0f083b840.tar.gz |
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.
-rw-r--r-- | include/erasurecode/erasurecode_helpers.h | 2 | ||||
-rw-r--r-- | src/erasurecode.c | 9 | ||||
-rw-r--r-- | src/erasurecode_helpers.c | 16 | ||||
-rw-r--r-- | test/liberasurecode_test.c | 17 |
4 files changed, 43 insertions, 1 deletions
diff --git a/include/erasurecode/erasurecode_helpers.h b/include/erasurecode/erasurecode_helpers.h index 93a8b6f..9c4e50d 100644 --- a/include/erasurecode/erasurecode_helpers.h +++ b/include/erasurecode/erasurecode_helpers.h @@ -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); diff --git a/src/erasurecode.c b/src/erasurecode.c index c9a32f1..775f37c 100644 --- a/src/erasurecode.c +++ b/src/erasurecode.c @@ -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); } @@ -441,6 +441,9 @@ int liberasurecode_encode(int desc, 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; } @@ -448,6 +451,9 @@ int liberasurecode_encode(int desc, 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; } @@ -455,6 +461,7 @@ int liberasurecode_encode(int desc, *encoded_data, *encoded_parity); *fragment_len = get_fragment_size((*encoded_data)[0]); + out: if (ret) { /* Cleanup the allocations we have done */ diff --git a/src/erasurecode_helpers.c b/src/erasurecode_helpers.c index 94aa308..54e711b 100644 --- a/src/erasurecode_helpers.c +++ b/src/erasurecode_helpers.c @@ -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); diff --git a/test/liberasurecode_test.c b/test/liberasurecode_test.c index 9d826c6..04d06cf 100644 --- a/test/liberasurecode_test.c +++ b/test/liberasurecode_test.c @@ -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); } |