最近在PureFlash存储项目上实现EC功能,用到了intel ias-l库的erasure code。查看了isa-l库关于EC的使用用例,这里记录一下编码以及解码过程中函数的使用。
在EC的实现中,我们想要对一段数据进行编码,假设chunk size为128K, ec模式为8+4(k=8, p=4, m=12),因此当凑足1M数据后,我们需要对1M数据进行编码,生成512K的校验数据:
编码
编码过程用到了3个函数:
gf_gen_cauchy1_matrix
ec_init_tables_base
ec_encode_data_base
gf_gen_cauchy1_matrix
基于柯西矩阵生成编码矩阵。编码矩阵用一个m * k 字节长度的buff存放,生成的编码矩阵如下:
encode_matrix每个数据块的大小为1字节
ec_init_tables_base
根据编码矩阵的校验块部分(上图棕色数据块)生成g_tbls
g_tbls每个数据块的大小为32字节
ec_encode_data_base
使用g_tbls对数据进行编码
这里可以简单看下行列式的乘法的实现
for (i = 0; i < len; i++) {
s = 0;
for (j = 0; j < srcs; j++)
s ^= gf_mul(src[j][i], v[j * 32 + l * srcs * 32 + 1]);
dest[l][i] = s;
}
可见检验块(128K)的第i个字节,就是用8个srcs块(128K)的第i个字节,分别与g_tbls的8个块(每个块32字节)中的第一个字节运算所得。
解码
解码的过程需要生成解码矩阵,而此过程需要我们自己编码实现。好在示例中,已经给出了生成解码矩阵的代码,理解了其中的含义,将其移植到我们的代码中即可。
解码相关函数:
gf_gen_decode_matrix
ec_init_tables_base
ec_encode_data_base
gf_gen_decode_matrix
在一个stripe的所有chunk中,已知哪些块存在数据错误,例如上图:nsrcerrs = 2, nerrs = 3
src_in_err
src_err_list
从编码矩阵中,按照src_in_err选择可以用于解码的方阵,decode_index为0, 2, 3, 4, 6, 7, 8,9
对方阵求逆,gf_invert_matrix:
gf_invert_matrix得到的invert_matrix并非最终的解码矩阵。如下代码,生成 nerrs * k 解码矩阵:
for (i = 0; i < nsrcerrs; i++) {
for (j = 0; j < k; j++) {
decode_matrix[k * i + j] = invert_matrix[k * src_err_list[i] + j];
}
}
/* src_err_list from encode_matrix * invert of b for parity decoding */
for (p = nsrcerrs; p < nerrs; p++) {
for (i = 0; i < k; i++) {
s = 0;
for (j = 0; j < k; j++)
s ^= gf_mul(invert_matrix[j * k + i],
encode_matrix[k * src_err_list[p] + j]);
decode_matrix[k * p + i] = s;
}
}
ec_init_tables_base
同编码过程,使用decode_matrix生成g_tbls
ec_encode_data_base
同编码过程,使用g_tbls与正常的数据块运算,恢复损坏的数据块。