Use a power of generator representation of GF(256) multiplication group
to save space time and complexity. * grub-core/disk/raid6_recover.c (raid6_table1): Removed. (raid6_table2): Likewise. (powx): New array. (powx_inv): Likewise. (poly): New const. (grub_raid_block_mul): Replace with ... (grub_raid_block_mulx): ...this. (grub_raid6_init_table): Rewritten. (grub_raid6_recover): Use power of generator representation.
This commit is contained in:
parent
09e2763fb1
commit
11ee4389e2
2 changed files with 42 additions and 54 deletions
15
ChangeLog
15
ChangeLog
|
@ -1,3 +1,18 @@
|
||||||
|
2011-11-04 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
|
Use a power of generator representation of GF(256) multiplication group
|
||||||
|
to save space time and complexity.
|
||||||
|
|
||||||
|
* grub-core/disk/raid6_recover.c (raid6_table1): Removed.
|
||||||
|
(raid6_table2): Likewise.
|
||||||
|
(powx): New array.
|
||||||
|
(powx_inv): Likewise.
|
||||||
|
(poly): New const.
|
||||||
|
(grub_raid_block_mul): Replace with ...
|
||||||
|
(grub_raid_block_mulx): ...this.
|
||||||
|
(grub_raid6_init_table): Rewritten.
|
||||||
|
(grub_raid6_recover): Use power of generator representation.
|
||||||
|
|
||||||
2011-11-04 Vladimir Serbinenko <phcoder@gmail.com>
|
2011-11-04 Vladimir Serbinenko <phcoder@gmail.com>
|
||||||
|
|
||||||
* grub-core/disk/raid6_recover.c (grub_raid6_recover): Get start_sector
|
* grub-core/disk/raid6_recover.c (grub_raid6_recover): Get start_sector
|
||||||
|
|
|
@ -26,66 +26,39 @@
|
||||||
|
|
||||||
GRUB_MOD_LICENSE ("GPLv3+");
|
GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
static grub_uint8_t raid6_table1[256][256];
|
/* x**y. */
|
||||||
static grub_uint8_t raid6_table2[256][256];
|
static grub_uint8_t powx[255 * 2];
|
||||||
|
/* Such an s that x**s = y */
|
||||||
|
static int powx_inv[256];
|
||||||
|
static const grub_uint8_t poly = 0x1d;
|
||||||
|
|
||||||
static void
|
static void
|
||||||
grub_raid_block_mul (grub_uint8_t mul, char *buf, int size)
|
grub_raid_block_mulx (int mul, char *buf, int size)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
grub_uint8_t *p;
|
grub_uint8_t *p;
|
||||||
|
|
||||||
p = (grub_uint8_t *) buf;
|
p = (grub_uint8_t *) buf;
|
||||||
for (i = 0; i < size; i++, p++)
|
for (i = 0; i < size; i++, p++)
|
||||||
*p = raid6_table1[mul][*p];
|
if (*p)
|
||||||
|
*p = powx[mul + powx_inv[*p]];
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
grub_raid6_init_table (void)
|
grub_raid6_init_table (void)
|
||||||
{
|
{
|
||||||
int i, j;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < 256; i++)
|
grub_uint8_t cur = 1;
|
||||||
raid6_table1[i][1] = raid6_table1[1][i] = i;
|
for (i = 0; i < 255; i++)
|
||||||
|
|
||||||
for (i = 2; i < 256; i++)
|
|
||||||
for (j = i; j < 256; j++)
|
|
||||||
{
|
{
|
||||||
int n;
|
powx[i] = cur;
|
||||||
grub_uint8_t c;
|
powx[i + 255] = cur;
|
||||||
|
powx_inv[cur] = i;
|
||||||
n = i >> 1;
|
if (cur & 0x80)
|
||||||
|
cur = (cur << 1) ^ poly;
|
||||||
c = raid6_table1[n][j];
|
else
|
||||||
c = (c << 1) ^ ((c & 0x80) ? 0x1d : 0);
|
cur <<= 1;
|
||||||
if (i & 1)
|
|
||||||
c ^= j;
|
|
||||||
|
|
||||||
raid6_table1[j][i] = raid6_table1[i][j] = c;
|
|
||||||
}
|
|
||||||
|
|
||||||
raid6_table2[0][0] = 1;
|
|
||||||
for (i = 1; i < 256; i++)
|
|
||||||
raid6_table2[i][i] = raid6_table1[raid6_table2[i - 1][i - 1]][2];
|
|
||||||
|
|
||||||
for (i = 0; i < 254; i++)
|
|
||||||
for (j = 0; j < 254; j++)
|
|
||||||
{
|
|
||||||
grub_uint8_t c, n;
|
|
||||||
int k;
|
|
||||||
|
|
||||||
if (i == j)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
k = i - j;
|
|
||||||
if (k < 0)
|
|
||||||
k += 255;
|
|
||||||
|
|
||||||
c = n = raid6_table2[k][k] ^ 1;
|
|
||||||
for (k = 0; k < 253; k++)
|
|
||||||
c = raid6_table1[c][n];
|
|
||||||
|
|
||||||
raid6_table2[i][j] = raid6_table1[raid6_table2[255 - j][255 - j]][c];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,7 +99,7 @@ grub_raid6_recover (struct grub_raid_array *array, int disknr, int p,
|
||||||
0, size, buf)))
|
0, size, buf)))
|
||||||
{
|
{
|
||||||
grub_raid_block_xor (pbuf, buf, size);
|
grub_raid_block_xor (pbuf, buf, size);
|
||||||
grub_raid_block_mul (raid6_table2[i][i], buf, size);
|
grub_raid_block_mulx (i, buf, size);
|
||||||
grub_raid_block_xor (qbuf, buf, size);
|
grub_raid_block_xor (qbuf, buf, size);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -173,13 +146,13 @@ grub_raid6_recover (struct grub_raid_array *array, int disknr, int p,
|
||||||
goto quit;
|
goto quit;
|
||||||
|
|
||||||
grub_raid_block_xor (buf, qbuf, size);
|
grub_raid_block_xor (buf, qbuf, size);
|
||||||
grub_raid_block_mul (raid6_table2[255 - bad1][255 - bad1], buf,
|
grub_raid_block_mulx (255 - bad1, buf,
|
||||||
size);
|
size);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Two bad devices */
|
/* Two bad devices */
|
||||||
grub_uint8_t c;
|
int c;
|
||||||
|
|
||||||
if ((! array->members[p].device) || (! array->members[q].device))
|
if ((! array->members[p].device) || (! array->members[q].device))
|
||||||
{
|
{
|
||||||
|
@ -201,11 +174,11 @@ grub_raid6_recover (struct grub_raid_array *array, int disknr, int p,
|
||||||
|
|
||||||
grub_raid_block_xor (qbuf, buf, size);
|
grub_raid_block_xor (qbuf, buf, size);
|
||||||
|
|
||||||
c = raid6_table2[bad2][bad1];
|
c = (255 - bad1 + (255 - powx_inv[(powx[bad2 - bad1 + 255] ^ 1)])) % 255;
|
||||||
grub_raid_block_mul (c, qbuf, size);
|
grub_raid_block_mulx (c, qbuf, size);
|
||||||
|
|
||||||
c = raid6_table1[raid6_table2[bad2][bad2]][c];
|
c = (bad2 + c) % 255;
|
||||||
grub_raid_block_mul (c, pbuf, size);
|
grub_raid_block_mulx (c, pbuf, size);
|
||||||
|
|
||||||
grub_raid_block_xor (pbuf, qbuf, size);
|
grub_raid_block_xor (pbuf, qbuf, size);
|
||||||
grub_memcpy (buf, pbuf, size);
|
grub_memcpy (buf, pbuf, size);
|
||||||
|
|
Loading…
Reference in a new issue