summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/softraid_raid6.c29
1 files changed, 26 insertions, 3 deletions
diff --git a/sys/dev/softraid_raid6.c b/sys/dev/softraid_raid6.c
index 0b8a3146e5c..ea5a674eb52 100644
--- a/sys/dev/softraid_raid6.c
+++ b/sys/dev/softraid_raid6.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: softraid_raid6.c,v 1.5 2009/08/12 22:01:15 jordan Exp $ */
+/* $OpenBSD: softraid_raid6.c,v 1.6 2009/08/26 20:14:44 jordan Exp $ */
/*
* Copyright (c) 2009 Marco Peereboom <marco@peereboom.us>
* Copyright (c) 2009 Jordan Hargrave <jordan@openbsd.org>
@@ -44,6 +44,7 @@
#include <dev/softraidvar.h>
#include <dev/rndvar.h>
+uint8_t *gf_map[256];
uint8_t gf_pow[768];
int gf_log[256];
@@ -70,6 +71,7 @@ void sr_put_block(struct sr_discipline *, void *);
void gf_init(void);
uint8_t gf_inv(uint8_t);
+int gf_premul(uint8_t);
#define SR_NOFAIL 0x00
#define SR_FAILX (1L << 0)
@@ -608,6 +610,8 @@ sr_raid6_rw(struct sr_workunit *wu)
goto bad;
/* Calulate P = Dn; Q = gn * Dn */
+ if (gf_premul(gf_pow[chunk]))
+ goto bad;
sr_raid6_xorp(pbuf, data, length);
sr_raid6_xorq(qbuf, data, length, gf_pow[chunk]);
@@ -943,6 +947,9 @@ sr_raid6_addio(struct sr_workunit *wu, int dsk, daddr64_t blk, daddr64_t len,
ccb->ccb_wu = wu;
ccb->ccb_target = dsk;
if (pbuf || qbuf) {
+ if (qbuf && gf_premul(gn))
+ return (-1);
+
pqbuf = malloc(sizeof(struct sr_raid6_opaque), M_DEVBUF, M_CANFAIL);
if (pqbuf == NULL) {
sr_ccb_put(ccb);
@@ -983,12 +990,12 @@ void
sr_raid6_xorq(void *q, void *d, int len, int gn)
{
uint8_t *qbuf = q, *data = d;
- uint8_t *gn_pow = gf_pow + gf_log[gn];
+ uint8_t *gn_map = gf_map[gn];
/* Have to do this a byte at a time */
/* Faster multiply.. gn is always constant */
while (len--)
- qbuf[len] ^= gn_pow[gf_log[data[len]]];
+ qbuf[len] ^= gn_map[data[len]];
}
/* Create GF256 log/pow tables: polynomial = 0x11D */
@@ -1013,3 +1020,19 @@ gf_inv(uint8_t a)
return gf_pow[255 - gf_log[a]];
}
+/* Precalculate multiplication tables for drive gn */
+int
+gf_premul(uint8_t gn)
+{
+ int i;
+
+ if (gf_map[gn] != NULL)
+ return (0);
+
+ if ((gf_map[gn] = malloc(256, M_DEVBUF, M_CANFAIL)) == NULL)
+ return (-1);
+
+ for (i=0; i<256; i++)
+ gf_map[gn][i] = gf_pow[gf_log[i] + gf_log[gn]];
+ return (0);
+}