* Invoked indirectly by zfs_ereport_start_checksum(), called * below when our read operation fails completely. The main point * is to keep a copy of everything we read from disk, so that at * vdev_raidz_cksum_finish() time we can compare it with the good data. */
| 301 | * vdev_raidz_cksum_finish() time we can compare it with the good data. |
| 302 | */ |
| 303 | static void |
| 304 | vdev_raidz_cksum_report(zio_t *zio, zio_cksum_report_t *zcr, void *arg) |
| 305 | { |
| 306 | size_t c = (size_t)(uintptr_t)arg; |
| 307 | raidz_map_t *rm = zio->io_vsd; |
| 308 | |
| 309 | /* set up the report and bump the refcount */ |
| 310 | zcr->zcr_cbdata = rm; |
| 311 | zcr->zcr_cbinfo = c; |
| 312 | zcr->zcr_finish = vdev_raidz_cksum_finish; |
| 313 | zcr->zcr_free = vdev_raidz_cksum_free; |
| 314 | |
| 315 | rm->rm_reports++; |
| 316 | ASSERT3U(rm->rm_reports, >, 0); |
| 317 | ASSERT3U(rm->rm_nrows, ==, 1); |
| 318 | |
| 319 | if (rm->rm_row[0]->rr_abd_copy != NULL) |
| 320 | return; |
| 321 | |
| 322 | /* |
| 323 | * It's the first time we're called for this raidz_map_t, so we need |
| 324 | * to copy the data aside; there's no guarantee that our zio's buffer |
| 325 | * won't be re-used for something else. |
| 326 | * |
| 327 | * Our parity data is already in separate buffers, so there's no need |
| 328 | * to copy them. |
| 329 | */ |
| 330 | for (int i = 0; i < rm->rm_nrows; i++) { |
| 331 | raidz_row_t *rr = rm->rm_row[i]; |
| 332 | size_t offset = 0; |
| 333 | size_t size = 0; |
| 334 | |
| 335 | for (c = rr->rr_firstdatacol; c < rr->rr_cols; c++) |
| 336 | size += rr->rr_col[c].rc_size; |
| 337 | |
| 338 | rr->rr_abd_copy = abd_alloc_for_io(size, B_FALSE); |
| 339 | |
| 340 | for (c = rr->rr_firstdatacol; c < rr->rr_cols; c++) { |
| 341 | raidz_col_t *col = &rr->rr_col[c]; |
| 342 | abd_t *tmp = abd_get_offset_size(rr->rr_abd_copy, |
| 343 | offset, col->rc_size); |
| 344 | |
| 345 | abd_copy(tmp, col->rc_abd, col->rc_size); |
| 346 | |
| 347 | abd_put(col->rc_abd); |
| 348 | col->rc_abd = tmp; |
| 349 | |
| 350 | offset += col->rc_size; |
| 351 | } |
| 352 | ASSERT3U(offset, ==, size); |
| 353 | } |
| 354 | } |
| 355 | |
| 356 | static const zio_vsd_ops_t vdev_raidz_vsd_ops = { |
| 357 | .vsd_free = vdev_raidz_map_free_vsd, |
nothing calls this directly
no test coverage detected