1eda14cbcSMatt Macy /* 2eda14cbcSMatt Macy * CDDL HEADER START 3eda14cbcSMatt Macy * 4eda14cbcSMatt Macy * The contents of this file are subject to the terms of the 5eda14cbcSMatt Macy * Common Development and Distribution License (the "License"). 6eda14cbcSMatt Macy * You may not use this file except in compliance with the License. 7eda14cbcSMatt Macy * 8eda14cbcSMatt Macy * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9271171e0SMartin Matuska * or https://opensource.org/licenses/CDDL-1.0. 10eda14cbcSMatt Macy * See the License for the specific language governing permissions 11eda14cbcSMatt Macy * and limitations under the License. 12eda14cbcSMatt Macy * 13eda14cbcSMatt Macy * When distributing Covered Code, include this CDDL HEADER in each 14eda14cbcSMatt Macy * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15eda14cbcSMatt Macy * If applicable, add the following below this CDDL HEADER, with the 16eda14cbcSMatt Macy * fields enclosed by brackets "[]" replaced with your own identifying 17eda14cbcSMatt Macy * information: Portions Copyright [yyyy] [name of copyright owner] 18eda14cbcSMatt Macy * 19eda14cbcSMatt Macy * CDDL HEADER END 20eda14cbcSMatt Macy */ 21eda14cbcSMatt Macy /* 22eda14cbcSMatt Macy * Copyright (C) 2016 Gvozden Nešković. All rights reserved. 23eda14cbcSMatt Macy */ 24eda14cbcSMatt Macy 25eda14cbcSMatt Macy #ifndef _VDEV_RAIDZ_H 26eda14cbcSMatt Macy #define _VDEV_RAIDZ_H 27eda14cbcSMatt Macy 28eda14cbcSMatt Macy #include <sys/types.h> 29eda14cbcSMatt Macy #include <sys/debug.h> 30eda14cbcSMatt Macy #include <sys/kstat.h> 31eda14cbcSMatt Macy #include <sys/abd.h> 327877fdebSMatt Macy #include <sys/vdev_impl.h> 33eda14cbcSMatt Macy 34eda14cbcSMatt Macy #ifdef __cplusplus 35eda14cbcSMatt Macy extern "C" { 36eda14cbcSMatt Macy #endif 37eda14cbcSMatt Macy 38eda14cbcSMatt Macy #define CODE_P (0U) 39eda14cbcSMatt Macy #define CODE_Q (1U) 40eda14cbcSMatt Macy #define CODE_R (2U) 41eda14cbcSMatt Macy 42eda14cbcSMatt Macy #define PARITY_P (1U) 43eda14cbcSMatt Macy #define PARITY_PQ (2U) 44eda14cbcSMatt Macy #define PARITY_PQR (3U) 45eda14cbcSMatt Macy 46eda14cbcSMatt Macy #define TARGET_X (0U) 47eda14cbcSMatt Macy #define TARGET_Y (1U) 48eda14cbcSMatt Macy #define TARGET_Z (2U) 49eda14cbcSMatt Macy 50eda14cbcSMatt Macy /* 51eda14cbcSMatt Macy * Parity generation methods indexes 52eda14cbcSMatt Macy */ 53eda14cbcSMatt Macy enum raidz_math_gen_op { 54eda14cbcSMatt Macy RAIDZ_GEN_P = 0, 55eda14cbcSMatt Macy RAIDZ_GEN_PQ, 56eda14cbcSMatt Macy RAIDZ_GEN_PQR, 57eda14cbcSMatt Macy RAIDZ_GEN_NUM = 3 58eda14cbcSMatt Macy }; 59eda14cbcSMatt Macy /* 60eda14cbcSMatt Macy * Data reconstruction methods indexes 61eda14cbcSMatt Macy */ 62eda14cbcSMatt Macy enum raidz_rec_op { 63eda14cbcSMatt Macy RAIDZ_REC_P = 0, 64eda14cbcSMatt Macy RAIDZ_REC_Q, 65eda14cbcSMatt Macy RAIDZ_REC_R, 66eda14cbcSMatt Macy RAIDZ_REC_PQ, 67eda14cbcSMatt Macy RAIDZ_REC_PR, 68eda14cbcSMatt Macy RAIDZ_REC_QR, 69eda14cbcSMatt Macy RAIDZ_REC_PQR, 70eda14cbcSMatt Macy RAIDZ_REC_NUM = 7 71eda14cbcSMatt Macy }; 72eda14cbcSMatt Macy 73e92ffd9bSMartin Matuska extern const char *const raidz_gen_name[RAIDZ_GEN_NUM]; 74e92ffd9bSMartin Matuska extern const char *const raidz_rec_name[RAIDZ_REC_NUM]; 75eda14cbcSMatt Macy 76eda14cbcSMatt Macy /* 77eda14cbcSMatt Macy * Methods used to define raidz implementation 78eda14cbcSMatt Macy * 79eda14cbcSMatt Macy * @raidz_gen_f Parity generation function 80eda14cbcSMatt Macy * @par1 pointer to raidz_map 81eda14cbcSMatt Macy * @raidz_rec_f Data reconstruction function 82eda14cbcSMatt Macy * @par1 pointer to raidz_map 83eda14cbcSMatt Macy * @par2 array of reconstruction targets 84eda14cbcSMatt Macy * @will_work_f Function returns TRUE if impl. is supported on the system 85eda14cbcSMatt Macy * @init_impl_f Function is called once on init 86eda14cbcSMatt Macy * @fini_impl_f Function is called once on fini 87eda14cbcSMatt Macy */ 88eda14cbcSMatt Macy typedef void (*raidz_gen_f)(void *); 89eda14cbcSMatt Macy typedef int (*raidz_rec_f)(void *, const int *); 90eda14cbcSMatt Macy typedef boolean_t (*will_work_f)(void); 91eda14cbcSMatt Macy typedef void (*init_impl_f)(void); 92eda14cbcSMatt Macy typedef void (*fini_impl_f)(void); 93eda14cbcSMatt Macy 94eda14cbcSMatt Macy #define RAIDZ_IMPL_NAME_MAX (20) 95eda14cbcSMatt Macy 96eda14cbcSMatt Macy typedef struct raidz_impl_ops { 97eda14cbcSMatt Macy init_impl_f init; 98eda14cbcSMatt Macy fini_impl_f fini; 99eda14cbcSMatt Macy raidz_gen_f gen[RAIDZ_GEN_NUM]; /* Parity generate functions */ 100eda14cbcSMatt Macy raidz_rec_f rec[RAIDZ_REC_NUM]; /* Data reconstruction functions */ 101eda14cbcSMatt Macy will_work_f is_supported; /* Support check function */ 102eda14cbcSMatt Macy char name[RAIDZ_IMPL_NAME_MAX]; /* Name of the implementation */ 103eda14cbcSMatt Macy } raidz_impl_ops_t; 104eda14cbcSMatt Macy 105eda14cbcSMatt Macy typedef struct raidz_col { 106eda14cbcSMatt Macy uint64_t rc_devidx; /* child device index for I/O */ 107eda14cbcSMatt Macy uint64_t rc_offset; /* device offset */ 108eda14cbcSMatt Macy uint64_t rc_size; /* I/O size */ 109184c1b94SMartin Matuska abd_t rc_abdstruct; /* rc_abd probably points here */ 110eda14cbcSMatt Macy abd_t *rc_abd; /* I/O data */ 111f9693befSMartin Matuska abd_t *rc_orig_data; /* pre-reconstruction */ 112eda14cbcSMatt Macy int rc_error; /* I/O error for this device */ 113eda14cbcSMatt Macy uint8_t rc_tried; /* Did we attempt this I/O column? */ 114eda14cbcSMatt Macy uint8_t rc_skipped; /* Did we skip this I/O column? */ 1157877fdebSMatt Macy uint8_t rc_need_orig_restore; /* need to restore from orig_data? */ 11616038816SMartin Matuska uint8_t rc_force_repair; /* Write good data to this column */ 11716038816SMartin Matuska uint8_t rc_allow_repair; /* Allow repair I/O to this column */ 118eda14cbcSMatt Macy } raidz_col_t; 119eda14cbcSMatt Macy 1207877fdebSMatt Macy typedef struct raidz_row { 1217877fdebSMatt Macy uint64_t rr_cols; /* Regular column count */ 1227877fdebSMatt Macy uint64_t rr_scols; /* Count including skipped columns */ 1237877fdebSMatt Macy uint64_t rr_bigcols; /* Remainder data column count */ 1247877fdebSMatt Macy uint64_t rr_missingdata; /* Count of missing data devices */ 1257877fdebSMatt Macy uint64_t rr_missingparity; /* Count of missing parity devices */ 1267877fdebSMatt Macy uint64_t rr_firstdatacol; /* First data column/parity count */ 1277877fdebSMatt Macy abd_t *rr_abd_empty; /* dRAID empty sector buffer */ 1287877fdebSMatt Macy int rr_nempty; /* empty sectors included in parity */ 1297877fdebSMatt Macy #ifdef ZFS_DEBUG 1307877fdebSMatt Macy uint64_t rr_offset; /* Logical offset for *_io_verify() */ 1317877fdebSMatt Macy uint64_t rr_size; /* Physical size for *_io_verify() */ 1327877fdebSMatt Macy #endif 1337877fdebSMatt Macy raidz_col_t rr_col[0]; /* Flexible array of I/O columns */ 1347877fdebSMatt Macy } raidz_row_t; 1357877fdebSMatt Macy 136eda14cbcSMatt Macy typedef struct raidz_map { 1377877fdebSMatt Macy boolean_t rm_ecksuminjected; /* checksum error was injected */ 1387877fdebSMatt Macy int rm_nrows; /* Regular row count */ 1397877fdebSMatt Macy int rm_nskip; /* RAIDZ sectors skipped for padding */ 1407877fdebSMatt Macy int rm_skipstart; /* Column index of padding start */ 141eda14cbcSMatt Macy const raidz_impl_ops_t *rm_ops; /* RAIDZ math operations */ 1427877fdebSMatt Macy raidz_row_t *rm_row[0]; /* flexible array of rows */ 143eda14cbcSMatt Macy } raidz_map_t; 144eda14cbcSMatt Macy 1457877fdebSMatt Macy 146eda14cbcSMatt Macy #define RAIDZ_ORIGINAL_IMPL (INT_MAX) 147eda14cbcSMatt Macy 148eda14cbcSMatt Macy extern const raidz_impl_ops_t vdev_raidz_scalar_impl; 149eda14cbcSMatt Macy extern boolean_t raidz_will_scalar_work(void); 150eda14cbcSMatt Macy 151eda14cbcSMatt Macy #if defined(__x86_64) && defined(HAVE_SSE2) /* only x86_64 for now */ 152eda14cbcSMatt Macy extern const raidz_impl_ops_t vdev_raidz_sse2_impl; 153eda14cbcSMatt Macy #endif 154eda14cbcSMatt Macy #if defined(__x86_64) && defined(HAVE_SSSE3) /* only x86_64 for now */ 155eda14cbcSMatt Macy extern const raidz_impl_ops_t vdev_raidz_ssse3_impl; 156eda14cbcSMatt Macy #endif 157eda14cbcSMatt Macy #if defined(__x86_64) && defined(HAVE_AVX2) /* only x86_64 for now */ 158eda14cbcSMatt Macy extern const raidz_impl_ops_t vdev_raidz_avx2_impl; 159eda14cbcSMatt Macy #endif 160eda14cbcSMatt Macy #if defined(__x86_64) && defined(HAVE_AVX512F) /* only x86_64 for now */ 161eda14cbcSMatt Macy extern const raidz_impl_ops_t vdev_raidz_avx512f_impl; 162eda14cbcSMatt Macy #endif 163eda14cbcSMatt Macy #if defined(__x86_64) && defined(HAVE_AVX512BW) /* only x86_64 for now */ 164eda14cbcSMatt Macy extern const raidz_impl_ops_t vdev_raidz_avx512bw_impl; 165eda14cbcSMatt Macy #endif 166eda14cbcSMatt Macy #if defined(__aarch64__) 167eda14cbcSMatt Macy extern const raidz_impl_ops_t vdev_raidz_aarch64_neon_impl; 168eda14cbcSMatt Macy extern const raidz_impl_ops_t vdev_raidz_aarch64_neonx2_impl; 169eda14cbcSMatt Macy #endif 170eda14cbcSMatt Macy #if defined(__powerpc__) 171eda14cbcSMatt Macy extern const raidz_impl_ops_t vdev_raidz_powerpc_altivec_impl; 172eda14cbcSMatt Macy #endif 173eda14cbcSMatt Macy 174eda14cbcSMatt Macy /* 175eda14cbcSMatt Macy * Commonly used raidz_map helpers 176eda14cbcSMatt Macy * 177eda14cbcSMatt Macy * raidz_parity Returns parity of the RAIDZ block 178eda14cbcSMatt Macy * raidz_ncols Returns number of columns the block spans 1797877fdebSMatt Macy * Note, all rows have the same number of columns. 180eda14cbcSMatt Macy * raidz_nbigcols Returns number of big columns 181eda14cbcSMatt Macy * raidz_col_p Returns pointer to a column 182eda14cbcSMatt Macy * raidz_col_size Returns size of a column 183eda14cbcSMatt Macy * raidz_big_size Returns size of big columns 184eda14cbcSMatt Macy * raidz_short_size Returns size of short columns 185eda14cbcSMatt Macy */ 1867877fdebSMatt Macy #define raidz_parity(rm) ((rm)->rm_row[0]->rr_firstdatacol) 1877877fdebSMatt Macy #define raidz_ncols(rm) ((rm)->rm_row[0]->rr_cols) 188eda14cbcSMatt Macy #define raidz_nbigcols(rm) ((rm)->rm_bigcols) 189eda14cbcSMatt Macy #define raidz_col_p(rm, c) ((rm)->rm_col + (c)) 190eda14cbcSMatt Macy #define raidz_col_size(rm, c) ((rm)->rm_col[c].rc_size) 191eda14cbcSMatt Macy #define raidz_big_size(rm) (raidz_col_size(rm, CODE_P)) 192eda14cbcSMatt Macy #define raidz_short_size(rm) (raidz_col_size(rm, raidz_ncols(rm)-1)) 193eda14cbcSMatt Macy 194eda14cbcSMatt Macy /* 195eda14cbcSMatt Macy * Macro defines an RAIDZ parity generation method 196eda14cbcSMatt Macy * 197eda14cbcSMatt Macy * @code parity the function produce 198eda14cbcSMatt Macy * @impl name of the implementation 199eda14cbcSMatt Macy */ 200eda14cbcSMatt Macy #define _RAIDZ_GEN_WRAP(code, impl) \ 201eda14cbcSMatt Macy static void \ 2027877fdebSMatt Macy impl ## _gen_ ## code(void *rrp) \ 203eda14cbcSMatt Macy { \ 2047877fdebSMatt Macy raidz_row_t *rr = (raidz_row_t *)rrp; \ 2057877fdebSMatt Macy raidz_generate_## code ## _impl(rr); \ 206eda14cbcSMatt Macy } 207eda14cbcSMatt Macy 208eda14cbcSMatt Macy /* 209eda14cbcSMatt Macy * Macro defines an RAIDZ data reconstruction method 210eda14cbcSMatt Macy * 211eda14cbcSMatt Macy * @code parity the function produce 212eda14cbcSMatt Macy * @impl name of the implementation 213eda14cbcSMatt Macy */ 214eda14cbcSMatt Macy #define _RAIDZ_REC_WRAP(code, impl) \ 215eda14cbcSMatt Macy static int \ 2167877fdebSMatt Macy impl ## _rec_ ## code(void *rrp, const int *tgtidx) \ 217eda14cbcSMatt Macy { \ 2187877fdebSMatt Macy raidz_row_t *rr = (raidz_row_t *)rrp; \ 2197877fdebSMatt Macy return (raidz_reconstruct_## code ## _impl(rr, tgtidx)); \ 220eda14cbcSMatt Macy } 221eda14cbcSMatt Macy 222eda14cbcSMatt Macy /* 223eda14cbcSMatt Macy * Define all gen methods for an implementation 224eda14cbcSMatt Macy * 225eda14cbcSMatt Macy * @impl name of the implementation 226eda14cbcSMatt Macy */ 227eda14cbcSMatt Macy #define DEFINE_GEN_METHODS(impl) \ 228eda14cbcSMatt Macy _RAIDZ_GEN_WRAP(p, impl); \ 229eda14cbcSMatt Macy _RAIDZ_GEN_WRAP(pq, impl); \ 230eda14cbcSMatt Macy _RAIDZ_GEN_WRAP(pqr, impl) 231eda14cbcSMatt Macy 232eda14cbcSMatt Macy /* 233eda14cbcSMatt Macy * Define all rec functions for an implementation 234eda14cbcSMatt Macy * 235eda14cbcSMatt Macy * @impl name of the implementation 236eda14cbcSMatt Macy */ 237eda14cbcSMatt Macy #define DEFINE_REC_METHODS(impl) \ 238eda14cbcSMatt Macy _RAIDZ_REC_WRAP(p, impl); \ 239eda14cbcSMatt Macy _RAIDZ_REC_WRAP(q, impl); \ 240eda14cbcSMatt Macy _RAIDZ_REC_WRAP(r, impl); \ 241eda14cbcSMatt Macy _RAIDZ_REC_WRAP(pq, impl); \ 242eda14cbcSMatt Macy _RAIDZ_REC_WRAP(pr, impl); \ 243eda14cbcSMatt Macy _RAIDZ_REC_WRAP(qr, impl); \ 244eda14cbcSMatt Macy _RAIDZ_REC_WRAP(pqr, impl) 245eda14cbcSMatt Macy 246eda14cbcSMatt Macy #define RAIDZ_GEN_METHODS(impl) \ 247eda14cbcSMatt Macy { \ 248eda14cbcSMatt Macy [RAIDZ_GEN_P] = & impl ## _gen_p, \ 249eda14cbcSMatt Macy [RAIDZ_GEN_PQ] = & impl ## _gen_pq, \ 250eda14cbcSMatt Macy [RAIDZ_GEN_PQR] = & impl ## _gen_pqr \ 251eda14cbcSMatt Macy } 252eda14cbcSMatt Macy 253eda14cbcSMatt Macy #define RAIDZ_REC_METHODS(impl) \ 254eda14cbcSMatt Macy { \ 255eda14cbcSMatt Macy [RAIDZ_REC_P] = & impl ## _rec_p, \ 256eda14cbcSMatt Macy [RAIDZ_REC_Q] = & impl ## _rec_q, \ 257eda14cbcSMatt Macy [RAIDZ_REC_R] = & impl ## _rec_r, \ 258eda14cbcSMatt Macy [RAIDZ_REC_PQ] = & impl ## _rec_pq, \ 259eda14cbcSMatt Macy [RAIDZ_REC_PR] = & impl ## _rec_pr, \ 260eda14cbcSMatt Macy [RAIDZ_REC_QR] = & impl ## _rec_qr, \ 261eda14cbcSMatt Macy [RAIDZ_REC_PQR] = & impl ## _rec_pqr \ 262eda14cbcSMatt Macy } 263eda14cbcSMatt Macy 264eda14cbcSMatt Macy 265eda14cbcSMatt Macy typedef struct raidz_impl_kstat { 266eda14cbcSMatt Macy uint64_t gen[RAIDZ_GEN_NUM]; /* gen method speed B/s */ 267eda14cbcSMatt Macy uint64_t rec[RAIDZ_REC_NUM]; /* rec method speed B/s */ 268eda14cbcSMatt Macy } raidz_impl_kstat_t; 269eda14cbcSMatt Macy 270eda14cbcSMatt Macy /* 271eda14cbcSMatt Macy * Enumerate various multiplication constants 272eda14cbcSMatt Macy * used in reconstruction methods 273eda14cbcSMatt Macy */ 274eda14cbcSMatt Macy typedef enum raidz_mul_info { 275eda14cbcSMatt Macy /* Reconstruct Q */ 276eda14cbcSMatt Macy MUL_Q_X = 0, 277eda14cbcSMatt Macy /* Reconstruct R */ 278eda14cbcSMatt Macy MUL_R_X = 0, 279eda14cbcSMatt Macy /* Reconstruct PQ */ 280eda14cbcSMatt Macy MUL_PQ_X = 0, 281eda14cbcSMatt Macy MUL_PQ_Y = 1, 282eda14cbcSMatt Macy /* Reconstruct PR */ 283eda14cbcSMatt Macy MUL_PR_X = 0, 284eda14cbcSMatt Macy MUL_PR_Y = 1, 285eda14cbcSMatt Macy /* Reconstruct QR */ 286eda14cbcSMatt Macy MUL_QR_XQ = 0, 287eda14cbcSMatt Macy MUL_QR_X = 1, 288eda14cbcSMatt Macy MUL_QR_YQ = 2, 289eda14cbcSMatt Macy MUL_QR_Y = 3, 290eda14cbcSMatt Macy /* Reconstruct PQR */ 291eda14cbcSMatt Macy MUL_PQR_XP = 0, 292eda14cbcSMatt Macy MUL_PQR_XQ = 1, 293eda14cbcSMatt Macy MUL_PQR_XR = 2, 294eda14cbcSMatt Macy MUL_PQR_YU = 3, 295eda14cbcSMatt Macy MUL_PQR_YP = 4, 296eda14cbcSMatt Macy MUL_PQR_YQ = 5, 297eda14cbcSMatt Macy 298eda14cbcSMatt Macy MUL_CNT = 6 299eda14cbcSMatt Macy } raidz_mul_info_t; 300eda14cbcSMatt Macy 301eda14cbcSMatt Macy /* 302eda14cbcSMatt Macy * Powers of 2 in the Galois field. 303eda14cbcSMatt Macy */ 304eda14cbcSMatt Macy extern const uint8_t vdev_raidz_pow2[256] __attribute__((aligned(256))); 305eda14cbcSMatt Macy /* Logs of 2 in the Galois field defined above. */ 306eda14cbcSMatt Macy extern const uint8_t vdev_raidz_log2[256] __attribute__((aligned(256))); 307eda14cbcSMatt Macy 308eda14cbcSMatt Macy /* 309eda14cbcSMatt Macy * Multiply a given number by 2 raised to the given power. 310eda14cbcSMatt Macy */ 311eda14cbcSMatt Macy static inline uint8_t 312eda14cbcSMatt Macy vdev_raidz_exp2(const uint8_t a, const unsigned exp) 313eda14cbcSMatt Macy { 314eda14cbcSMatt Macy if (a == 0) 315eda14cbcSMatt Macy return (0); 316eda14cbcSMatt Macy 317eda14cbcSMatt Macy return (vdev_raidz_pow2[(exp + (unsigned)vdev_raidz_log2[a]) % 255]); 318eda14cbcSMatt Macy } 319eda14cbcSMatt Macy 320eda14cbcSMatt Macy /* 321eda14cbcSMatt Macy * Galois Field operations. 322eda14cbcSMatt Macy * 323eda14cbcSMatt Macy * gf_exp2 - computes 2 raised to the given power 324eda14cbcSMatt Macy * gf_exp2 - computes 4 raised to the given power 325eda14cbcSMatt Macy * gf_mul - multiplication 326eda14cbcSMatt Macy * gf_div - division 327eda14cbcSMatt Macy * gf_inv - multiplicative inverse 328eda14cbcSMatt Macy */ 329eda14cbcSMatt Macy typedef unsigned gf_t; 330eda14cbcSMatt Macy typedef unsigned gf_log_t; 331eda14cbcSMatt Macy 332eda14cbcSMatt Macy static inline gf_t 333eda14cbcSMatt Macy gf_mul(const gf_t a, const gf_t b) 334eda14cbcSMatt Macy { 335eda14cbcSMatt Macy gf_log_t logsum; 336eda14cbcSMatt Macy 337eda14cbcSMatt Macy if (a == 0 || b == 0) 338eda14cbcSMatt Macy return (0); 339eda14cbcSMatt Macy 340eda14cbcSMatt Macy logsum = (gf_log_t)vdev_raidz_log2[a] + (gf_log_t)vdev_raidz_log2[b]; 341eda14cbcSMatt Macy 342eda14cbcSMatt Macy return ((gf_t)vdev_raidz_pow2[logsum % 255]); 343eda14cbcSMatt Macy } 344eda14cbcSMatt Macy 345eda14cbcSMatt Macy static inline gf_t 346eda14cbcSMatt Macy gf_div(const gf_t a, const gf_t b) 347eda14cbcSMatt Macy { 348eda14cbcSMatt Macy gf_log_t logsum; 349eda14cbcSMatt Macy 350eda14cbcSMatt Macy ASSERT3U(b, >, 0); 351eda14cbcSMatt Macy if (a == 0) 352eda14cbcSMatt Macy return (0); 353eda14cbcSMatt Macy 354eda14cbcSMatt Macy logsum = (gf_log_t)255 + (gf_log_t)vdev_raidz_log2[a] - 355eda14cbcSMatt Macy (gf_log_t)vdev_raidz_log2[b]; 356eda14cbcSMatt Macy 357eda14cbcSMatt Macy return ((gf_t)vdev_raidz_pow2[logsum % 255]); 358eda14cbcSMatt Macy } 359eda14cbcSMatt Macy 360eda14cbcSMatt Macy static inline gf_t 361eda14cbcSMatt Macy gf_inv(const gf_t a) 362eda14cbcSMatt Macy { 363eda14cbcSMatt Macy gf_log_t logsum; 364eda14cbcSMatt Macy 365eda14cbcSMatt Macy ASSERT3U(a, >, 0); 366eda14cbcSMatt Macy 367eda14cbcSMatt Macy logsum = (gf_log_t)255 - (gf_log_t)vdev_raidz_log2[a]; 368eda14cbcSMatt Macy 369eda14cbcSMatt Macy return ((gf_t)vdev_raidz_pow2[logsum]); 370eda14cbcSMatt Macy } 371eda14cbcSMatt Macy 372eda14cbcSMatt Macy static inline gf_t 373eda14cbcSMatt Macy gf_exp2(gf_log_t exp) 374eda14cbcSMatt Macy { 375eda14cbcSMatt Macy return (vdev_raidz_pow2[exp % 255]); 376eda14cbcSMatt Macy } 377eda14cbcSMatt Macy 378eda14cbcSMatt Macy static inline gf_t 379eda14cbcSMatt Macy gf_exp4(gf_log_t exp) 380eda14cbcSMatt Macy { 381eda14cbcSMatt Macy ASSERT3U(exp, <=, 255); 382eda14cbcSMatt Macy return ((gf_t)vdev_raidz_pow2[(2 * exp) % 255]); 383eda14cbcSMatt Macy } 384eda14cbcSMatt Macy 385eda14cbcSMatt Macy #ifdef __cplusplus 386eda14cbcSMatt Macy } 387eda14cbcSMatt Macy #endif 388eda14cbcSMatt Macy 389eda14cbcSMatt Macy #endif /* _VDEV_RAIDZ_H */ 390