summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTushar Gohad <tushar.gohad@intel.com>2015-01-30 18:28:42 -0700
committerTushar Gohad <tushar.gohad@intel.com>2015-01-30 18:42:04 -0700
commitff5dd3901748c5419ba3cfd328ebcfb2503be4d1 (patch)
treed547e8a2ddee1d6b13e510c2151c61edd84dc625
parent09efa2dd8402ecf8a783e6b34bd6b8f667ee3298 (diff)
downloadliberasurecode-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.h7
-rw-r--r--src/erasurecode.c26
-rw-r--r--test/libec_slap.c8
-rw-r--r--test/liberasurecode_test.c22
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) {