Fix crash when calculating a parity chunk with previous parity chunk missing (test coming shortly)
parent
1c29ed80b9
commit
61fca7c426
|
@ -154,6 +154,8 @@ struct reed_sol_matrix_t
|
||||||
int refs = 0;
|
int refs = 0;
|
||||||
int *je_data;
|
int *je_data;
|
||||||
uint8_t *isal_data;
|
uint8_t *isal_data;
|
||||||
|
// 32 bytes = 256/8 = max pg_size/8
|
||||||
|
std::map<std::array<uint8_t, 32>, void*> subdata;
|
||||||
std::map<reed_sol_erased_t, void*> decodings;
|
std::map<reed_sol_erased_t, void*> decodings;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -194,6 +196,12 @@ void use_ec(int pg_size, int pg_minsize, bool use)
|
||||||
free(rs_it->second.je_data);
|
free(rs_it->second.je_data);
|
||||||
if (rs_it->second.isal_data)
|
if (rs_it->second.isal_data)
|
||||||
free(rs_it->second.isal_data);
|
free(rs_it->second.isal_data);
|
||||||
|
for (auto sub_it = rs_it->second.subdata.begin(); sub_it != rs_it->second.subdata.end();)
|
||||||
|
{
|
||||||
|
void *data = sub_it->second;
|
||||||
|
rs_it->second.subdata.erase(sub_it++);
|
||||||
|
free(data);
|
||||||
|
}
|
||||||
for (auto dec_it = rs_it->second.decodings.begin(); dec_it != rs_it->second.decodings.end();)
|
for (auto dec_it = rs_it->second.decodings.begin(); dec_it != rs_it->second.decodings.end();)
|
||||||
{
|
{
|
||||||
void *data = dec_it->second;
|
void *data = dec_it->second;
|
||||||
|
@ -808,11 +816,56 @@ void calc_rmw_parity_ec(osd_rmw_stripe_t *stripes, int pg_size, int pg_minsize,
|
||||||
if (end != 0)
|
if (end != 0)
|
||||||
{
|
{
|
||||||
int write_parity = 0;
|
int write_parity = 0;
|
||||||
for (int i = pg_minsize; i < pg_size; i++)
|
bool is_seq = true;
|
||||||
|
for (int i = pg_size-1; i >= pg_minsize; i--)
|
||||||
|
{
|
||||||
if (write_osd_set[i] != 0)
|
if (write_osd_set[i] != 0)
|
||||||
write_parity++;
|
write_parity++;
|
||||||
|
else if (write_parity != 0)
|
||||||
|
is_seq = false;
|
||||||
|
}
|
||||||
if (write_parity > 0)
|
if (write_parity > 0)
|
||||||
{
|
{
|
||||||
|
// First get the coding matrix or sub-matrix
|
||||||
|
void *matrix_data =
|
||||||
|
#ifdef WITH_ISAL
|
||||||
|
matrix->isal_data;
|
||||||
|
#else
|
||||||
|
matrix->je_data;
|
||||||
|
#endif
|
||||||
|
if (!is_seq)
|
||||||
|
{
|
||||||
|
// We need a coding sub-matrix
|
||||||
|
std::array<uint8_t, 32> missing_parity = {};
|
||||||
|
for (int i = pg_minsize; i < pg_size; i++)
|
||||||
|
{
|
||||||
|
if (!write_osd_set[i])
|
||||||
|
missing_parity[(i-pg_minsize) >> 3] |= (1 << ((i-pg_minsize) & 0x7));
|
||||||
|
}
|
||||||
|
auto sub_it = matrix->subdata.find(missing_parity);
|
||||||
|
if (sub_it == matrix->subdata.end())
|
||||||
|
{
|
||||||
|
int item_size =
|
||||||
|
#ifdef WITH_ISAL
|
||||||
|
32;
|
||||||
|
#else
|
||||||
|
sizeof(int);
|
||||||
|
#endif
|
||||||
|
void *subm = malloc_or_die(item_size * write_parity * pg_minsize);
|
||||||
|
for (int i = pg_minsize, j = 0; i < pg_size; i++)
|
||||||
|
{
|
||||||
|
if (write_osd_set[i])
|
||||||
|
{
|
||||||
|
memcpy(subm + item_size*pg_minsize*j, matrix_data + item_size*pg_minsize*(i-pg_minsize), item_size*pg_minsize);
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
matrix->subdata[missing_parity] = subm;
|
||||||
|
matrix_data = subm;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
matrix_data = sub_it->second;
|
||||||
|
}
|
||||||
// Calculate new coding chunks
|
// Calculate new coding chunks
|
||||||
buf_len_t bufs[pg_size][3];
|
buf_len_t bufs[pg_size][3];
|
||||||
int nbuf[pg_size], curbuf[pg_size];
|
int nbuf[pg_size], curbuf[pg_size];
|
||||||
|
@ -841,13 +894,13 @@ void calc_rmw_parity_ec(osd_rmw_stripe_t *stripes, int pg_size, int pg_minsize,
|
||||||
while (pos < end)
|
while (pos < end)
|
||||||
{
|
{
|
||||||
uint32_t next_end = end;
|
uint32_t next_end = end;
|
||||||
for (int i = 0; i < pg_size; i++)
|
for (int i = 0, j = 0; i < pg_size; i++)
|
||||||
{
|
{
|
||||||
if (i < pg_minsize || write_osd_set[i] != 0)
|
if (i < pg_minsize || write_osd_set[i] != 0)
|
||||||
{
|
{
|
||||||
assert(curbuf[i] < nbuf[i]);
|
assert(curbuf[i] < nbuf[i]);
|
||||||
assert(bufs[i][curbuf[i]].buf);
|
assert(bufs[i][curbuf[i]].buf);
|
||||||
data_ptrs[i] = (uint8_t*)bufs[i][curbuf[i]].buf + pos-positions[i];
|
data_ptrs[j++] = (uint8_t*)bufs[i][curbuf[i]].buf + pos-positions[i];
|
||||||
uint32_t this_end = bufs[i][curbuf[i]].len + positions[i];
|
uint32_t this_end = bufs[i][curbuf[i]].len + positions[i];
|
||||||
if (next_end > this_end)
|
if (next_end > this_end)
|
||||||
next_end = this_end;
|
next_end = this_end;
|
||||||
|
@ -868,32 +921,30 @@ void calc_rmw_parity_ec(osd_rmw_stripe_t *stripes, int pg_size, int pg_minsize,
|
||||||
}
|
}
|
||||||
#ifdef WITH_ISAL
|
#ifdef WITH_ISAL
|
||||||
ec_encode_data(
|
ec_encode_data(
|
||||||
next_end-pos, pg_minsize, write_parity, matrix->isal_data,
|
next_end-pos, pg_minsize, write_parity, (uint8_t*)matrix_data,
|
||||||
(uint8_t**)data_ptrs, (uint8_t**)data_ptrs+pg_minsize
|
(uint8_t**)data_ptrs, (uint8_t**)data_ptrs+pg_minsize
|
||||||
);
|
);
|
||||||
#else
|
#else
|
||||||
jerasure_matrix_encode(
|
jerasure_matrix_encode(
|
||||||
pg_minsize, write_parity, OSD_JERASURE_W, matrix->je_data,
|
pg_minsize, write_parity, OSD_JERASURE_W, (int*)matrix_data,
|
||||||
(char**)data_ptrs, (char**)data_ptrs+pg_minsize, next_end-pos
|
(char**)data_ptrs, (char**)data_ptrs+pg_minsize, next_end-pos
|
||||||
);
|
);
|
||||||
#endif
|
#endif
|
||||||
pos = next_end;
|
pos = next_end;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < pg_size; i++)
|
for (int i = 0, j = 0; i < pg_size; i++)
|
||||||
{
|
{
|
||||||
if (i < pg_minsize || write_osd_set[i] != 0)
|
if (i < pg_minsize || write_osd_set[i] != 0)
|
||||||
{
|
data_ptrs[j++] = stripes[i].bmp_buf;
|
||||||
data_ptrs[i] = stripes[i].bmp_buf;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#ifdef WITH_ISAL
|
#ifdef WITH_ISAL
|
||||||
ec_encode_data(
|
ec_encode_data(
|
||||||
bitmap_size, pg_minsize, write_parity, matrix->isal_data,
|
bitmap_size, pg_minsize, write_parity, (uint8_t*)matrix_data,
|
||||||
(uint8_t**)data_ptrs, (uint8_t**)data_ptrs+pg_minsize
|
(uint8_t**)data_ptrs, (uint8_t**)data_ptrs+pg_minsize
|
||||||
);
|
);
|
||||||
#else
|
#else
|
||||||
jerasure_matrix_encode(
|
jerasure_matrix_encode(
|
||||||
pg_minsize, write_parity, OSD_JERASURE_W, matrix->je_data,
|
pg_minsize, write_parity, OSD_JERASURE_W, (int*)matrix_data,
|
||||||
(char**)data_ptrs, (char**)data_ptrs+pg_minsize, bitmap_size
|
(char**)data_ptrs, (char**)data_ptrs+pg_minsize, bitmap_size
|
||||||
);
|
);
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue