diff --git a/src/osd_rmw.cpp b/src/osd_rmw.cpp index 8677f108..593ff95c 100644 --- a/src/osd_rmw.cpp +++ b/src/osd_rmw.cpp @@ -357,7 +357,7 @@ void reconstruct_stripes_ec(osd_rmw_stripe_t *stripes, int pg_size, int pg_minsi auto recover_seq = [&]() { int orig = 0; - for (int other = 0; other < pg_size; other++) + for (int other = 0; other < pg_size && orig < pg_minsize; other++) { if (stripes[other].read_end != 0 && !stripes[other].missing) { @@ -391,6 +391,32 @@ void reconstruct_stripes_ec(osd_rmw_stripe_t *stripes, int pg_size, int pg_minsi { recover_seq(); } + // Recover bitmaps + if (bitmap_size > 0) + { + for (int role = 0; role < pg_minsize; role++) + { + if (stripes[role].read_end != 0 && stripes[role].missing) + { + data_ptrs[pg_minsize + (wanted++)] = (uint8_t*)stripes[role].bmp_buf; + } + } + if (wanted > 0) + { + int orig = 0; + for (int other = 0; other < pg_size && orig < pg_minsize; other++) + { + if (stripes[other].read_end != 0 && !stripes[other].missing) + { + data_ptrs[orig++] = (uint8_t*)stripes[other].bmp_buf; + } + } + ec_encode_data( + bitmap_size, pg_minsize, wanted, dectable, + data_ptrs, data_ptrs + pg_minsize + ); + } + } } #else void reconstruct_stripes_ec(osd_rmw_stripe_t *stripes, int pg_size, int pg_minsize, uint32_t bitmap_size) diff --git a/src/osd_rmw_test.cpp b/src/osd_rmw_test.cpp index 3611dd32..b437928d 100644 --- a/src/osd_rmw_test.cpp +++ b/src/osd_rmw_test.cpp @@ -1045,7 +1045,12 @@ void test16() assert(stripes[3].read_buf == (uint8_t*)read_buf+2*128*1024); set_pattern(stripes[1].read_buf, 128*1024, PATTERN2); memcpy(stripes[3].read_buf, rmw_buf, 128*1024); + memset(stripes[0].bmp_buf, 0xa8, bmp); + memset(stripes[2].bmp_buf, 0xb7, bmp); + assert(bitmaps[1] == 0xFFFFFFFF); + assert(bitmaps[3] == 0xF1F1F1F1); reconstruct_stripes_ec(stripes, 4, 2, bmp); + assert(*(uint32_t*)stripes[3].bmp_buf == 0xF1F1F1F1); assert(bitmaps[0] == 0xFFFFFFFF); check_pattern(stripes[0].read_buf, 128*1024, PATTERN1); free(read_buf);