* returns EINVAL if reconstruction of the block will not be possible * returns ECKSUM if this specific reconstruction failed * returns 0 on successful reconstruction */
| 2056 | * returns 0 on successful reconstruction |
| 2057 | */ |
| 2058 | static int |
| 2059 | raidz_reconstruct(zio_t *zio, int *ltgts, int ntgts, int nparity) |
| 2060 | { |
| 2061 | raidz_map_t *rm = zio->io_vsd; |
| 2062 | |
| 2063 | /* Reconstruct each row */ |
| 2064 | for (int r = 0; r < rm->rm_nrows; r++) { |
| 2065 | raidz_row_t *rr = rm->rm_row[r]; |
| 2066 | int my_tgts[VDEV_RAIDZ_MAXPARITY]; /* value is child id */ |
| 2067 | int t = 0; |
| 2068 | int dead = 0; |
| 2069 | int dead_data = 0; |
| 2070 | |
| 2071 | for (int c = 0; c < rr->rr_cols; c++) { |
| 2072 | raidz_col_t *rc = &rr->rr_col[c]; |
| 2073 | ASSERT0(rc->rc_need_orig_restore); |
| 2074 | if (rc->rc_error != 0) { |
| 2075 | dead++; |
| 2076 | if (c >= nparity) |
| 2077 | dead_data++; |
| 2078 | continue; |
| 2079 | } |
| 2080 | if (rc->rc_size == 0) |
| 2081 | continue; |
| 2082 | for (int lt = 0; lt < ntgts; lt++) { |
| 2083 | if (rc->rc_devidx == ltgts[lt]) { |
| 2084 | if (rc->rc_orig_data == NULL) { |
| 2085 | rc->rc_orig_data = |
| 2086 | zio_buf_alloc(rc->rc_size); |
| 2087 | abd_copy_to_buf( |
| 2088 | rc->rc_orig_data, |
| 2089 | rc->rc_abd, rc->rc_size); |
| 2090 | } |
| 2091 | rc->rc_need_orig_restore = B_TRUE; |
| 2092 | |
| 2093 | dead++; |
| 2094 | if (c >= nparity) |
| 2095 | dead_data++; |
| 2096 | my_tgts[t++] = c; |
| 2097 | break; |
| 2098 | } |
| 2099 | } |
| 2100 | } |
| 2101 | if (dead > nparity) { |
| 2102 | /* reconstruction not possible */ |
| 2103 | raidz_restore_orig_data(rm); |
| 2104 | return (EINVAL); |
| 2105 | } |
| 2106 | rr->rr_code = 0; |
| 2107 | if (dead_data > 0) |
| 2108 | rr->rr_code = vdev_raidz_reconstruct_row(rm, rr, |
| 2109 | my_tgts, t); |
| 2110 | } |
| 2111 | |
| 2112 | /* Check for success */ |
| 2113 | if (raidz_checksum_verify(zio) == 0) { |
| 2114 | |
| 2115 | /* Reconstruction succeeded - report errors */ |
no test coverage detected