Fix fully-degraded EC writes destroying bitmaps
This commit is contained in:
+8
-7
@@ -669,16 +669,17 @@ void* calc_rmw(void *request_buf, osd_rmw_stripe_t *stripes, uint64_t *read_osd_
|
|||||||
stripes[role].write_end = end;
|
stripes[role].write_end = end;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (write_parity)
|
for (int role = 0; role < pg_minsize; role++)
|
||||||
{
|
{
|
||||||
for (int role = 0; role < pg_minsize; role++)
|
if (write_parity)
|
||||||
{
|
{
|
||||||
cover_read(start, end, stripes[role]);
|
cover_read(start, end, stripes[role]);
|
||||||
if (!stripes[role].read_end && (stripes[role].req_start != 0 || stripes[role].req_end != chunk_size))
|
}
|
||||||
{
|
if (!stripes[role].read_end && (stripes[role].req_start != 0 || stripes[role].req_end > 0 && stripes[role].req_end != chunk_size))
|
||||||
// Read bitmaps even if we don't need data but it's not fully overwritten
|
{
|
||||||
stripes[role].read_end = UINT32_MAX;
|
// Read bitmaps even if we don't need data but it's not fully overwritten
|
||||||
}
|
// And even if we don't write parity - we need to modify the bitmap and write it back
|
||||||
|
stripes[role].read_end = UINT32_MAX;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (write_osd_set != read_osd_set)
|
if (write_osd_set != read_osd_set)
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ void test_recover_53_d5();
|
|||||||
void test_recover_22();
|
void test_recover_22();
|
||||||
void test_ec_find_good_multi_chunks();
|
void test_ec_find_good_multi_chunks();
|
||||||
void test_ec_find_good_42_no_good();
|
void test_ec_find_good_42_no_good();
|
||||||
|
void test_ec_partial_write_no_parity_preserves_bitmap();
|
||||||
|
|
||||||
int main(int narg, char *args[])
|
int main(int narg, char *args[])
|
||||||
{
|
{
|
||||||
@@ -80,6 +81,8 @@ int main(int narg, char *args[])
|
|||||||
test_recover_53_d5();
|
test_recover_53_d5();
|
||||||
// Test 20
|
// Test 20
|
||||||
test_recover_22();
|
test_recover_22();
|
||||||
|
// Test 21
|
||||||
|
test_ec_partial_write_no_parity_preserves_bitmap();
|
||||||
// End
|
// End
|
||||||
printf("all ok\n");
|
printf("all ok\n");
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1507,3 +1510,31 @@ void test_ec_find_good_multi_chunks()
|
|||||||
free(write_buf);
|
free(write_buf);
|
||||||
use_ec(7, 4, false);
|
use_ec(7, 4, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
|
||||||
|
21. EC partial write with all parity OSDs missing — modified bitmaps should be read
|
||||||
|
|
||||||
|
***/
|
||||||
|
|
||||||
|
void test_ec_partial_write_no_parity_preserves_bitmap()
|
||||||
|
{
|
||||||
|
const int bmp = 4;
|
||||||
|
osd_num_t osd_set[5] = { 1, 2, 3, 0, 0 };
|
||||||
|
osd_rmw_stripe_t stripes[5] = {};
|
||||||
|
// Partial write to role 0, offset 0, len 4K
|
||||||
|
void *write_buf = malloc_or_die(4096);
|
||||||
|
split_stripes(2, 128*1024, 0, 4096, stripes);
|
||||||
|
assert(stripes[0].req_start == 0 && stripes[0].req_end == 4096);
|
||||||
|
assert(stripes[1].req_start == 0 && stripes[1].req_end == 0);
|
||||||
|
assert(stripes[2].req_start == 0 && stripes[2].req_end == 0);
|
||||||
|
void *rmw_buf = calc_rmw(write_buf, stripes, osd_set, 5, 3, 3, osd_set, 128*1024, bmp);
|
||||||
|
// stripes[0] now requires a bitmap-only read
|
||||||
|
assert(stripes[0].read_end == UINT32_MAX);
|
||||||
|
assert(stripes[1].read_end == 0);
|
||||||
|
assert(stripes[2].read_end == 0);
|
||||||
|
assert(stripes[3].read_end == 0);
|
||||||
|
assert(stripes[4].read_end == 0);
|
||||||
|
free(rmw_buf);
|
||||||
|
free(write_buf);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user