MCPcopy Create free account
hub / github.com/F-Stack/f-stack / vdev_raidz_combrec

Function vdev_raidz_combrec

freebsd/contrib/openzfs/module/zfs/vdev_raidz.c:2203–2287  ·  view source on GitHub ↗

* Iterate over all combinations of N bad vdevs and attempt a reconstruction. * Note that the algorithm below is non-optimal because it doesn't take into * account how reconstruction is actually performed. For example, with * triple-parity RAID-Z the reconstruction procedure is the same if column 4 * is targeted as invalid as if columns 1 and 4 are targeted since in both * cases we'd only use

Source from the content-addressed store, hash-verified

2201 * a future improvement.
2202 */
2203static int
2204vdev_raidz_combrec(zio_t *zio)
2205{
2206 int nparity = vdev_get_nparity(zio->io_vd);
2207 raidz_map_t *rm = zio->io_vsd;
2208
2209 /* Check if there's enough data to attempt reconstrution. */
2210 for (int i = 0; i < rm->rm_nrows; i++) {
2211 raidz_row_t *rr = rm->rm_row[i];
2212 int total_errors = 0;
2213
2214 for (int c = 0; c < rr->rr_cols; c++) {
2215 if (rr->rr_col[c].rc_error)
2216 total_errors++;
2217 }
2218
2219 if (total_errors > nparity)
2220 return (vdev_raidz_worst_error(rr));
2221 }
2222
2223 for (int num_failures = 1; num_failures <= nparity; num_failures++) {
2224 int tstore[VDEV_RAIDZ_MAXPARITY + 2];
2225 int *ltgts = &tstore[1]; /* value is logical child ID */
2226
2227 /* Determine number of logical children, n */
2228 int n = zio->io_vd->vdev_children;
2229
2230 ASSERT3U(num_failures, <=, nparity);
2231 ASSERT3U(num_failures, <=, VDEV_RAIDZ_MAXPARITY);
2232
2233 /* Handle corner cases in combrec logic */
2234 ltgts[-1] = -1;
2235 for (int i = 0; i < num_failures; i++) {
2236 ltgts[i] = i;
2237 }
2238 ltgts[num_failures] = n;
2239
2240 for (;;) {
2241 int err = raidz_reconstruct(zio, ltgts, num_failures,
2242 nparity);
2243 if (err == EINVAL) {
2244 /*
2245 * Reconstruction not possible with this #
2246 * failures; try more failures.
2247 */
2248 break;
2249 } else if (err == 0)
2250 return (0);
2251
2252 /* Compute next targets to try */
2253 for (int t = 0; ; t++) {
2254 ASSERT3U(t, <, num_failures);
2255 ltgts[t]++;
2256 if (ltgts[t] == n) {
2257 /* try more failures */
2258 ASSERT3U(t, ==, num_failures - 1);
2259 break;
2260 }

Callers 1

vdev_raidz_io_doneFunction · 0.85

Calls 3

vdev_get_nparityFunction · 0.85
vdev_raidz_worst_errorFunction · 0.85
raidz_reconstructFunction · 0.85

Tested by

no test coverage detected