Verify bitmaps during scrub

This commit is contained in:
Vitaliy Filippov
2026-06-13 19:56:06 +03:00
parent 553cc8ef87
commit f3d662bac7
3 changed files with 26 additions and 9 deletions
+12 -2
View File
@@ -1199,6 +1199,7 @@ static std::vector<int> ec_check_combination(osd_rmw_stripe_t *stripes, int stri
auto & bs = brute_stripes[src.role];
bs.bmp_buf = src.bmp_buf;
bs.write_buf = bs.read_buf = src.read_buf;
bs.role = subset[i];
}
for (int i = 0; i < pg_size; i++)
{
@@ -1209,13 +1210,21 @@ static std::vector<int> ec_check_combination(osd_rmw_stripe_t *stripes, int stri
bs.missing = true;
assert(tmp_buf.size() >= (i+1)*(chunk_size+bitmap_size));
bs.read_buf = bs.write_buf = tmp_buf.data() + i*(chunk_size+bitmap_size);
bs.bmp_buf = bs.read_buf + chunk_size;
if (bitmap_size)
{
bs.bmp_buf = bs.write_buf + chunk_size;
}
}
else if (i >= pg_minsize)
{
// parity chunks are regenerated in their write_bufs, so use a temporary buffer
assert(tmp_buf.size() >= (i+1)*(chunk_size+bitmap_size));
bs.write_buf = tmp_buf.data() + i*(chunk_size+bitmap_size);
if (bitmap_size)
{
bs.bmp_buf = bs.write_buf + chunk_size;
memcpy(bs.bmp_buf, stripes[i].bmp_buf, bitmap_size);
}
}
}
if (is_xor)
@@ -1242,7 +1251,8 @@ static std::vector<int> ec_check_combination(osd_rmw_stripe_t *stripes, int stri
// source chunk, mark OK
good_set.push_back(i);
}
else if (memcmp(stripes[i].role < pg_minsize ? bs.read_buf : bs.write_buf, stripes[i].read_buf, chunk_size) == 0)
else if (memcmp(stripes[i].role < pg_minsize ? bs.read_buf : bs.write_buf, stripes[i].read_buf, chunk_size) == 0 &&
(!bitmap_size || memcmp(bs.bmp_buf, stripes[i].bmp_buf, bitmap_size) == 0))
{
// matching chunk, mark OK
good_set.push_back(i);
+11 -6
View File
@@ -1218,13 +1218,17 @@ void test_ec43_error_bruteforce()
osd_num_t osd_set[7] = { 1, 2, 3, 4, 5, 6, 7 };
osd_rmw_stripe_t stripes[7] = {};
split_stripes(4, 4096, 0, 4096 * 4, stripes);
uint8_t *bmp_buf = (uint8_t*)malloc_or_die(4 * 7);
memset(bmp_buf, 0xff, 4 * 4);
for (int i = 0; i < 7; i++)
stripes[i].bmp_buf = bmp_buf + i*4;
uint8_t *write_buf = (uint8_t*)malloc_or_die(4096 * 7);
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, 7, 4, 7, osd_set, 4096, 0);
calc_rmw_parity_ec(stripes, 7, 4, osd_set, osd_set, 4096, 0);
uint8_t *rmw_buf = (uint8_t*)calc_rmw(write_buf, stripes, osd_set, 7, 4, 7, osd_set, 4096, 4);
calc_rmw_parity_ec(stripes, 7, 4, osd_set, osd_set, 4096, 4);
check_pattern(stripes[4].write_buf, 4096, PATTERN0^PATTERN1^PATTERN2^PATTERN3);
check_pattern(stripes[5].write_buf, 4096, 0xfcee568ba36371ac); // 2nd EC chunk
check_pattern(stripes[6].write_buf, 4096, 0x139274739ae6f387); // 3rd EC chunk
@@ -1242,26 +1246,27 @@ void test_ec43_error_bruteforce()
stripes[i].osd_num = i+1;
}
// All good chunks
auto res = ec_find_good(stripes, 7, 7, 4, false, 4096, 0, 100, true);
auto res = ec_find_good(stripes, 7, 7, 4, false, 4096, 4, 100, true);
assert_eq_vec(res, std::vector<int>({0, 1, 2, 3, 4, 5, 6}));
// 1 missing chunk
set_pattern(write_buf+1*4096, 4096, 0);
res = ec_find_good(stripes, 7, 7, 4, false, 4096, 0, 100, true);
res = ec_find_good(stripes, 7, 7, 4, false, 4096, 4, 100, true);
assert_eq_vec(res, std::vector<int>({0, 2, 3, 4, 5, 6}));
// 2 missing chunks
set_pattern(write_buf+1*4096, 4096, 0);
set_pattern(write_buf+5*4096, 4096, 0);
res = ec_find_good(stripes, 7, 7, 4, false, 4096, 0, 100, true);
res = ec_find_good(stripes, 7, 7, 4, false, 4096, 4, 100, true);
assert_eq_vec(res, std::vector<int>({0, 2, 3, 4, 6}));
// 3 missing chunks
set_pattern(write_buf+1*4096, 4096, 0);
set_pattern(write_buf+5*4096, 4096, 0);
set_pattern(write_buf+6*4096, 4096, 0);
res = ec_find_good(stripes, 7, 7, 4, false, 4096, 0, 100, true);
res = ec_find_good(stripes, 7, 7, 4, false, 4096, 4, 100, true);
assert_eq_vec(res, std::vector<int>());
// Done
free(rmw_buf);
free(write_buf);
free(bmp_buf);
use_ec(7, 4, false);
}
+3 -1
View File
@@ -474,7 +474,9 @@ void osd_t::scrub_check_results(osd_op_t *cur_op)
for (int other = 0; other < role; other++)
{
// Only compare with unique chunks (eq_to[other] == other)
if (eq_to[other] == other && memcmp(op_data->stripes[role].read_buf, op_data->stripes[other].read_buf, bs_block_size) == 0)
if (eq_to[other] == other &&
memcmp(op_data->stripes[role].read_buf, op_data->stripes[other].read_buf, bs_block_size) == 0 &&
memcmp(op_data->stripes[role].bmp_buf, op_data->stripes[other].bmp_buf, clean_entry_bitmap_size) == 0)
{
eq_to[role] = eq_to[other];
break;