2026-04-02 16:00:27 +02:00
|
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
2026-04-02 16:25:49 +02:00
|
|
|
// Copyright (C) 2013 Andrea Mazzoleni
|
2013-12-28 09:10:00 +01:00
|
|
|
|
|
|
|
|
#include "internal.h"
|
|
|
|
|
#include "gf.h"
|
|
|
|
|
|
|
|
|
|
/*
|
2014-01-08 17:07:13 +01:00
|
|
|
* GEN1 (RAID5 with xor) 32bit C implementation
|
2013-12-28 09:10:00 +01:00
|
|
|
*/
|
2014-01-08 17:07:13 +01:00
|
|
|
void raid_gen1_int32(int nd, size_t size, void **vv)
|
2013-12-28 09:10:00 +01:00
|
|
|
{
|
2015-03-12 18:53:36 +01:00
|
|
|
uint8_t **v = (uint8_t **)vv;
|
2013-12-28 12:04:16 +01:00
|
|
|
uint8_t *p;
|
2013-12-28 09:10:00 +01:00
|
|
|
int d, l;
|
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
|
|
uint32_t p0;
|
|
|
|
|
uint32_t p1;
|
|
|
|
|
|
|
|
|
|
l = nd - 1;
|
|
|
|
|
p = v[nd];
|
|
|
|
|
|
2013-12-28 12:04:16 +01:00
|
|
|
for (i = 0; i < size; i += 8) {
|
2026-08-18 22:52:46 +02:00
|
|
|
p0 = v_read32(&v[l][i]);
|
|
|
|
|
p1 = v_read32(&v[l][i + 4]);
|
2014-11-12 20:41:00 +01:00
|
|
|
for (d = l - 1; d >= 0; --d) {
|
2026-08-18 22:52:46 +02:00
|
|
|
p0 ^= v_read32(&v[d][i]);
|
|
|
|
|
p1 ^= v_read32(&v[d][i + 4]);
|
2013-12-28 09:10:00 +01:00
|
|
|
}
|
2026-08-18 22:52:46 +02:00
|
|
|
v_write32(&p[i], p0);
|
|
|
|
|
v_write32(&p[i + 4], p1);
|
2013-12-28 09:10:00 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
2014-01-08 17:07:13 +01:00
|
|
|
* GEN1 (RAID5 with xor) 64bit C implementation
|
2013-12-28 09:10:00 +01:00
|
|
|
*/
|
2014-01-08 17:07:13 +01:00
|
|
|
void raid_gen1_int64(int nd, size_t size, void **vv)
|
2013-12-28 09:10:00 +01:00
|
|
|
{
|
2015-03-12 18:53:36 +01:00
|
|
|
uint8_t **v = (uint8_t **)vv;
|
2013-12-28 12:04:16 +01:00
|
|
|
uint8_t *p;
|
2013-12-28 09:10:00 +01:00
|
|
|
int d, l;
|
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
|
|
uint64_t p0;
|
|
|
|
|
uint64_t p1;
|
|
|
|
|
|
|
|
|
|
l = nd - 1;
|
|
|
|
|
p = v[nd];
|
|
|
|
|
|
2013-12-28 12:04:16 +01:00
|
|
|
for (i = 0; i < size; i += 16) {
|
2026-08-18 22:52:46 +02:00
|
|
|
p0 = v_read64(&v[l][i]);
|
|
|
|
|
p1 = v_read64(&v[l][i + 8]);
|
2014-11-12 20:41:00 +01:00
|
|
|
for (d = l - 1; d >= 0; --d) {
|
2026-08-18 22:52:46 +02:00
|
|
|
p0 ^= v_read64(&v[d][i]);
|
|
|
|
|
p1 ^= v_read64(&v[d][i + 8]);
|
2013-12-28 09:10:00 +01:00
|
|
|
}
|
2026-08-18 22:52:46 +02:00
|
|
|
v_write64(&p[i], p0);
|
|
|
|
|
v_write64(&p[i + 8], p1);
|
2013-12-28 09:10:00 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
2026-08-19 01:36:18 +02:00
|
|
|
* GEN2 (double parity) 32bit C implementation
|
2013-12-28 09:10:00 +01:00
|
|
|
*/
|
2026-08-19 01:36:18 +02:00
|
|
|
static __always_inline void raid_gen2_int32_gen(int nd, size_t size, void **vv, int generator)
|
2013-12-28 09:10:00 +01:00
|
|
|
{
|
2015-03-12 18:53:36 +01:00
|
|
|
uint8_t **v = (uint8_t **)vv;
|
2013-12-28 12:04:16 +01:00
|
|
|
uint8_t *p;
|
|
|
|
|
uint8_t *q;
|
2013-12-28 09:10:00 +01:00
|
|
|
int d, l;
|
|
|
|
|
size_t i;
|
2026-07-29 12:47:13 +02:00
|
|
|
const uint32_t poly_32 = raid_poly_32;
|
2013-12-28 09:10:00 +01:00
|
|
|
|
|
|
|
|
uint32_t d0, q0, p0;
|
|
|
|
|
uint32_t d1, q1, p1;
|
2026-08-19 01:36:18 +02:00
|
|
|
uint32_t qold;
|
2013-12-28 09:10:00 +01:00
|
|
|
|
|
|
|
|
l = nd - 1;
|
|
|
|
|
p = v[nd];
|
2014-11-12 20:41:00 +01:00
|
|
|
q = v[nd + 1];
|
2013-12-28 09:10:00 +01:00
|
|
|
|
2013-12-28 12:04:16 +01:00
|
|
|
for (i = 0; i < size; i += 8) {
|
2026-08-18 22:52:46 +02:00
|
|
|
q0 = p0 = v_read32(&v[l][i]);
|
|
|
|
|
q1 = p1 = v_read32(&v[l][i + 4]);
|
2014-11-12 20:41:00 +01:00
|
|
|
for (d = l - 1; d >= 0; --d) {
|
2026-08-18 22:52:46 +02:00
|
|
|
d0 = v_read32(&v[d][i]);
|
|
|
|
|
d1 = v_read32(&v[d][i + 4]);
|
2013-12-28 09:10:00 +01:00
|
|
|
|
|
|
|
|
p0 ^= d0;
|
|
|
|
|
p1 ^= d1;
|
|
|
|
|
|
2026-08-19 01:36:18 +02:00
|
|
|
qold = q0;
|
2026-07-29 12:47:13 +02:00
|
|
|
q0 = x2_32(q0, poly_32);
|
2026-08-19 01:36:18 +02:00
|
|
|
if (generator == 3)
|
|
|
|
|
q0 ^= qold;
|
|
|
|
|
|
|
|
|
|
qold = q1;
|
2026-07-29 12:47:13 +02:00
|
|
|
q1 = x2_32(q1, poly_32);
|
2026-08-19 01:36:18 +02:00
|
|
|
if (generator == 3)
|
|
|
|
|
q1 ^= qold;
|
2013-12-28 09:10:00 +01:00
|
|
|
|
|
|
|
|
q0 ^= d0;
|
|
|
|
|
q1 ^= d1;
|
|
|
|
|
}
|
2026-08-18 22:52:46 +02:00
|
|
|
v_write32(&p[i], p0);
|
|
|
|
|
v_write32(&p[i + 4], p1);
|
|
|
|
|
v_write32(&q[i], q0);
|
|
|
|
|
v_write32(&q[i + 4], q1);
|
2013-12-28 09:10:00 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-19 01:36:18 +02:00
|
|
|
void raid_gen2_int32_raid(int nd, size_t size, void **vv)
|
|
|
|
|
{
|
|
|
|
|
raid_gen2_int32_gen(nd, size, vv, 2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void raid_gen2_int32_aes(int nd, size_t size, void **vv)
|
|
|
|
|
{
|
|
|
|
|
raid_gen2_int32_gen(nd, size, vv, 3);
|
|
|
|
|
}
|
|
|
|
|
|
2013-12-28 09:10:00 +01:00
|
|
|
/*
|
2026-08-19 01:36:18 +02:00
|
|
|
* GEN2 (double parity) 64bit C implementation
|
2013-12-28 09:10:00 +01:00
|
|
|
*/
|
2026-08-19 01:36:18 +02:00
|
|
|
static __always_inline void raid_gen2_int64_gen(int nd, size_t size, void **vv, int generator)
|
2013-12-28 09:10:00 +01:00
|
|
|
{
|
2015-03-12 18:53:36 +01:00
|
|
|
uint8_t **v = (uint8_t **)vv;
|
2013-12-28 12:04:16 +01:00
|
|
|
uint8_t *p;
|
|
|
|
|
uint8_t *q;
|
2013-12-28 09:10:00 +01:00
|
|
|
int d, l;
|
|
|
|
|
size_t i;
|
2026-07-29 12:47:13 +02:00
|
|
|
const uint64_t poly_64 = raid_poly_64;
|
2013-12-28 09:10:00 +01:00
|
|
|
|
|
|
|
|
uint64_t d0, q0, p0;
|
|
|
|
|
uint64_t d1, q1, p1;
|
2026-08-19 01:36:18 +02:00
|
|
|
uint64_t qold;
|
2013-12-28 09:10:00 +01:00
|
|
|
|
|
|
|
|
l = nd - 1;
|
|
|
|
|
p = v[nd];
|
2014-11-12 20:41:00 +01:00
|
|
|
q = v[nd + 1];
|
2013-12-28 09:10:00 +01:00
|
|
|
|
2013-12-28 12:04:16 +01:00
|
|
|
for (i = 0; i < size; i += 16) {
|
2026-08-18 22:52:46 +02:00
|
|
|
q0 = p0 = v_read64(&v[l][i]);
|
|
|
|
|
q1 = p1 = v_read64(&v[l][i + 8]);
|
2014-11-12 20:41:00 +01:00
|
|
|
for (d = l - 1; d >= 0; --d) {
|
2026-08-18 22:52:46 +02:00
|
|
|
d0 = v_read64(&v[d][i]);
|
|
|
|
|
d1 = v_read64(&v[d][i + 8]);
|
2013-12-28 09:10:00 +01:00
|
|
|
|
|
|
|
|
p0 ^= d0;
|
|
|
|
|
p1 ^= d1;
|
|
|
|
|
|
2026-08-19 01:36:18 +02:00
|
|
|
qold = q0;
|
2026-07-29 12:47:13 +02:00
|
|
|
q0 = x2_64(q0, poly_64);
|
2026-08-19 01:36:18 +02:00
|
|
|
if (generator == 3)
|
|
|
|
|
q0 ^= qold;
|
|
|
|
|
|
|
|
|
|
qold = q1;
|
2026-07-29 12:47:13 +02:00
|
|
|
q1 = x2_64(q1, poly_64);
|
2026-08-19 01:36:18 +02:00
|
|
|
if (generator == 3)
|
|
|
|
|
q1 ^= qold;
|
2013-12-28 09:10:00 +01:00
|
|
|
|
|
|
|
|
q0 ^= d0;
|
|
|
|
|
q1 ^= d1;
|
|
|
|
|
}
|
2026-08-18 22:52:46 +02:00
|
|
|
v_write64(&p[i], p0);
|
|
|
|
|
v_write64(&p[i + 8], p1);
|
|
|
|
|
v_write64(&q[i], q0);
|
|
|
|
|
v_write64(&q[i + 8], q1);
|
2013-12-28 09:10:00 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-08-19 01:36:18 +02:00
|
|
|
void raid_gen2_int64_raid(int nd, size_t size, void **vv)
|
|
|
|
|
{
|
|
|
|
|
raid_gen2_int64_gen(nd, size, vv, 2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void raid_gen2_int64_aes(int nd, size_t size, void **vv)
|
|
|
|
|
{
|
|
|
|
|
raid_gen2_int64_gen(nd, size, vv, 3);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void raid_gen2_int8(int nd, size_t size, void **vv)
|
|
|
|
|
{
|
|
|
|
|
raid_gen_ref(nd, 2, size, vv);
|
|
|
|
|
}
|
|
|
|
|
|
2026-06-05 11:01:03 +02:00
|
|
|
/*
|
|
|
|
|
* GENz (triple parity with powers of 2^-1) 32bit C implementation
|
|
|
|
|
*/
|
2026-08-19 01:36:18 +02:00
|
|
|
void raid_genz_int32_raid(int nd, size_t size, void **vv)
|
2026-06-05 11:01:03 +02:00
|
|
|
{
|
2026-07-29 12:47:13 +02:00
|
|
|
uint8_t **v = (uint8_t **)vv;
|
2026-06-05 11:01:03 +02:00
|
|
|
uint8_t *p;
|
|
|
|
|
uint8_t *q;
|
|
|
|
|
uint8_t *r;
|
|
|
|
|
int d, l;
|
|
|
|
|
size_t i;
|
2026-07-29 12:47:13 +02:00
|
|
|
const uint32_t poly_32 = raid_poly_32;
|
|
|
|
|
const uint32_t inv2_32 = raid_inv2_32;
|
2026-06-05 11:01:03 +02:00
|
|
|
|
|
|
|
|
uint32_t d0, r0, q0, p0;
|
|
|
|
|
uint32_t d1, r1, q1, p1;
|
|
|
|
|
|
|
|
|
|
l = nd - 1;
|
|
|
|
|
p = v[nd];
|
|
|
|
|
q = v[nd + 1];
|
|
|
|
|
r = v[nd + 2];
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < size; i += 8) {
|
2026-08-18 22:52:46 +02:00
|
|
|
r0 = q0 = p0 = v_read32(&v[l][i]);
|
|
|
|
|
r1 = q1 = p1 = v_read32(&v[l][i + 4]);
|
2026-06-05 11:01:03 +02:00
|
|
|
for (d = l - 1; d >= 0; --d) {
|
2026-08-18 22:52:46 +02:00
|
|
|
d0 = v_read32(&v[d][i]);
|
|
|
|
|
d1 = v_read32(&v[d][i + 4]);
|
2026-06-05 11:01:03 +02:00
|
|
|
|
|
|
|
|
p0 ^= d0;
|
|
|
|
|
p1 ^= d1;
|
|
|
|
|
|
2026-07-29 12:47:13 +02:00
|
|
|
q0 = x2_32(q0, poly_32);
|
|
|
|
|
q1 = x2_32(q1, poly_32);
|
2026-06-05 11:01:03 +02:00
|
|
|
|
|
|
|
|
q0 ^= d0;
|
|
|
|
|
q1 ^= d1;
|
|
|
|
|
|
2026-07-29 12:47:13 +02:00
|
|
|
r0 = d2_32(r0, inv2_32);
|
|
|
|
|
r1 = d2_32(r1, inv2_32);
|
2026-06-05 11:01:03 +02:00
|
|
|
|
|
|
|
|
r0 ^= d0;
|
|
|
|
|
r1 ^= d1;
|
|
|
|
|
}
|
2026-08-18 22:52:46 +02:00
|
|
|
v_write32(&p[i], p0);
|
|
|
|
|
v_write32(&p[i + 4], p1);
|
|
|
|
|
v_write32(&q[i], q0);
|
|
|
|
|
v_write32(&q[i + 4], q1);
|
|
|
|
|
v_write32(&r[i], r0);
|
|
|
|
|
v_write32(&r[i + 4], r1);
|
2026-06-05 11:01:03 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* GENz (triple parity with powers of 2^-1) 64bit C implementation
|
|
|
|
|
*/
|
2026-08-19 01:36:18 +02:00
|
|
|
void raid_genz_int64_raid(int nd, size_t size, void **vv)
|
2026-06-05 11:01:03 +02:00
|
|
|
{
|
2026-07-29 12:47:13 +02:00
|
|
|
uint8_t **v = (uint8_t **)vv;
|
2026-06-05 11:01:03 +02:00
|
|
|
uint8_t *p;
|
|
|
|
|
uint8_t *q;
|
|
|
|
|
uint8_t *r;
|
|
|
|
|
int d, l;
|
|
|
|
|
size_t i;
|
2026-07-29 12:47:13 +02:00
|
|
|
const uint64_t poly_64 = raid_poly_64;
|
|
|
|
|
const uint64_t inv2_64 = raid_inv2_64;
|
2026-06-05 11:01:03 +02:00
|
|
|
|
|
|
|
|
uint64_t d0, r0, q0, p0;
|
|
|
|
|
uint64_t d1, r1, q1, p1;
|
|
|
|
|
|
|
|
|
|
l = nd - 1;
|
|
|
|
|
p = v[nd];
|
|
|
|
|
q = v[nd + 1];
|
|
|
|
|
r = v[nd + 2];
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < size; i += 16) {
|
2026-08-18 22:52:46 +02:00
|
|
|
r0 = q0 = p0 = v_read64(&v[l][i]);
|
|
|
|
|
r1 = q1 = p1 = v_read64(&v[l][i + 8]);
|
2026-06-05 11:01:03 +02:00
|
|
|
for (d = l - 1; d >= 0; --d) {
|
2026-08-18 22:52:46 +02:00
|
|
|
d0 = v_read64(&v[d][i]);
|
|
|
|
|
d1 = v_read64(&v[d][i + 8]);
|
2026-06-05 11:01:03 +02:00
|
|
|
|
|
|
|
|
p0 ^= d0;
|
|
|
|
|
p1 ^= d1;
|
|
|
|
|
|
2026-07-29 12:47:13 +02:00
|
|
|
q0 = x2_64(q0, poly_64);
|
|
|
|
|
q1 = x2_64(q1, poly_64);
|
2026-06-05 11:01:03 +02:00
|
|
|
|
|
|
|
|
q0 ^= d0;
|
|
|
|
|
q1 ^= d1;
|
|
|
|
|
|
2026-07-29 12:47:13 +02:00
|
|
|
r0 = d2_64(r0, inv2_64);
|
|
|
|
|
r1 = d2_64(r1, inv2_64);
|
2026-06-05 11:01:03 +02:00
|
|
|
|
|
|
|
|
r0 ^= d0;
|
|
|
|
|
r1 ^= d1;
|
|
|
|
|
}
|
2026-08-18 22:52:46 +02:00
|
|
|
v_write64(&p[i], p0);
|
|
|
|
|
v_write64(&p[i + 8], p1);
|
|
|
|
|
v_write64(&q[i], q0);
|
|
|
|
|
v_write64(&q[i + 8], q1);
|
|
|
|
|
v_write64(&r[i], r0);
|
|
|
|
|
v_write64(&r[i + 8], r1);
|
2026-06-05 11:01:03 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-12-28 09:10:00 +01:00
|
|
|
/*
|
2014-01-08 17:07:13 +01:00
|
|
|
* GEN3 (triple parity with Cauchy matrix) 8bit C implementation
|
2013-12-28 12:04:16 +01:00
|
|
|
*
|
2013-12-28 15:12:09 +01:00
|
|
|
* Note that instead of a generic multiplication table, likely resulting
|
2013-12-28 12:04:16 +01:00
|
|
|
* in multiple cache misses, a precomputed table could be used.
|
2013-12-28 09:10:00 +01:00
|
|
|
* But this is only a kind of reference function, and we are not really
|
|
|
|
|
* interested in speed.
|
|
|
|
|
*/
|
2014-01-08 17:07:13 +01:00
|
|
|
void raid_gen3_int8(int nd, size_t size, void **vv)
|
2013-12-28 09:10:00 +01:00
|
|
|
{
|
2015-03-12 18:53:36 +01:00
|
|
|
uint8_t **v = (uint8_t **)vv;
|
2013-12-28 12:04:16 +01:00
|
|
|
uint8_t *p;
|
|
|
|
|
uint8_t *q;
|
|
|
|
|
uint8_t *r;
|
2013-12-28 09:10:00 +01:00
|
|
|
int d, l;
|
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
|
|
uint8_t d0, r0, q0, p0;
|
|
|
|
|
|
|
|
|
|
l = nd - 1;
|
|
|
|
|
p = v[nd];
|
2014-11-12 20:41:00 +01:00
|
|
|
q = v[nd + 1];
|
|
|
|
|
r = v[nd + 2];
|
2013-12-28 09:10:00 +01:00
|
|
|
|
2013-12-28 12:04:16 +01:00
|
|
|
for (i = 0; i < size; i += 1) {
|
2013-12-28 09:10:00 +01:00
|
|
|
p0 = q0 = r0 = 0;
|
2013-12-28 12:04:16 +01:00
|
|
|
for (d = l; d > 0; --d) {
|
2026-08-18 22:52:46 +02:00
|
|
|
d0 = v[d][i];
|
2013-12-28 09:10:00 +01:00
|
|
|
|
|
|
|
|
p0 ^= d0;
|
2026-07-29 12:47:13 +02:00
|
|
|
q0 ^= raid_gfmul[d0][raid_gfgen[1][d]];
|
|
|
|
|
r0 ^= raid_gfmul[d0][raid_gfgen[2][d]];
|
2013-12-28 09:10:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* first disk with all coefficients at 1 */
|
2026-08-18 22:52:46 +02:00
|
|
|
d0 = v[0][i];
|
2013-12-28 09:10:00 +01:00
|
|
|
|
|
|
|
|
p0 ^= d0;
|
|
|
|
|
q0 ^= d0;
|
|
|
|
|
r0 ^= d0;
|
|
|
|
|
|
2026-08-18 22:52:46 +02:00
|
|
|
p[i] = p0;
|
|
|
|
|
q[i] = q0;
|
|
|
|
|
r[i] = r0;
|
2013-12-28 09:10:00 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
2014-01-08 17:07:13 +01:00
|
|
|
* GEN4 (quad parity with Cauchy matrix) 8bit C implementation
|
2013-12-28 12:04:16 +01:00
|
|
|
*
|
2013-12-28 15:12:09 +01:00
|
|
|
* Note that instead of a generic multiplication table, likely resulting
|
2013-12-28 12:04:16 +01:00
|
|
|
* in multiple cache misses, a precomputed table could be used.
|
2013-12-28 09:10:00 +01:00
|
|
|
* But this is only a kind of reference function, and we are not really
|
|
|
|
|
* interested in speed.
|
|
|
|
|
*/
|
2014-01-08 17:07:13 +01:00
|
|
|
void raid_gen4_int8(int nd, size_t size, void **vv)
|
2013-12-28 09:10:00 +01:00
|
|
|
{
|
2015-03-12 18:53:36 +01:00
|
|
|
uint8_t **v = (uint8_t **)vv;
|
2013-12-28 12:04:16 +01:00
|
|
|
uint8_t *p;
|
|
|
|
|
uint8_t *q;
|
|
|
|
|
uint8_t *r;
|
|
|
|
|
uint8_t *s;
|
2013-12-28 09:10:00 +01:00
|
|
|
int d, l;
|
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
|
|
uint8_t d0, s0, r0, q0, p0;
|
|
|
|
|
|
|
|
|
|
l = nd - 1;
|
|
|
|
|
p = v[nd];
|
2014-11-12 20:41:00 +01:00
|
|
|
q = v[nd + 1];
|
|
|
|
|
r = v[nd + 2];
|
|
|
|
|
s = v[nd + 3];
|
2013-12-28 09:10:00 +01:00
|
|
|
|
2013-12-28 12:04:16 +01:00
|
|
|
for (i = 0; i < size; i += 1) {
|
2013-12-28 09:10:00 +01:00
|
|
|
p0 = q0 = r0 = s0 = 0;
|
2013-12-28 12:04:16 +01:00
|
|
|
for (d = l; d > 0; --d) {
|
2026-08-18 22:52:46 +02:00
|
|
|
d0 = v[d][i];
|
2013-12-28 09:10:00 +01:00
|
|
|
|
|
|
|
|
p0 ^= d0;
|
2026-07-29 12:47:13 +02:00
|
|
|
q0 ^= raid_gfmul[d0][raid_gfgen[1][d]];
|
|
|
|
|
r0 ^= raid_gfmul[d0][raid_gfgen[2][d]];
|
|
|
|
|
s0 ^= raid_gfmul[d0][raid_gfgen[3][d]];
|
2013-12-28 09:10:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* first disk with all coefficients at 1 */
|
2026-08-18 22:52:46 +02:00
|
|
|
d0 = v[0][i];
|
2013-12-28 09:10:00 +01:00
|
|
|
|
|
|
|
|
p0 ^= d0;
|
|
|
|
|
q0 ^= d0;
|
|
|
|
|
r0 ^= d0;
|
|
|
|
|
s0 ^= d0;
|
|
|
|
|
|
2026-08-18 22:52:46 +02:00
|
|
|
p[i] = p0;
|
|
|
|
|
q[i] = q0;
|
|
|
|
|
r[i] = r0;
|
|
|
|
|
s[i] = s0;
|
2013-12-28 09:10:00 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
2014-01-08 17:07:13 +01:00
|
|
|
* GEN5 (penta parity with Cauchy matrix) 8bit C implementation
|
2013-12-28 12:04:16 +01:00
|
|
|
*
|
2013-12-28 15:12:09 +01:00
|
|
|
* Note that instead of a generic multiplication table, likely resulting
|
2013-12-28 12:04:16 +01:00
|
|
|
* in multiple cache misses, a precomputed table could be used.
|
2013-12-28 09:10:00 +01:00
|
|
|
* But this is only a kind of reference function, and we are not really
|
|
|
|
|
* interested in speed.
|
|
|
|
|
*/
|
2014-01-08 17:07:13 +01:00
|
|
|
void raid_gen5_int8(int nd, size_t size, void **vv)
|
2013-12-28 09:10:00 +01:00
|
|
|
{
|
2015-03-12 18:53:36 +01:00
|
|
|
uint8_t **v = (uint8_t **)vv;
|
2013-12-28 12:04:16 +01:00
|
|
|
uint8_t *p;
|
|
|
|
|
uint8_t *q;
|
|
|
|
|
uint8_t *r;
|
|
|
|
|
uint8_t *s;
|
|
|
|
|
uint8_t *t;
|
2013-12-28 09:10:00 +01:00
|
|
|
int d, l;
|
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
|
|
uint8_t d0, t0, s0, r0, q0, p0;
|
|
|
|
|
|
|
|
|
|
l = nd - 1;
|
|
|
|
|
p = v[nd];
|
2014-11-12 20:41:00 +01:00
|
|
|
q = v[nd + 1];
|
|
|
|
|
r = v[nd + 2];
|
|
|
|
|
s = v[nd + 3];
|
|
|
|
|
t = v[nd + 4];
|
2013-12-28 09:10:00 +01:00
|
|
|
|
2013-12-28 12:04:16 +01:00
|
|
|
for (i = 0; i < size; i += 1) {
|
2013-12-28 09:10:00 +01:00
|
|
|
p0 = q0 = r0 = s0 = t0 = 0;
|
2013-12-28 12:04:16 +01:00
|
|
|
for (d = l; d > 0; --d) {
|
2026-08-18 22:52:46 +02:00
|
|
|
d0 = v[d][i];
|
2013-12-28 09:10:00 +01:00
|
|
|
|
|
|
|
|
p0 ^= d0;
|
2026-07-29 12:47:13 +02:00
|
|
|
q0 ^= raid_gfmul[d0][raid_gfgen[1][d]];
|
|
|
|
|
r0 ^= raid_gfmul[d0][raid_gfgen[2][d]];
|
|
|
|
|
s0 ^= raid_gfmul[d0][raid_gfgen[3][d]];
|
|
|
|
|
t0 ^= raid_gfmul[d0][raid_gfgen[4][d]];
|
2013-12-28 09:10:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* first disk with all coefficients at 1 */
|
2026-08-18 22:52:46 +02:00
|
|
|
d0 = v[0][i];
|
2013-12-28 09:10:00 +01:00
|
|
|
|
|
|
|
|
p0 ^= d0;
|
|
|
|
|
q0 ^= d0;
|
|
|
|
|
r0 ^= d0;
|
|
|
|
|
s0 ^= d0;
|
|
|
|
|
t0 ^= d0;
|
|
|
|
|
|
2026-08-18 22:52:46 +02:00
|
|
|
p[i] = p0;
|
|
|
|
|
q[i] = q0;
|
|
|
|
|
r[i] = r0;
|
|
|
|
|
s[i] = s0;
|
|
|
|
|
t[i] = t0;
|
2013-12-28 09:10:00 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
2014-01-08 17:07:13 +01:00
|
|
|
* GEN6 (hexa parity with Cauchy matrix) 8bit C implementation
|
2013-12-28 12:04:16 +01:00
|
|
|
*
|
2013-12-28 15:12:09 +01:00
|
|
|
* Note that instead of a generic multiplication table, likely resulting
|
2013-12-28 12:04:16 +01:00
|
|
|
* in multiple cache misses, a precomputed table could be used.
|
2013-12-28 09:10:00 +01:00
|
|
|
* But this is only a kind of reference function, and we are not really
|
|
|
|
|
* interested in speed.
|
|
|
|
|
*/
|
2014-01-08 17:07:13 +01:00
|
|
|
void raid_gen6_int8(int nd, size_t size, void **vv)
|
2013-12-28 09:10:00 +01:00
|
|
|
{
|
2015-03-12 18:53:36 +01:00
|
|
|
uint8_t **v = (uint8_t **)vv;
|
2013-12-28 12:04:16 +01:00
|
|
|
uint8_t *p;
|
|
|
|
|
uint8_t *q;
|
|
|
|
|
uint8_t *r;
|
|
|
|
|
uint8_t *s;
|
|
|
|
|
uint8_t *t;
|
|
|
|
|
uint8_t *u;
|
2013-12-28 09:10:00 +01:00
|
|
|
int d, l;
|
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
|
|
uint8_t d0, u0, t0, s0, r0, q0, p0;
|
|
|
|
|
|
|
|
|
|
l = nd - 1;
|
|
|
|
|
p = v[nd];
|
2014-11-12 20:41:00 +01:00
|
|
|
q = v[nd + 1];
|
|
|
|
|
r = v[nd + 2];
|
|
|
|
|
s = v[nd + 3];
|
|
|
|
|
t = v[nd + 4];
|
|
|
|
|
u = v[nd + 5];
|
2013-12-28 09:10:00 +01:00
|
|
|
|
2013-12-28 12:04:16 +01:00
|
|
|
for (i = 0; i < size; i += 1) {
|
2013-12-28 09:10:00 +01:00
|
|
|
p0 = q0 = r0 = s0 = t0 = u0 = 0;
|
2013-12-28 12:04:16 +01:00
|
|
|
for (d = l; d > 0; --d) {
|
2026-08-18 22:52:46 +02:00
|
|
|
d0 = v[d][i];
|
2013-12-28 09:10:00 +01:00
|
|
|
|
|
|
|
|
p0 ^= d0;
|
2026-07-29 12:47:13 +02:00
|
|
|
q0 ^= raid_gfmul[d0][raid_gfgen[1][d]];
|
|
|
|
|
r0 ^= raid_gfmul[d0][raid_gfgen[2][d]];
|
|
|
|
|
s0 ^= raid_gfmul[d0][raid_gfgen[3][d]];
|
|
|
|
|
t0 ^= raid_gfmul[d0][raid_gfgen[4][d]];
|
|
|
|
|
u0 ^= raid_gfmul[d0][raid_gfgen[5][d]];
|
2013-12-28 09:10:00 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* first disk with all coefficients at 1 */
|
2026-08-18 22:52:46 +02:00
|
|
|
d0 = v[0][i];
|
2013-12-28 09:10:00 +01:00
|
|
|
|
|
|
|
|
p0 ^= d0;
|
|
|
|
|
q0 ^= d0;
|
|
|
|
|
r0 ^= d0;
|
|
|
|
|
s0 ^= d0;
|
|
|
|
|
t0 ^= d0;
|
|
|
|
|
u0 ^= d0;
|
|
|
|
|
|
2026-08-18 22:52:46 +02:00
|
|
|
p[i] = p0;
|
|
|
|
|
q[i] = q0;
|
|
|
|
|
r[i] = r0;
|
|
|
|
|
s[i] = s0;
|
|
|
|
|
t[i] = t0;
|
|
|
|
|
u[i] = u0;
|
2013-12-28 09:10:00 +01:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Recover failure of one data block at index id[0] using parity at index
|
|
|
|
|
* ip[0] for any RAID level.
|
|
|
|
|
*
|
|
|
|
|
* Starting from the equation:
|
|
|
|
|
*
|
|
|
|
|
* Pd = A[ip[0],id[0]] * Dx
|
|
|
|
|
*
|
|
|
|
|
* and solving we get:
|
|
|
|
|
*
|
|
|
|
|
* Dx = A[ip[0],id[0]]^-1 * Pd
|
|
|
|
|
*/
|
2014-01-03 10:36:21 +01:00
|
|
|
void raid_rec1_int8(int nr, int *id, int *ip, int nd, size_t size, void **vv)
|
2013-12-28 09:10:00 +01:00
|
|
|
{
|
2015-03-12 18:53:36 +01:00
|
|
|
uint8_t **v = (uint8_t **)vv;
|
2013-12-28 12:04:16 +01:00
|
|
|
uint8_t *p;
|
|
|
|
|
uint8_t *pa;
|
|
|
|
|
const uint8_t *T;
|
2013-12-28 09:10:00 +01:00
|
|
|
uint8_t G;
|
|
|
|
|
uint8_t V;
|
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
|
|
(void)nr; /* unused, it's always 1 */
|
|
|
|
|
|
2026-04-15 10:47:29 +02:00
|
|
|
/* if it's RAID5, use the faster function */
|
2013-12-28 09:10:00 +01:00
|
|
|
if (ip[0] == 0) {
|
2014-01-08 17:07:13 +01:00
|
|
|
raid_rec1of1(id, nd, size, vv);
|
2013-12-28 09:10:00 +01:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* setup the coefficients matrix */
|
2013-12-28 12:04:16 +01:00
|
|
|
G = A(ip[0], id[0]);
|
2013-12-28 09:10:00 +01:00
|
|
|
|
|
|
|
|
/* invert it to solve the system of linear equations */
|
|
|
|
|
V = inv(G);
|
|
|
|
|
|
|
|
|
|
/* get multiplication tables */
|
|
|
|
|
T = table(V);
|
|
|
|
|
|
|
|
|
|
/* compute delta parity */
|
|
|
|
|
raid_delta_gen(1, id, ip, nd, size, vv);
|
|
|
|
|
|
2014-11-12 20:41:00 +01:00
|
|
|
p = v[nd + ip[0]];
|
2013-12-28 09:10:00 +01:00
|
|
|
pa = v[id[0]];
|
|
|
|
|
|
2013-12-28 12:04:16 +01:00
|
|
|
for (i = 0; i < size; ++i) {
|
2013-12-28 09:10:00 +01:00
|
|
|
/* delta */
|
|
|
|
|
uint8_t Pd = p[i] ^ pa[i];
|
|
|
|
|
|
|
|
|
|
/* reconstruct */
|
|
|
|
|
pa[i] = T[Pd];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Recover failure of two data blocks at indexes id[0],id[1] using parity at
|
|
|
|
|
* indexes ip[0],ip[1] for any RAID level.
|
|
|
|
|
*
|
|
|
|
|
* Starting from the equations:
|
|
|
|
|
*
|
|
|
|
|
* Pd = A[ip[0],id[0]] * Dx + A[ip[0],id[1]] * Dy
|
|
|
|
|
* Qd = A[ip[1],id[0]] * Dx + A[ip[1],id[1]] * Dy
|
|
|
|
|
*
|
|
|
|
|
* we solve inverting the coefficients matrix.
|
|
|
|
|
*/
|
2014-01-03 10:36:21 +01:00
|
|
|
void raid_rec2_int8(int nr, int *id, int *ip, int nd, size_t size, void **vv)
|
2013-12-28 09:10:00 +01:00
|
|
|
{
|
2015-03-12 18:53:36 +01:00
|
|
|
uint8_t **v = (uint8_t **)vv;
|
2013-12-28 12:04:16 +01:00
|
|
|
uint8_t *p;
|
|
|
|
|
uint8_t *pa;
|
|
|
|
|
uint8_t *q;
|
|
|
|
|
uint8_t *qa;
|
2013-12-28 09:10:00 +01:00
|
|
|
const int N = 2;
|
2026-06-23 12:16:38 +02:00
|
|
|
const uint8_t *T[2][2];
|
|
|
|
|
uint8_t G[2 * 2];
|
|
|
|
|
uint8_t V[2 * 2];
|
2013-12-28 09:10:00 +01:00
|
|
|
size_t i;
|
|
|
|
|
int j, k;
|
|
|
|
|
|
|
|
|
|
(void)nr; /* unused, it's always 2 */
|
|
|
|
|
|
2026-04-15 10:47:29 +02:00
|
|
|
/* if it's RAID6, recovering with P and Q uses the faster function */
|
2013-12-28 09:10:00 +01:00
|
|
|
if (ip[0] == 0 && ip[1] == 1) {
|
2014-01-08 17:07:13 +01:00
|
|
|
raid_rec2of2_int8(id, ip, nd, size, vv);
|
2013-12-28 09:10:00 +01:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* setup the coefficients matrix */
|
2013-12-28 12:04:16 +01:00
|
|
|
for (j = 0; j < N; ++j)
|
|
|
|
|
for (k = 0; k < N; ++k)
|
2014-11-12 20:41:00 +01:00
|
|
|
G[j * N + k] = A(ip[j], id[k]);
|
2013-12-28 09:10:00 +01:00
|
|
|
|
|
|
|
|
/* invert it to solve the system of linear equations */
|
|
|
|
|
raid_invert(G, V, N);
|
|
|
|
|
|
|
|
|
|
/* get multiplication tables */
|
2013-12-28 12:04:16 +01:00
|
|
|
for (j = 0; j < N; ++j)
|
|
|
|
|
for (k = 0; k < N; ++k)
|
2014-11-12 20:41:00 +01:00
|
|
|
T[j][k] = table(V[j * N + k]);
|
2013-12-28 09:10:00 +01:00
|
|
|
|
|
|
|
|
/* compute delta parity */
|
|
|
|
|
raid_delta_gen(2, id, ip, nd, size, vv);
|
|
|
|
|
|
2014-11-12 20:41:00 +01:00
|
|
|
p = v[nd + ip[0]];
|
|
|
|
|
q = v[nd + ip[1]];
|
2013-12-28 09:10:00 +01:00
|
|
|
pa = v[id[0]];
|
|
|
|
|
qa = v[id[1]];
|
|
|
|
|
|
2013-12-28 12:04:16 +01:00
|
|
|
for (i = 0; i < size; ++i) {
|
2013-12-28 09:10:00 +01:00
|
|
|
/* delta */
|
|
|
|
|
uint8_t Pd = p[i] ^ pa[i];
|
|
|
|
|
uint8_t Qd = q[i] ^ qa[i];
|
|
|
|
|
|
|
|
|
|
/* reconstruct */
|
|
|
|
|
pa[i] = T[0][0][Pd] ^ T[0][1][Qd];
|
|
|
|
|
qa[i] = T[1][0][Pd] ^ T[1][1][Qd];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Recover failure of N data blocks at indexes id[N] using parity at indexes
|
|
|
|
|
* ip[N] for any RAID level.
|
|
|
|
|
*
|
|
|
|
|
* Starting from the N equations, with 0<=i<N :
|
|
|
|
|
*
|
|
|
|
|
* PD[i] = sum(A[ip[i],id[j]] * D[i]) 0<=j<N
|
|
|
|
|
*
|
|
|
|
|
* we solve inverting the coefficients matrix.
|
|
|
|
|
*
|
2026-04-15 10:47:29 +02:00
|
|
|
* Note that referring to previous equations you have:
|
2013-12-28 09:10:00 +01:00
|
|
|
* PD[0] = Pd, PD[1] = Qd, PD[2] = Rd, ...
|
|
|
|
|
* D[0] = Dx, D[1] = Dy, D[2] = Dz, ...
|
|
|
|
|
*/
|
2014-01-03 10:36:21 +01:00
|
|
|
void raid_recX_int8(int nr, int *id, int *ip, int nd, size_t size, void **vv)
|
2013-12-28 09:10:00 +01:00
|
|
|
{
|
2015-03-12 18:53:36 +01:00
|
|
|
uint8_t **v = (uint8_t **)vv;
|
2013-12-28 12:04:16 +01:00
|
|
|
uint8_t *p[RAID_PARITY_MAX];
|
|
|
|
|
uint8_t *pa[RAID_PARITY_MAX];
|
|
|
|
|
const uint8_t *T[RAID_PARITY_MAX][RAID_PARITY_MAX];
|
2014-11-12 20:41:00 +01:00
|
|
|
uint8_t G[RAID_PARITY_MAX * RAID_PARITY_MAX];
|
|
|
|
|
uint8_t V[RAID_PARITY_MAX * RAID_PARITY_MAX];
|
2013-12-28 09:10:00 +01:00
|
|
|
size_t i;
|
|
|
|
|
int j, k;
|
|
|
|
|
|
|
|
|
|
/* setup the coefficients matrix */
|
2013-12-28 12:04:16 +01:00
|
|
|
for (j = 0; j < nr; ++j)
|
|
|
|
|
for (k = 0; k < nr; ++k)
|
2014-11-12 20:41:00 +01:00
|
|
|
G[j * nr + k] = A(ip[j], id[k]);
|
2013-12-28 09:10:00 +01:00
|
|
|
|
|
|
|
|
/* invert it to solve the system of linear equations */
|
|
|
|
|
raid_invert(G, V, nr);
|
|
|
|
|
|
|
|
|
|
/* get multiplication tables */
|
2013-12-28 12:04:16 +01:00
|
|
|
for (j = 0; j < nr; ++j)
|
|
|
|
|
for (k = 0; k < nr; ++k)
|
2014-11-12 20:41:00 +01:00
|
|
|
T[j][k] = table(V[j * nr + k]);
|
2013-12-28 09:10:00 +01:00
|
|
|
|
|
|
|
|
/* compute delta parity */
|
|
|
|
|
raid_delta_gen(nr, id, ip, nd, size, vv);
|
|
|
|
|
|
2013-12-28 12:04:16 +01:00
|
|
|
for (j = 0; j < nr; ++j) {
|
2014-11-12 20:41:00 +01:00
|
|
|
p[j] = v[nd + ip[j]];
|
2013-12-28 09:10:00 +01:00
|
|
|
pa[j] = v[id[j]];
|
|
|
|
|
}
|
|
|
|
|
|
2013-12-28 12:04:16 +01:00
|
|
|
for (i = 0; i < size; ++i) {
|
2013-12-28 09:10:00 +01:00
|
|
|
uint8_t PD[RAID_PARITY_MAX];
|
|
|
|
|
|
|
|
|
|
/* delta */
|
2013-12-28 12:04:16 +01:00
|
|
|
for (j = 0; j < nr; ++j)
|
2013-12-28 09:10:00 +01:00
|
|
|
PD[j] = p[j][i] ^ pa[j][i];
|
|
|
|
|
|
|
|
|
|
/* reconstruct */
|
2013-12-28 12:04:16 +01:00
|
|
|
for (j = 0; j < nr; ++j) {
|
2013-12-28 09:10:00 +01:00
|
|
|
uint8_t b = 0;
|
2015-03-12 18:53:36 +01:00
|
|
|
|
2013-12-28 12:04:16 +01:00
|
|
|
for (k = 0; k < nr; ++k)
|
2013-12-28 09:10:00 +01:00
|
|
|
b ^= T[j][k][PD[k]];
|
|
|
|
|
pa[j][i] = b;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-11 18:26:55 +02:00
|
|
|
void raid_register_int(void)
|
|
|
|
|
{
|
2026-08-19 01:36:18 +02:00
|
|
|
raid_gen_register(RAID_ALGO_CAUCHY_PAR2, "int8", raid_gen2_int8, RAID_POLY_ANY);
|
|
|
|
|
raid_gen_register(RAID_ALGO_CAUCHY_PAR3, "int8", raid_gen3_int8, RAID_POLY_ANY);
|
|
|
|
|
raid_gen_register(RAID_ALGO_CAUCHY_PAR4, "int8", raid_gen4_int8, RAID_POLY_ANY);
|
|
|
|
|
raid_gen_register(RAID_ALGO_CAUCHY_PAR5, "int8", raid_gen5_int8, RAID_POLY_ANY);
|
|
|
|
|
raid_gen_register(RAID_ALGO_CAUCHY_PAR6, "int8", raid_gen6_int8, RAID_POLY_ANY);
|
|
|
|
|
|
2026-04-11 18:26:55 +02:00
|
|
|
if (sizeof(void *) == 4) {
|
2026-07-29 12:47:13 +02:00
|
|
|
raid_gen_register(RAID_ALGO_CAUCHY_PAR1, "int32", raid_gen1_int32, RAID_POLY_ANY);
|
2026-08-19 01:36:18 +02:00
|
|
|
raid_gen_register(RAID_ALGO_CAUCHY_PAR2, "int32", raid_gen2_int32_raid, RAID_POLY_RAID);
|
|
|
|
|
raid_gen_register(RAID_ALGO_CAUCHY_PAR2, "int32", raid_gen2_int32_aes, RAID_POLY_AES);
|
|
|
|
|
raid_gen_register(RAID_ALGO_VANDERMONDE_PAR3, "int32", raid_genz_int32_raid, RAID_POLY_RAID);
|
2026-04-11 18:26:55 +02:00
|
|
|
} else {
|
2026-07-29 12:47:13 +02:00
|
|
|
raid_gen_register(RAID_ALGO_CAUCHY_PAR1, "int64", raid_gen1_int64, RAID_POLY_ANY);
|
2026-08-19 01:36:18 +02:00
|
|
|
raid_gen_register(RAID_ALGO_CAUCHY_PAR2, "int64", raid_gen2_int64_raid, RAID_POLY_RAID);
|
|
|
|
|
raid_gen_register(RAID_ALGO_CAUCHY_PAR2, "int64", raid_gen2_int64_aes, RAID_POLY_AES);
|
|
|
|
|
raid_gen_register(RAID_ALGO_VANDERMONDE_PAR3, "int64", raid_genz_int64_raid, RAID_POLY_RAID);
|
2026-04-11 18:26:55 +02:00
|
|
|
}
|
2026-07-29 12:47:13 +02:00
|
|
|
|
|
|
|
|
raid_rec_register(RAID_ALGO_CAUCHY_PAR1, "int8", raid_rec1_int8, RAID_POLY_ANY);
|
|
|
|
|
raid_rec_register(RAID_ALGO_CAUCHY_PAR2, "int8", raid_rec2_int8, RAID_POLY_ANY);
|
|
|
|
|
raid_rec_register(RAID_ALGO_CAUCHY_PAR3, "int8", raid_recX_int8, RAID_POLY_ANY);
|
|
|
|
|
raid_rec_register(RAID_ALGO_CAUCHY_PAR4, "int8", raid_recX_int8, RAID_POLY_ANY);
|
|
|
|
|
raid_rec_register(RAID_ALGO_CAUCHY_PAR5, "int8", raid_recX_int8, RAID_POLY_ANY);
|
|
|
|
|
raid_rec_register(RAID_ALGO_CAUCHY_PAR6, "int8", raid_recX_int8, RAID_POLY_ANY);
|
2026-04-11 18:26:55 +02:00
|
|
|
}
|