diff options
author | Tushar Gohad <tushar.gohad@intel.com> | 2015-01-30 18:28:42 -0700 |
---|---|---|
committer | Tushar Gohad <tushar.gohad@intel.com> | 2015-01-30 18:42:04 -0700 |
commit | ff5dd3901748c5419ba3cfd328ebcfb2503be4d1 (patch) | |
tree | d547e8a2ddee1d6b13e510c2151c61edd84dc625 | |
parent | 09efa2dd8402ecf8a783e6b34bd6b8f667ee3298 (diff) | |
download | liberasurecode-ff5dd3901748c5419ba3cfd328ebcfb2503be4d1.tar.gz |
Add optional fragment metadata check for decode
Signed-off-by: Tushar Gohad <tushar.gohad@intel.com>
-rw-r--r-- | include/erasurecode/erasurecode.h | 7 | ||||
-rw-r--r-- | src/erasurecode.c | 26 | ||||
-rw-r--r-- | test/libec_slap.c | 8 | ||||
-rw-r--r-- | test/liberasurecode_test.c | 22 |
4 files changed, 44 insertions, 19 deletions
diff --git a/include/erasurecode/erasurecode.h b/include/erasurecode/erasurecode.h index d53f182..74f6385 100644 --- a/include/erasurecode/erasurecode.h +++ b/include/erasurecode/erasurecode.h @@ -169,6 +169,7 @@ int liberasurecode_encode_cleanup(int desc, char **encoded_data, * @param fragments - erasure encoded fragments (> = k) * @param num_fragments - number of fragments being passed in * @param fragment_len - length of each fragment (assume they are the same) + * @param force_metadata_checks - force fragment metadata checks (default: 0) * @param out_data - _output_ pointer to decoded data * @param out_data_len - _output_ length of decoded output * (both output data pointers are allocated by liberasurecode, @@ -180,6 +181,7 @@ int liberasurecode_encode_cleanup(int desc, char **encoded_data, int liberasurecode_decode(int desc, char **available_fragments, /* input */ int num_fragments, uint64_t fragment_len, /* input */ + int force_metadata_checks, /* input */ char **out_data, uint64_t *out_data_len); /* output */ /** @@ -279,9 +281,9 @@ int liberasurecode_get_fragment_metadata(char *fragment, * from liberasurecode_instance_create() * @param fragment - fragment to verify * -* @return 0 if fragment validation is successful, 1 otherwise. +* @return 1 if fragment validation fails, 0 otherwise. */ -int is_valid_fragment(int desc, char *fragment); +int is_invalid_fragment(int desc, char *fragment); /** * Verify a subset of fragments generated by encode() @@ -336,6 +338,7 @@ typedef enum { EBADCHKSUM = 205, EINVALIDPARAMS = 206, EBADHEADER = 207, + EINSUFFFRAGS = 208, } LIBERASURECODE_ERROR_CODES; /* =~=*=~==~=*=~==~=*=~==~=*=~===~=*=~==~=*=~===~=*=~==~=*=~===~=*=~==~=*=~= */ diff --git a/src/erasurecode.c b/src/erasurecode.c index b4d9872..22aa2e8 100644 --- a/src/erasurecode.c +++ b/src/erasurecode.c @@ -495,6 +495,7 @@ int liberasurecode_decode_cleanup(int desc, char *data) * @param fragments - erasure encoded fragments (> = k) * @param num_fragments - number of fragments being passed in * @param fragment_len - length of each fragment (assume they are the same) + * @param force_metadata_checks - force fragment metadata checks (default: 0) * @param out_data - _output_ pointer to decoded data * @param out_data_len - _output_ length of decoded output * @return 0 on success, -error code otherwise @@ -502,6 +503,7 @@ int liberasurecode_decode_cleanup(int desc, char *data) int liberasurecode_decode(int desc, char **available_fragments, /* input */ int num_fragments, uint64_t fragment_len, /* input */ + int force_metadata_checks, /* input */ char **out_data, uint64_t *out_data_len) /* output */ { int i, j; @@ -546,6 +548,11 @@ int liberasurecode_decode(int desc, k = instance->args.uargs.k; m = instance->args.uargs.m; + if (num_fragments < k) { + ret = -EINSUFFFRAGS; + goto out; + } + /* * Try to re-assebmle the original data before attempting a decode */ @@ -578,6 +585,21 @@ int liberasurecode_decode(int desc, log_error("Could not allocate missing_idxs buffer!"); goto out; } + + /* If metadata checks requested, check fragment integrity upfront */ + if (force_metadata_checks) { + int num_invalid_fragments = 0; + for (i = 0; i < num_fragments; ++i) { + if (is_invalid_fragment(desc, available_fragments[i])) { + ++num_invalid_fragments; + } + } + if (num_invalid_fragments > (k - 1)) { + ret = -EINSUFFFRAGS; + log_error("Not enough valid fragments available for decode!"); + goto out; + } + } /* * Separate the fragments into data and parity. Also determine which @@ -965,13 +987,13 @@ int liberasurecode_verify_fragment_metadata(ec_backend_t be, return 0; } -int is_valid_fragment(int desc, char *fragment) +int is_invalid_fragment(int desc, char *fragment) { uint32_t ver = 0; fragment_metadata_t fragment_metadata; ec_backend_t be = liberasurecode_backend_instance_get_by_desc(desc); if (!be) { - log_error("Unable to verify stripe metadata: invalid backend id %d.", + log_error("Unable to verify fragment metadata: invalid backend id %d.", desc); return 1; } diff --git a/test/libec_slap.c b/test/libec_slap.c index f3166fe..0f3c24b 100644 --- a/test/libec_slap.c +++ b/test/libec_slap.c @@ -283,8 +283,8 @@ static int test_hd_code(struct ec_args *args, create_frags_array_set(&frags,encoded_data, args->k, encoded_parity, args->m, mask); rc = liberasurecode_decode(desc, frags.array, frags.num_fragments, - encoded_fragment_len, &out_data, - &out_data_len); + encoded_fragment_len, 1, + &out_data, &out_data_len); assert(rc == 0); assert(out_data_len == blocksize * args->k); if (memcmp(data, out_data, out_data_len) != 0) { @@ -308,8 +308,8 @@ static int test_hd_code(struct ec_args *args, create_frags_array_set(&frags,encoded_data, args->k, encoded_parity, args->m, mask); rc = liberasurecode_decode(desc, frags.array, frags.num_fragments, - encoded_fragment_len, &out_data, - &out_data_len); + encoded_fragment_len, 1, + &out_data, &out_data_len); free(frags.array); free(out_data); diff --git a/test/liberasurecode_test.c b/test/liberasurecode_test.c index 49b70c6..b3c17df 100644 --- a/test/liberasurecode_test.c +++ b/test/liberasurecode_test.c @@ -346,23 +346,23 @@ static void test_decode_invalid_args() encoded_parity, &null_args, skips); rc = liberasurecode_decode(-1, avail_frags, num_avail_frags, - encoded_fragment_len, &decoded_data, - &decoded_data_len); + encoded_fragment_len, 1, + &decoded_data, &decoded_data_len); assert(rc < 0); rc = liberasurecode_decode(desc, NULL, num_avail_frags, - encoded_fragment_len, &decoded_data, - &decoded_data_len); + encoded_fragment_len, 1, + &decoded_data, &decoded_data_len); assert(rc < 0); rc = liberasurecode_decode(desc, avail_frags, num_avail_frags, - encoded_fragment_len, NULL, - &decoded_data_len); + encoded_fragment_len, 1, + NULL, &decoded_data_len); assert(rc < 0); rc = liberasurecode_decode(desc, avail_frags, num_avail_frags, - encoded_fragment_len, &decoded_data, - NULL); + encoded_fragment_len, 1, + &decoded_data, NULL); assert(rc < 0); free(skips); liberasurecode_encode_cleanup(desc, encoded_data, encoded_parity); @@ -540,8 +540,8 @@ static void encode_decode_test_impl(const ec_backend_id_t be_id, assert(num_avail_frags != -1); rc = liberasurecode_decode(desc, avail_frags, num_avail_frags, - encoded_fragment_len, &decoded_data, - &decoded_data_len); + encoded_fragment_len, 1, + &decoded_data, &decoded_data_len); assert(0 == rc); assert(decoded_data_len == orig_data_size); assert(memcmp(decoded_data, orig_data, orig_data_size) == 0); @@ -1002,7 +1002,7 @@ static void verify_fragment_metadata_mismatch_impl(const ec_backend_id_t be_id, default: assert(false); } - rc = is_valid_fragment(desc, avail_frags[i]); + rc = is_invalid_fragment(desc, avail_frags[i]); assert(rc == 1); //heal fragment switch (scenario) { |