Implement brute-force error locator for EC

This commit is contained in:
Vitaliy Filippov
2023-05-20 23:19:39 +03:00
parent 0c78dd7178
commit 281be547eb
3 changed files with 227 additions and 0 deletions
+64
View File
@@ -28,6 +28,7 @@ void test14();
void test15(bool second);
void test16();
void test_recover_22_d2();
void test_ec42_error_bruteforce();
int main(int narg, char *args[])
{
@@ -64,6 +65,8 @@ int main(int narg, char *args[])
test16();
// Test 17
test_recover_22_d2();
// Error bruteforce
test_ec42_error_bruteforce();
// End
printf("all ok\n");
return 0;
@@ -1106,3 +1109,64 @@ void test_recover_22_d2()
// Done
use_ec(4, 2, false);
}
/***
EC 4+2 error location bruteforce
***/
static void assert_eq_vec(const std::vector<int> & a, const std::vector<int> & b)
{
printf("Expect [");
for (int i = 0; i < a.size(); i++)
printf(" %d", a[i]);
printf(" ] have [");
for (int i = 0; i < b.size(); i++)
printf(" %d", b[i]);
printf(" ]\n");
assert(a == b);
}
void test_ec42_error_bruteforce()
{
use_ec(6, 4, true);
osd_num_t osd_set[6] = { 1, 2, 3, 4, 5, 6 };
osd_rmw_stripe_t stripes[6] = {};
split_stripes(4, 4096, 0, 4096 * 4, stripes);
uint8_t *write_buf = (uint8_t*)malloc_or_die(4096 * 6);
set_pattern(write_buf+0*4096, 4096, PATTERN0);
set_pattern(write_buf+1*4096, 4096, PATTERN1);
set_pattern(write_buf+2*4096, 4096, PATTERN2);
set_pattern(write_buf+3*4096, 4096, PATTERN3);
uint8_t *rmw_buf = (uint8_t*)calc_rmw(write_buf, stripes, osd_set, 6, 4, 6, osd_set, 4096, 0);
calc_rmw_parity_ec(stripes, 6, 4, osd_set, osd_set, 4096, 0);
check_pattern(stripes[4].write_buf, 4096, PATTERN0^PATTERN1^PATTERN2^PATTERN3);
check_pattern(stripes[5].write_buf, 4096, 0x139274739ae6f387); // 2nd EC chunk
memcpy(write_buf+4*4096, stripes[4].write_buf, 4096);
memcpy(write_buf+5*4096, stripes[5].write_buf, 4096);
// Try to locate errors
for (int i = 0; i < 6; i++)
{
stripes[i].read_start = 0;
stripes[i].read_end = 4096;
stripes[i].read_buf = write_buf+i*4096;
stripes[i].write_buf = NULL;
}
// All good chunks
auto res = ec_find_good(stripes, 6, 4, false, 4096, 0, 100);
assert_eq_vec(res, std::vector<int>({0, 1, 2, 3, 4, 5}));
// 1 missing chunk
set_pattern(write_buf+1*4096, 4096, 0);
res = ec_find_good(stripes, 6, 4, false, 4096, 0, 100);
assert_eq_vec(res, std::vector<int>({0, 2, 3, 4, 5}));
// 2 missing chunks
set_pattern(write_buf+1*4096, 4096, 0);
set_pattern(write_buf+5*4096, 4096, 0);
res = ec_find_good(stripes, 6, 4, false, 4096, 0, 100);
assert_eq_vec(res, std::vector<int>());
// Done
free(rmw_buf);
free(write_buf);
use_ec(6, 4, false);
}