]>
git.proxmox.com Git - ceph.git/blob - ceph/src/erasure-code/jerasure/jerasure/src/galois.c
2 * Copyright (c) 2014, James S. Plank and Kevin Greenan
5 * Jerasure - A C/C++ Library for a Variety of Reed-Solomon and RAID-6 Erasure
8 * Revision 2.0: Galois Field backend now links to GF-Complete
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
14 * - Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
17 * - Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in
19 * the documentation and/or other materials provided with the
22 * - Neither the name of the University of Tennessee nor the names of its
23 * contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
31 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
32 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
33 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
34 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY
36 * WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 * POSSIBILITY OF SUCH DAMAGE.
40 /* Jerasure's authors:
42 Revision 2.x - 2014: James S. Plank and Kevin M. Greenan
43 Revision 1.2 - 2008: James S. Plank, Scott Simmerman and Catherine D. Schuman.
44 Revision 1.0 - 2007: James S. Plank
55 #define MAX_GF_INSTANCES 64
56 gf_t
*gfp_array
[MAX_GF_INSTANCES
] = { 0 };
57 int gfp_is_composite
[MAX_GF_INSTANCES
] = { 0 };
59 gf_t
*galois_get_field_ptr(int w
)
61 if (gfp_array
[w
] != NULL
) {
68 gf_t
* galois_init_field(int w
,
80 if (w
<= 0 || w
> 32) {
81 fprintf(stderr
, "ERROR -- cannot init default Galois field for w=%d\n", w
);
85 gfp
= (gf_t
*) malloc(sizeof(gf_t
));
87 fprintf(stderr
, "ERROR -- cannot allocate memory for Galois field w=%d\n", w
);
91 scratch_size
= gf_scratch_size(w
, mult_type
, region_type
, divide_type
, arg1
, arg2
);
93 fprintf(stderr
, "ERROR -- cannot get scratch size for base field w=%d\n", w
);
97 scratch_memory
= malloc(scratch_size
);
98 if (!scratch_memory
) {
99 fprintf(stderr
, "ERROR -- cannot get scratch memory for base field w=%d\n", w
);
103 if(!gf_init_hard(gfp
,
114 fprintf(stderr
, "ERROR -- cannot init default Galois field for w=%d\n", w
);
118 gfp_is_composite
[w
] = 0;
122 gf_t
* galois_init_composite_field(int w
,
129 void *scratch_memory
;
132 if (w
<= 0 || w
> 32) {
133 fprintf(stderr
, "ERROR -- cannot init composite field for w=%d\n", w
);
137 gfp
= (gf_t
*) malloc(sizeof(gf_t
));
139 fprintf(stderr
, "ERROR -- cannot allocate memory for Galois field w=%d\n", w
);
143 scratch_size
= gf_scratch_size(w
, GF_MULT_COMPOSITE
, region_type
, divide_type
, degree
, 0);
145 fprintf(stderr
, "ERROR -- cannot get scratch size for composite field w=%d\n", w
);
149 scratch_memory
= malloc(scratch_size
);
150 if (!scratch_memory
) {
151 fprintf(stderr
, "ERROR -- cannot get scratch memory for composite field w=%d\n", w
);
155 if(!gf_init_hard(gfp
,
166 fprintf(stderr
, "ERROR -- cannot init default composite field for w=%d\n", w
);
169 gfp_is_composite
[w
] = 1;
173 int galois_init_default_field(int w
)
175 if (gfp_array
[w
] == NULL
) {
176 gfp_array
[w
] = (gf_t
*)malloc(sizeof(gf_t
));
177 if(gfp_array
[w
] == NULL
)
179 if (!gf_init_easy(gfp_array
[w
], w
))
185 static void galois_init(int w
)
187 if (w
<= 0 || w
> 32) {
188 fprintf(stderr
, "ERROR -- cannot init default Galois field for w=%d\n", w
);
192 switch (galois_init_default_field(w
)) {
194 fprintf(stderr
, "ERROR -- cannot allocate memory for Galois field w=%d\n", w
);
198 fprintf(stderr
, "ERROR -- cannot init default Galois field for w=%d\n", w
);
205 static int is_valid_gf(gf_t
*gf
, int w
)
207 // TODO: I assume we may eventually
208 // want to do w=64 and 128, so w
209 // will be needed to perform this check
215 if (gf
->multiply
.w32
== NULL
) {
218 if (gf
->multiply_region
.w32
== NULL
) {
221 if (gf
->divide
.w32
== NULL
) {
224 if (gf
->inverse
.w32
== NULL
) {
227 if (gf
->extract_word
.w32
== NULL
) {
234 void galois_change_technique(gf_t
*gf
, int w
)
236 if (w
<= 0 || w
> 32) {
237 fprintf(stderr
, "ERROR -- cannot support Galois field for w=%d\n", w
);
241 if (!is_valid_gf(gf
, w
)) {
242 fprintf(stderr
, "ERROR -- overriding with invalid Galois field for w=%d\n", w
);
246 if (gfp_array
[w
] != NULL
) {
247 gf_free(gfp_array
[w
], gfp_is_composite
[w
]);
253 int galois_single_multiply(int x
, int y
, int w
)
255 if (x
== 0 || y
== 0) return 0;
257 if (gfp_array
[w
] == NULL
) {
262 return gfp_array
[w
]->multiply
.w32(gfp_array
[w
], x
, y
);
264 fprintf(stderr
, "ERROR -- Galois field not implemented for w=%d\n", w
);
269 int galois_single_divide(int x
, int y
, int w
)
271 if (x
== 0) return 0;
272 if (y
== 0) return -1;
274 if (gfp_array
[w
] == NULL
) {
279 return gfp_array
[w
]->divide
.w32(gfp_array
[w
], x
, y
);
281 fprintf(stderr
, "ERROR -- Galois field not implemented for w=%d\n", w
);
286 void galois_w08_region_multiply(char *region
, /* Region to multiply */
287 int multby
, /* Number to multiply by */
288 int nbytes
, /* Number of bytes in region */
289 char *r2
, /* If r2 != NULL, products go here */
292 if (gfp_array
[8] == NULL
) {
295 gfp_array
[8]->multiply_region
.w32(gfp_array
[8], region
, r2
, multby
, nbytes
, add
);
298 void galois_w16_region_multiply(char *region
, /* Region to multiply */
299 int multby
, /* Number to multiply by */
300 int nbytes
, /* Number of bytes in region */
301 char *r2
, /* If r2 != NULL, products go here */
304 if (gfp_array
[16] == NULL
) {
307 gfp_array
[16]->multiply_region
.w32(gfp_array
[16], region
, r2
, multby
, nbytes
, add
);
311 void galois_w32_region_multiply(char *region
, /* Region to multiply */
312 int multby
, /* Number to multiply by */
313 int nbytes
, /* Number of bytes in region */
314 char *r2
, /* If r2 != NULL, products go here */
317 if (gfp_array
[32] == NULL
) {
320 gfp_array
[32]->multiply_region
.w32(gfp_array
[32], region
, r2
, multby
, nbytes
, add
);
323 void galois_w8_region_xor(void *src
, void *dest
, int nbytes
)
325 if (gfp_array
[8] == NULL
) {
328 gfp_array
[8]->multiply_region
.w32(gfp_array
[32], src
, dest
, 1, nbytes
, 1);
331 void galois_w16_region_xor(void *src
, void *dest
, int nbytes
)
333 if (gfp_array
[16] == NULL
) {
336 gfp_array
[16]->multiply_region
.w32(gfp_array
[16], src
, dest
, 1, nbytes
, 1);
339 void galois_w32_region_xor(void *src
, void *dest
, int nbytes
)
341 if (gfp_array
[32] == NULL
) {
344 gfp_array
[32]->multiply_region
.w32(gfp_array
[32], src
, dest
, 1, nbytes
, 1);
347 void galois_region_xor(char *src
, char *dest
, int nbytes
)
350 galois_w32_region_xor(src
, dest
, nbytes
);
353 for (i
= 0; i
< nbytes
; i
++) {
361 int galois_inverse(int y
, int w
)
363 if (y
== 0) return -1;
364 return galois_single_divide(1, y
, w
);