* 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_draid_cksum_finish() time we can compare it with the good data. */
| 807 | * vdev_draid_cksum_finish() time we can compare it with the good data. |
| 808 | */ |
| 809 | static void |
| 810 | vdev_draid_cksum_report(zio_t *zio, zio_cksum_report_t *zcr, void *arg) |
| 811 | { |
| 812 | size_t c = (size_t)(uintptr_t)arg; |
| 813 | raidz_map_t *rm = zio->io_vsd; |
| 814 | |
| 815 | /* set up the report and bump the refcount */ |
| 816 | zcr->zcr_cbdata = rm; |
| 817 | zcr->zcr_cbinfo = c; |
| 818 | zcr->zcr_finish = vdev_draid_cksum_finish; |
| 819 | zcr->zcr_free = vdev_draid_cksum_free; |
| 820 | |
| 821 | rm->rm_reports++; |
| 822 | ASSERT3U(rm->rm_reports, >, 0); |
| 823 | |
| 824 | if (rm->rm_row[0]->rr_abd_copy != NULL) |
| 825 | return; |
| 826 | |
| 827 | /* |
| 828 | * It's the first time we're called for this raidz_map_t, so we need |
| 829 | * to copy the data aside; there's no guarantee that our zio's buffer |
| 830 | * won't be re-used for something else. |
| 831 | * |
| 832 | * Our parity data is already in separate buffers, so there's no need |
| 833 | * to copy them. Furthermore, all columns should have been expanded |
| 834 | * by vdev_draid_map_alloc_empty() when attempting reconstruction. |
| 835 | */ |
| 836 | for (int i = 0; i < rm->rm_nrows; i++) { |
| 837 | raidz_row_t *rr = rm->rm_row[i]; |
| 838 | size_t offset = 0; |
| 839 | size_t size = 0; |
| 840 | |
| 841 | for (c = rr->rr_firstdatacol; c < rr->rr_cols; c++) { |
| 842 | ASSERT3U(rr->rr_col[c].rc_size, ==, |
| 843 | rr->rr_col[0].rc_size); |
| 844 | size += rr->rr_col[c].rc_size; |
| 845 | } |
| 846 | |
| 847 | rr->rr_abd_copy = abd_alloc_for_io(size, B_FALSE); |
| 848 | |
| 849 | for (c = rr->rr_firstdatacol; c < rr->rr_cols; c++) { |
| 850 | raidz_col_t *col = &rr->rr_col[c]; |
| 851 | abd_t *tmp = abd_get_offset_size(rr->rr_abd_copy, |
| 852 | offset, col->rc_size); |
| 853 | |
| 854 | abd_copy(tmp, col->rc_abd, col->rc_size); |
| 855 | |
| 856 | if (abd_is_gang(col->rc_abd)) |
| 857 | abd_free(col->rc_abd); |
| 858 | else |
| 859 | abd_put(col->rc_abd); |
| 860 | |
| 861 | col->rc_abd = tmp; |
| 862 | offset += col->rc_size; |
| 863 | } |
| 864 | ASSERT3U(offset, ==, size); |
| 865 | } |
| 866 | } |
nothing calls this directly
no test coverage detected