2 * Copyright (C) 2013 Andrea Mazzoleni
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
19 * RAID mode supporting up to 6 parities.
21 * It requires SSSE3 to get good performance with triple or more parities.
23 * This is the default mode set after calling raid_init().
25 #define RAID_MODE_CAUCHY 0
28 * RAID mode supporting up to 3 parities,
30 * It has a fast triple parity implementation without SSSE3, but it cannot
31 * go beyond triple parity.
33 * This is mostly intended for low end CPUs like ARM and AMD Athlon.
35 #define RAID_MODE_VANDERMONDE 1
38 * Maximum number of parity disks supported.
40 #define RAID_PARITY_MAX 6
43 * Maximum number of data disks supported.
45 #define RAID_DATA_MAX 251
48 * Initializes the RAID system.
50 * You must call this function before any other.
52 * The RAID system is initialized in the RAID_MODE_CAUCHY mode.
57 * Runs a basic functionality self test.
59 * The test is immediate, and it's intended to be run at application
60 * startup to check the integrity of the RAID system.
62 * It returns 0 on success.
64 int raid_selftest(void);
67 * Sets the mode to use. One of RAID_MODE_*.
69 * You can change mode at any time, and it will affect next calls to raid_gen(),
70 * raid_rec() and raid_data().
72 * The two modes are compatible for the first two levels of parity.
73 * The third one is different.
75 void raid_mode(int mode);
78 * Sets the zero buffer to use in recovering.
80 * Before calling raid_rec() and raid_data() you must provide a memory
81 * buffer filled with zero with the same size of the blocks to recover.
83 * This buffer is only read and never written.
85 void raid_zero(void *zero);
88 * Computes parity blocks.
90 * This function computes the specified number of parity blocks of the
91 * provided set of data blocks.
93 * Each parity block allows to recover one data block.
95 * @nd Number of data blocks.
96 * @np Number of parities blocks to compute.
97 * @size Size of the blocks pointed by @v. It must be a multiplier of 64.
98 * @v Vector of pointers to the blocks of data and parity.
99 * It has (@nd + @np) elements. The starting elements are the blocks for
100 * data, following with the parity blocks.
101 * Data blocks are only read and not modified. Parity blocks are written.
102 * Each block has @size bytes.
104 void raid_gen(int nd, int np, size_t size, void **v);
107 * Recovers failures in data and parity blocks.
109 * This function recovers all the data and parity blocks marked as bad
112 * Ensure to have @nr <= @np, otherwise recovering is not possible.
114 * The parities blocks used for recovering are automatically selected from
115 * the ones NOT present in the @ir vector.
117 * In case there are more parity blocks than needed, the parities at lower
118 * indexes are used in the recovering, and the others are ignored.
120 * Note that no internal integrity check is done when recovering. If the
121 * provided parities are correct, the resulting data will be correct.
122 * If parities are wrong, the resulting recovered data will be wrong.
123 * This happens even in the case you have more parities blocks than needed,
124 * and some form of integrity verification would be possible.
126 * @nr Number of failed data and parity blocks to recover.
127 * @ir[] Vector of @nr indexes of the failed data and parity blocks.
128 * The indexes start from 0. They must be in order.
129 * The first parity is represented with value @nd, the second with value
130 * @nd + 1, just like positions in the @v vector.
131 * @nd Number of data blocks.
132 * @np Number of parity blocks.
133 * @size Size of the blocks pointed by @v. It must be a multiplier of 64.
134 * @v Vector of pointers to the blocks of data and parity.
135 * It has (@nd + @np) elements. The starting elements are the blocks
136 * for data, following with the parity blocks.
137 * Each block has @size bytes.
139 void raid_rec(int nr, int *ir, int nd, int np, size_t size, void **v);
142 * Recovers failures in data blocks only.
144 * This function recovers all the data blocks marked as bad in the @id vector.
145 * The parity blocks are not modified.
147 * @nr Number of failed data blocks to recover.
148 * @id[] Vector of @nr indexes of the data blocks to recover.
149 * The indexes start from 0. They must be in order.
150 * @ip[] Vector of @nr indexes of the parity blocks to use for recovering.
151 * The indexes start from 0. They must be in order.
152 * @nd Number of data blocks.
153 * @size Size of the blocks pointed by @v. It must be a multiplier of 64.
154 * @v Vector of pointers to the blocks of data and parity.
155 * It has (@nd + @ip[@nr - 1] + 1) elements. The starting elements are the
156 * blocks for data, following with the parity blocks.
157 * Each blocks has @size bytes.
159 void raid_data(int nr, int *id, int *ip, int nd, size_t size, void **v);
162 * Check the provided failed blocks combination.
164 * This function checks if the specified failed blocks combination satisfies
165 * the redundancy information. A combination is assumed matching, if the
166 * remaining valid parity is matching the expected value after recovering.
168 * The number of failed blocks @nr must be strictly less than the number of
169 * parities @np, because you need one more parity to validate the recovering.
171 * No data or parity blocks are modified.
173 * @nr Number of failed data and parity blocks.
174 * @ir[] Vector of @nr indexes of the failed data and parity blocks.
175 * The indexes start from 0. They must be in order.
176 * The first parity is represented with value @nd, the second with value
177 * @nd + 1, just like positions in the @v vector.
178 * @nd Number of data blocks.
179 * @np Number of parity blocks.
180 * @size Size of the blocks pointed by @v. It must be a multiplier of 64.
181 * @v Vector of pointers to the blocks of data and parity.
182 * It has (@nd + @np) elements. The starting elements are the blocks
183 * for data, following with the parity blocks.
184 * Each block has @size bytes.
185 * @return 0 if the check is satisfied. -1 otherwise.
187 int raid_check(int nr, int *ir, int nd, int np, size_t size, void **v);
190 * Scan for failed blocks.
192 * This function identifies the failed data and parity blocks using the
193 * available redundancy.
195 * It uses a brute force method, and then the call can be expansive.
196 * The expected execution time is proportional at the binomial coefficient
197 * @np + @nd choose @np - 1, usually written as:
203 * No data or parity blocks are modified.
205 * The failed block indexes are returned in the @ir vector.
206 * It must have space for at least @np - 1 values.
208 * The returned @ir vector can then be used in a raid_rec() call to recover
209 * the failed data and parity blocks.
211 * @ir[] Vector filled with the indexes of the failed data and parity blocks.
212 * The indexes start from 0 and they are in order.
213 * The first parity is represented with value @nd, the second with value
214 * @nd + 1, just like positions in the @v vector.
215 * @nd Number of data blocks.
216 * @np Number of parity blocks.
217 * @size Size of the blocks pointed by @v. It must be a multiplier of 64.
218 * @v Vector of pointers to the blocks of data and parity.
219 * It has (@nd + @np) elements. The starting elements are the blocks
220 * for data, following with the parity blocks.
221 * Each block has @size bytes.
222 * @return Number of block indexes returned in the @ir vector.
223 * 0 if no error is detected.
224 * -1 if it's not possible to identify the failed disks.
226 int raid_scan(int *ir, int nd, int np, size_t size, void **v);