1e86372a0SGvozden Neskovic /*
2e86372a0SGvozden Neskovic * CDDL HEADER START
3e86372a0SGvozden Neskovic *
4e86372a0SGvozden Neskovic * The contents of this file are subject to the terms of the
5e86372a0SGvozden Neskovic * Common Development and Distribution License (the "License").
6e86372a0SGvozden Neskovic * You may not use this file except in compliance with the License.
7e86372a0SGvozden Neskovic *
8e86372a0SGvozden Neskovic * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9e86372a0SGvozden Neskovic * or http://www.opensolaris.org/os/licensing.
10e86372a0SGvozden Neskovic * See the License for the specific language governing permissions
11e86372a0SGvozden Neskovic * and limitations under the License.
12e86372a0SGvozden Neskovic *
13e86372a0SGvozden Neskovic * When distributing Covered Code, include this CDDL HEADER in each
14e86372a0SGvozden Neskovic * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15e86372a0SGvozden Neskovic * If applicable, add the following below this CDDL HEADER, with the
16e86372a0SGvozden Neskovic * fields enclosed by brackets "[]" replaced with your own identifying
17e86372a0SGvozden Neskovic * information: Portions Copyright [yyyy] [name of copyright owner]
18e86372a0SGvozden Neskovic *
19e86372a0SGvozden Neskovic * CDDL HEADER END
20e86372a0SGvozden Neskovic */
21e86372a0SGvozden Neskovic /*
22e86372a0SGvozden Neskovic * Copyright (C) 2016 Gvozden Nešković. All rights reserved.
23e86372a0SGvozden Neskovic */
24e86372a0SGvozden Neskovic
25e86372a0SGvozden Neskovic #ifndef _VDEV_RAIDZ_H
26e86372a0SGvozden Neskovic #define _VDEV_RAIDZ_H
27e86372a0SGvozden Neskovic
28e86372a0SGvozden Neskovic #include <sys/types.h>
29e86372a0SGvozden Neskovic #include <sys/debug.h>
30e86372a0SGvozden Neskovic #include <sys/kstat.h>
31e86372a0SGvozden Neskovic #include <sys/abd.h>
32e86372a0SGvozden Neskovic
33e86372a0SGvozden Neskovic #ifdef __cplusplus
34e86372a0SGvozden Neskovic extern "C" {
35e86372a0SGvozden Neskovic #endif
36e86372a0SGvozden Neskovic
37e86372a0SGvozden Neskovic #define CODE_P (0U)
38e86372a0SGvozden Neskovic #define CODE_Q (1U)
39e86372a0SGvozden Neskovic #define CODE_R (2U)
40e86372a0SGvozden Neskovic
41e86372a0SGvozden Neskovic #define PARITY_P (1U)
42e86372a0SGvozden Neskovic #define PARITY_PQ (2U)
43e86372a0SGvozden Neskovic #define PARITY_PQR (3U)
44e86372a0SGvozden Neskovic
45e86372a0SGvozden Neskovic #define TARGET_X (0U)
46e86372a0SGvozden Neskovic #define TARGET_Y (1U)
47e86372a0SGvozden Neskovic #define TARGET_Z (2U)
48e86372a0SGvozden Neskovic
49e86372a0SGvozden Neskovic /*
50e86372a0SGvozden Neskovic * Parity generation methods indexes
51e86372a0SGvozden Neskovic */
52e86372a0SGvozden Neskovic enum raidz_math_gen_op {
53e86372a0SGvozden Neskovic RAIDZ_GEN_P = 0,
54e86372a0SGvozden Neskovic RAIDZ_GEN_PQ,
55e86372a0SGvozden Neskovic RAIDZ_GEN_PQR,
56e86372a0SGvozden Neskovic RAIDZ_GEN_NUM = 3
57e86372a0SGvozden Neskovic };
58e86372a0SGvozden Neskovic /*
59e86372a0SGvozden Neskovic * Data reconstruction methods indexes
60e86372a0SGvozden Neskovic */
61e86372a0SGvozden Neskovic enum raidz_rec_op {
62e86372a0SGvozden Neskovic RAIDZ_REC_P = 0,
63e86372a0SGvozden Neskovic RAIDZ_REC_Q,
64e86372a0SGvozden Neskovic RAIDZ_REC_R,
65e86372a0SGvozden Neskovic RAIDZ_REC_PQ,
66e86372a0SGvozden Neskovic RAIDZ_REC_PR,
67e86372a0SGvozden Neskovic RAIDZ_REC_QR,
68e86372a0SGvozden Neskovic RAIDZ_REC_PQR,
69e86372a0SGvozden Neskovic RAIDZ_REC_NUM = 7
70e86372a0SGvozden Neskovic };
71e86372a0SGvozden Neskovic
72e86372a0SGvozden Neskovic extern const char *raidz_gen_name[RAIDZ_GEN_NUM];
73e86372a0SGvozden Neskovic extern const char *raidz_rec_name[RAIDZ_REC_NUM];
74e86372a0SGvozden Neskovic
75e86372a0SGvozden Neskovic /*
76e86372a0SGvozden Neskovic * Methods used to define raidz implementation
77e86372a0SGvozden Neskovic *
78e86372a0SGvozden Neskovic * @raidz_gen_f Parity generation function
79e86372a0SGvozden Neskovic * @par1 pointer to raidz_map
80e86372a0SGvozden Neskovic * @raidz_rec_f Data reconstruction function
81e86372a0SGvozden Neskovic * @par1 pointer to raidz_map
82e86372a0SGvozden Neskovic * @par2 array of reconstruction targets
83e86372a0SGvozden Neskovic * @will_work_f Function returns TRUE if impl. is supported on the system
84e86372a0SGvozden Neskovic * @init_impl_f Function is called once on init
85e86372a0SGvozden Neskovic * @fini_impl_f Function is called once on fini
86e86372a0SGvozden Neskovic */
87e86372a0SGvozden Neskovic typedef void (*raidz_gen_f)(void *);
88e86372a0SGvozden Neskovic typedef int (*raidz_rec_f)(void *, const int *);
89e86372a0SGvozden Neskovic typedef boolean_t (*will_work_f)(void);
90e86372a0SGvozden Neskovic typedef void (*init_impl_f)(void);
91e86372a0SGvozden Neskovic typedef void (*fini_impl_f)(void);
92e86372a0SGvozden Neskovic
93e86372a0SGvozden Neskovic #define RAIDZ_IMPL_NAME_MAX (20)
94e86372a0SGvozden Neskovic
95e86372a0SGvozden Neskovic typedef struct raidz_impl_ops {
96e86372a0SGvozden Neskovic init_impl_f init;
97e86372a0SGvozden Neskovic fini_impl_f fini;
98e86372a0SGvozden Neskovic raidz_gen_f gen[RAIDZ_GEN_NUM]; /* Parity generate functions */
99e86372a0SGvozden Neskovic raidz_rec_f rec[RAIDZ_REC_NUM]; /* Data reconstruction functions */
100e86372a0SGvozden Neskovic will_work_f is_supported; /* Support check function */
101e86372a0SGvozden Neskovic char name[RAIDZ_IMPL_NAME_MAX]; /* Name of the implementation */
102e86372a0SGvozden Neskovic } raidz_impl_ops_t;
103e86372a0SGvozden Neskovic
104e86372a0SGvozden Neskovic typedef struct raidz_col {
105e86372a0SGvozden Neskovic size_t rc_devidx; /* child device index for I/O */
106e86372a0SGvozden Neskovic size_t rc_offset; /* device offset */
107e86372a0SGvozden Neskovic size_t rc_size; /* I/O size */
108e86372a0SGvozden Neskovic abd_t *rc_abd; /* I/O data */
109e86372a0SGvozden Neskovic void *rc_gdata; /* used to store the "good" version */
110e86372a0SGvozden Neskovic int rc_error; /* I/O error for this device */
111e86372a0SGvozden Neskovic unsigned int rc_tried; /* Did we attempt this I/O column? */
112e86372a0SGvozden Neskovic unsigned int rc_skipped; /* Did we skip this I/O column? */
113e86372a0SGvozden Neskovic } raidz_col_t;
114e86372a0SGvozden Neskovic
115e86372a0SGvozden Neskovic typedef struct raidz_map {
116e86372a0SGvozden Neskovic size_t rm_cols; /* Regular column count */
117e86372a0SGvozden Neskovic size_t rm_scols; /* Count including skipped columns */
118e86372a0SGvozden Neskovic size_t rm_bigcols; /* Number of oversized columns */
119e86372a0SGvozden Neskovic size_t rm_asize; /* Actual total I/O size */
120e86372a0SGvozden Neskovic size_t rm_missingdata; /* Count of missing data devices */
121e86372a0SGvozden Neskovic size_t rm_missingparity; /* Count of missing parity devices */
122e86372a0SGvozden Neskovic size_t rm_firstdatacol; /* First data column/parity count */
123e86372a0SGvozden Neskovic size_t rm_nskip; /* Skipped sectors for padding */
124e86372a0SGvozden Neskovic size_t rm_skipstart; /* Column index of padding start */
125e86372a0SGvozden Neskovic void *rm_abd_copy; /* rm_asize-buffer of copied data */
126e86372a0SGvozden Neskovic size_t rm_reports; /* # of referencing checksum reports */
127e86372a0SGvozden Neskovic unsigned int rm_freed; /* map no longer has referencing ZIO */
128e86372a0SGvozden Neskovic unsigned int rm_ecksuminjected; /* checksum error was injected */
129e86372a0SGvozden Neskovic const raidz_impl_ops_t *rm_ops; /* RAIDZ math operations */
130e86372a0SGvozden Neskovic raidz_col_t rm_col[1]; /* Flexible array of I/O columns */
131e86372a0SGvozden Neskovic } raidz_map_t;
132e86372a0SGvozden Neskovic
133e86372a0SGvozden Neskovic #define RAIDZ_ORIGINAL_IMPL (INT_MAX)
134e86372a0SGvozden Neskovic
135e86372a0SGvozden Neskovic extern const raidz_impl_ops_t vdev_raidz_scalar_impl;
136*f91a4547SGvozden Neskovic #if defined(__x86)
137*f91a4547SGvozden Neskovic extern const raidz_impl_ops_t vdev_raidz_sse2_impl;
138*f91a4547SGvozden Neskovic #endif
139*f91a4547SGvozden Neskovic #if defined(__x86)
140*f91a4547SGvozden Neskovic extern const raidz_impl_ops_t vdev_raidz_ssse3_impl;
141*f91a4547SGvozden Neskovic #endif
142*f91a4547SGvozden Neskovic #if defined(__x86)
143*f91a4547SGvozden Neskovic extern const raidz_impl_ops_t vdev_raidz_avx2_impl;
144*f91a4547SGvozden Neskovic #endif
145e86372a0SGvozden Neskovic
146e86372a0SGvozden Neskovic /*
147e86372a0SGvozden Neskovic * Commonly used raidz_map helpers
148e86372a0SGvozden Neskovic *
149e86372a0SGvozden Neskovic * raidz_parity Returns parity of the RAIDZ block
150e86372a0SGvozden Neskovic * raidz_ncols Returns number of columns the block spans
151*f91a4547SGvozden Neskovic * raidz_nbigcols Returns number of big columns
152e86372a0SGvozden Neskovic * raidz_col_p Returns pointer to a column
153e86372a0SGvozden Neskovic * raidz_col_size Returns size of a column
154e86372a0SGvozden Neskovic * raidz_big_size Returns size of big columns
155e86372a0SGvozden Neskovic * raidz_short_size Returns size of short columns
156e86372a0SGvozden Neskovic */
157e86372a0SGvozden Neskovic #define raidz_parity(rm) ((rm)->rm_firstdatacol)
158e86372a0SGvozden Neskovic #define raidz_ncols(rm) ((rm)->rm_cols)
159e86372a0SGvozden Neskovic #define raidz_nbigcols(rm) ((rm)->rm_bigcols)
160e86372a0SGvozden Neskovic #define raidz_col_p(rm, c) ((rm)->rm_col + (c))
161e86372a0SGvozden Neskovic #define raidz_col_size(rm, c) ((rm)->rm_col[c].rc_size)
162e86372a0SGvozden Neskovic #define raidz_big_size(rm) (raidz_col_size(rm, CODE_P))
163e86372a0SGvozden Neskovic #define raidz_short_size(rm) (raidz_col_size(rm, raidz_ncols(rm)-1))
164e86372a0SGvozden Neskovic
165e86372a0SGvozden Neskovic /*
166e86372a0SGvozden Neskovic * Macro defines an RAIDZ parity generation method
167e86372a0SGvozden Neskovic *
168e86372a0SGvozden Neskovic * @code parity the function produce
169e86372a0SGvozden Neskovic * @impl name of the implementation
170e86372a0SGvozden Neskovic */
171e86372a0SGvozden Neskovic #define _RAIDZ_GEN_WRAP(code, impl) \
172e86372a0SGvozden Neskovic static void \
173e86372a0SGvozden Neskovic impl ## _gen_ ## code(void *rmp) \
174e86372a0SGvozden Neskovic { \
175e86372a0SGvozden Neskovic raidz_map_t *rm = (raidz_map_t *) rmp; \
176e86372a0SGvozden Neskovic raidz_generate_## code ## _impl(rm); \
177e86372a0SGvozden Neskovic }
178e86372a0SGvozden Neskovic
179e86372a0SGvozden Neskovic /*
180e86372a0SGvozden Neskovic * Macro defines an RAIDZ data reconstruction method
181e86372a0SGvozden Neskovic *
182e86372a0SGvozden Neskovic * @code parity the function produce
183e86372a0SGvozden Neskovic * @impl name of the implementation
184e86372a0SGvozden Neskovic */
185e86372a0SGvozden Neskovic #define _RAIDZ_REC_WRAP(code, impl) \
186e86372a0SGvozden Neskovic static int \
187e86372a0SGvozden Neskovic impl ## _rec_ ## code(void *rmp, const int *tgtidx) \
188e86372a0SGvozden Neskovic { \
189e86372a0SGvozden Neskovic raidz_map_t *rm = (raidz_map_t *) rmp; \
190e86372a0SGvozden Neskovic return (raidz_reconstruct_## code ## _impl(rm, tgtidx)); \
191e86372a0SGvozden Neskovic }
192e86372a0SGvozden Neskovic
193e86372a0SGvozden Neskovic /*
194e86372a0SGvozden Neskovic * Define all gen methods for an implementation
195e86372a0SGvozden Neskovic *
196e86372a0SGvozden Neskovic * @impl name of the implementation
197e86372a0SGvozden Neskovic */
198e86372a0SGvozden Neskovic #define DEFINE_GEN_METHODS(impl) \
199e86372a0SGvozden Neskovic _RAIDZ_GEN_WRAP(p, impl); \
200e86372a0SGvozden Neskovic _RAIDZ_GEN_WRAP(pq, impl); \
201e86372a0SGvozden Neskovic _RAIDZ_GEN_WRAP(pqr, impl)
202e86372a0SGvozden Neskovic
203e86372a0SGvozden Neskovic /*
204e86372a0SGvozden Neskovic * Define all rec functions for an implementation
205e86372a0SGvozden Neskovic *
206e86372a0SGvozden Neskovic * @impl name of the implementation
207e86372a0SGvozden Neskovic */
208e86372a0SGvozden Neskovic #define DEFINE_REC_METHODS(impl) \
209e86372a0SGvozden Neskovic _RAIDZ_REC_WRAP(p, impl); \
210e86372a0SGvozden Neskovic _RAIDZ_REC_WRAP(q, impl); \
211e86372a0SGvozden Neskovic _RAIDZ_REC_WRAP(r, impl); \
212e86372a0SGvozden Neskovic _RAIDZ_REC_WRAP(pq, impl); \
213e86372a0SGvozden Neskovic _RAIDZ_REC_WRAP(pr, impl); \
214e86372a0SGvozden Neskovic _RAIDZ_REC_WRAP(qr, impl); \
215e86372a0SGvozden Neskovic _RAIDZ_REC_WRAP(pqr, impl)
216e86372a0SGvozden Neskovic
217e86372a0SGvozden Neskovic #define RAIDZ_GEN_METHODS(impl) \
218e86372a0SGvozden Neskovic { \
219e86372a0SGvozden Neskovic [RAIDZ_GEN_P] = & impl ## _gen_p, \
220e86372a0SGvozden Neskovic [RAIDZ_GEN_PQ] = & impl ## _gen_pq, \
221e86372a0SGvozden Neskovic [RAIDZ_GEN_PQR] = & impl ## _gen_pqr \
222e86372a0SGvozden Neskovic }
223e86372a0SGvozden Neskovic
224e86372a0SGvozden Neskovic #define RAIDZ_REC_METHODS(impl) \
225e86372a0SGvozden Neskovic { \
226e86372a0SGvozden Neskovic [RAIDZ_REC_P] = & impl ## _rec_p, \
227e86372a0SGvozden Neskovic [RAIDZ_REC_Q] = & impl ## _rec_q, \
228e86372a0SGvozden Neskovic [RAIDZ_REC_R] = & impl ## _rec_r, \
229e86372a0SGvozden Neskovic [RAIDZ_REC_PQ] = & impl ## _rec_pq, \
230e86372a0SGvozden Neskovic [RAIDZ_REC_PR] = & impl ## _rec_pr, \
231e86372a0SGvozden Neskovic [RAIDZ_REC_QR] = & impl ## _rec_qr, \
232e86372a0SGvozden Neskovic [RAIDZ_REC_PQR] = & impl ## _rec_pqr \
233e86372a0SGvozden Neskovic }
234e86372a0SGvozden Neskovic
235e86372a0SGvozden Neskovic
236e86372a0SGvozden Neskovic typedef struct raidz_impl_kstat {
237*f91a4547SGvozden Neskovic uint64_t gen[RAIDZ_GEN_NUM]; /* gen method speed B/s */
238*f91a4547SGvozden Neskovic uint64_t rec[RAIDZ_REC_NUM]; /* rec method speed B/s */
239e86372a0SGvozden Neskovic } raidz_impl_kstat_t;
240e86372a0SGvozden Neskovic
241e86372a0SGvozden Neskovic /*
242e86372a0SGvozden Neskovic * Enumerate various multiplication constants
243e86372a0SGvozden Neskovic * used in reconstruction methods
244e86372a0SGvozden Neskovic */
245e86372a0SGvozden Neskovic typedef enum raidz_mul_info {
246e86372a0SGvozden Neskovic /* Reconstruct Q */
247e86372a0SGvozden Neskovic MUL_Q_X = 0,
248e86372a0SGvozden Neskovic /* Reconstruct R */
249e86372a0SGvozden Neskovic MUL_R_X = 0,
250e86372a0SGvozden Neskovic /* Reconstruct PQ */
251e86372a0SGvozden Neskovic MUL_PQ_X = 0,
252e86372a0SGvozden Neskovic MUL_PQ_Y = 1,
253e86372a0SGvozden Neskovic /* Reconstruct PR */
254e86372a0SGvozden Neskovic MUL_PR_X = 0,
255e86372a0SGvozden Neskovic MUL_PR_Y = 1,
256e86372a0SGvozden Neskovic /* Reconstruct QR */
257e86372a0SGvozden Neskovic MUL_QR_XQ = 0,
258e86372a0SGvozden Neskovic MUL_QR_X = 1,
259e86372a0SGvozden Neskovic MUL_QR_YQ = 2,
260e86372a0SGvozden Neskovic MUL_QR_Y = 3,
261e86372a0SGvozden Neskovic /* Reconstruct PQR */
262e86372a0SGvozden Neskovic MUL_PQR_XP = 0,
263e86372a0SGvozden Neskovic MUL_PQR_XQ = 1,
264e86372a0SGvozden Neskovic MUL_PQR_XR = 2,
265e86372a0SGvozden Neskovic MUL_PQR_YU = 3,
266e86372a0SGvozden Neskovic MUL_PQR_YP = 4,
267e86372a0SGvozden Neskovic MUL_PQR_YQ = 5,
268e86372a0SGvozden Neskovic
269e86372a0SGvozden Neskovic MUL_CNT = 6
270e86372a0SGvozden Neskovic } raidz_mul_info_t;
271e86372a0SGvozden Neskovic
272e86372a0SGvozden Neskovic /*
273e86372a0SGvozden Neskovic * Powers of 2 in the Galois field.
274e86372a0SGvozden Neskovic */
275e86372a0SGvozden Neskovic extern const uint8_t vdev_raidz_pow2[256] __attribute__((aligned(256)));
276e86372a0SGvozden Neskovic /* Logs of 2 in the Galois field defined above. */
277e86372a0SGvozden Neskovic extern const uint8_t vdev_raidz_log2[256] __attribute__((aligned(256)));
278e86372a0SGvozden Neskovic
279e86372a0SGvozden Neskovic /*
280e86372a0SGvozden Neskovic * Multiply a given number by 2 raised to the given power.
281e86372a0SGvozden Neskovic */
282e86372a0SGvozden Neskovic static inline uint8_t
vdev_raidz_exp2(const uint8_t a,const unsigned exp)283e86372a0SGvozden Neskovic vdev_raidz_exp2(const uint8_t a, const unsigned exp)
284e86372a0SGvozden Neskovic {
285e86372a0SGvozden Neskovic if (a == 0)
286e86372a0SGvozden Neskovic return (0);
287e86372a0SGvozden Neskovic
288e86372a0SGvozden Neskovic return (vdev_raidz_pow2[(exp + (unsigned) vdev_raidz_log2[a]) % 255]);
289e86372a0SGvozden Neskovic }
290e86372a0SGvozden Neskovic
291e86372a0SGvozden Neskovic /*
292e86372a0SGvozden Neskovic * Galois Field operations.
293e86372a0SGvozden Neskovic *
294e86372a0SGvozden Neskovic * gf_exp2 - computes 2 raised to the given power
295e86372a0SGvozden Neskovic * gf_exp2 - computes 4 raised to the given power
296e86372a0SGvozden Neskovic * gf_mul - multiplication
297e86372a0SGvozden Neskovic * gf_div - division
298e86372a0SGvozden Neskovic * gf_inv - multiplicative inverse
299e86372a0SGvozden Neskovic */
300e86372a0SGvozden Neskovic typedef unsigned gf_t;
301e86372a0SGvozden Neskovic typedef unsigned gf_log_t;
302e86372a0SGvozden Neskovic
303e86372a0SGvozden Neskovic static inline gf_t
gf_mul(const gf_t a,const gf_t b)304e86372a0SGvozden Neskovic gf_mul(const gf_t a, const gf_t b)
305e86372a0SGvozden Neskovic {
306e86372a0SGvozden Neskovic gf_log_t logsum;
307e86372a0SGvozden Neskovic
308e86372a0SGvozden Neskovic if (a == 0 || b == 0)
309e86372a0SGvozden Neskovic return (0);
310e86372a0SGvozden Neskovic
311e86372a0SGvozden Neskovic logsum = (gf_log_t) vdev_raidz_log2[a] + (gf_log_t) vdev_raidz_log2[b];
312e86372a0SGvozden Neskovic
313e86372a0SGvozden Neskovic return ((gf_t) vdev_raidz_pow2[logsum % 255]);
314e86372a0SGvozden Neskovic }
315e86372a0SGvozden Neskovic
316e86372a0SGvozden Neskovic static inline gf_t
gf_div(const gf_t a,const gf_t b)317e86372a0SGvozden Neskovic gf_div(const gf_t a, const gf_t b)
318e86372a0SGvozden Neskovic {
319e86372a0SGvozden Neskovic gf_log_t logsum;
320e86372a0SGvozden Neskovic
321e86372a0SGvozden Neskovic ASSERT3U(b, >, 0);
322e86372a0SGvozden Neskovic if (a == 0)
323e86372a0SGvozden Neskovic return (0);
324e86372a0SGvozden Neskovic
325e86372a0SGvozden Neskovic logsum = (gf_log_t) 255 + (gf_log_t) vdev_raidz_log2[a] -
326e86372a0SGvozden Neskovic (gf_log_t) vdev_raidz_log2[b];
327e86372a0SGvozden Neskovic
328e86372a0SGvozden Neskovic return ((gf_t) vdev_raidz_pow2[logsum % 255]);
329e86372a0SGvozden Neskovic }
330e86372a0SGvozden Neskovic
331e86372a0SGvozden Neskovic static inline gf_t
gf_inv(const gf_t a)332e86372a0SGvozden Neskovic gf_inv(const gf_t a)
333e86372a0SGvozden Neskovic {
334e86372a0SGvozden Neskovic gf_log_t logsum;
335e86372a0SGvozden Neskovic
336e86372a0SGvozden Neskovic ASSERT3U(a, >, 0);
337e86372a0SGvozden Neskovic
338e86372a0SGvozden Neskovic logsum = (gf_log_t) 255 - (gf_log_t) vdev_raidz_log2[a];
339e86372a0SGvozden Neskovic
340e86372a0SGvozden Neskovic return ((gf_t) vdev_raidz_pow2[logsum]);
341e86372a0SGvozden Neskovic }
342e86372a0SGvozden Neskovic
343e86372a0SGvozden Neskovic static inline gf_t
gf_exp2(gf_log_t exp)344e86372a0SGvozden Neskovic gf_exp2(gf_log_t exp)
345e86372a0SGvozden Neskovic {
346e86372a0SGvozden Neskovic return (vdev_raidz_pow2[exp % 255]);
347e86372a0SGvozden Neskovic }
348e86372a0SGvozden Neskovic
349e86372a0SGvozden Neskovic static inline gf_t
gf_exp4(gf_log_t exp)350e86372a0SGvozden Neskovic gf_exp4(gf_log_t exp)
351e86372a0SGvozden Neskovic {
352e86372a0SGvozden Neskovic ASSERT3U(exp, <=, 255);
353e86372a0SGvozden Neskovic return ((gf_t) vdev_raidz_pow2[(2 * exp) % 255]);
354e86372a0SGvozden Neskovic }
355e86372a0SGvozden Neskovic
356e86372a0SGvozden Neskovic #ifdef __cplusplus
357e86372a0SGvozden Neskovic }
358e86372a0SGvozden Neskovic #endif
359e86372a0SGvozden Neskovic
360e86372a0SGvozden Neskovic #endif /* _VDEV_RAIDZ_H */
361