| 1138 | } |
| 1139 | |
| 1140 | static uint64_t |
| 1141 | vdev_draid_map_alloc_row(zio_t *zio, raidz_row_t **rrp, uint64_t io_offset, |
| 1142 | uint64_t abd_offset, uint64_t abd_size) |
| 1143 | { |
| 1144 | vdev_t *vd = zio->io_vd; |
| 1145 | vdev_draid_config_t *vdc = vd->vdev_tsd; |
| 1146 | uint64_t ashift = vd->vdev_top->vdev_ashift; |
| 1147 | uint64_t io_size = abd_size; |
| 1148 | uint64_t io_asize = vdev_draid_asize(vd, io_size); |
| 1149 | uint64_t group = vdev_draid_offset_to_group(vd, io_offset); |
| 1150 | uint64_t start_offset = vdev_draid_group_to_offset(vd, group + 1); |
| 1151 | |
| 1152 | /* |
| 1153 | * Limit the io_size to the space remaining in the group. A second |
| 1154 | * row in the raidz_map_t is created for the remainder. |
| 1155 | */ |
| 1156 | if (io_offset + io_asize > start_offset) { |
| 1157 | io_size = vdev_draid_asize_to_psize(vd, |
| 1158 | start_offset - io_offset); |
| 1159 | } |
| 1160 | |
| 1161 | /* |
| 1162 | * At most a block may span the logical end of one group and the start |
| 1163 | * of the next group. Therefore, at the end of a group the io_size must |
| 1164 | * span the group width evenly and the remainder must be aligned to the |
| 1165 | * start of the next group. |
| 1166 | */ |
| 1167 | IMPLY(abd_offset == 0 && io_size < zio->io_size, |
| 1168 | (io_asize >> ashift) % vdc->vdc_groupwidth == 0); |
| 1169 | IMPLY(abd_offset != 0, |
| 1170 | vdev_draid_group_to_offset(vd, group) == io_offset); |
| 1171 | |
| 1172 | /* Lookup starting byte offset on each child vdev */ |
| 1173 | uint64_t groupstart, perm; |
| 1174 | uint64_t physical_offset = vdev_draid_logical_to_physical(vd, |
| 1175 | io_offset, &perm, &groupstart); |
| 1176 | |
| 1177 | /* |
| 1178 | * If there is less than groupwidth drives available after the group |
| 1179 | * start, the group is going to wrap onto the next row. 'wrap' is the |
| 1180 | * group disk number that starts on the next row. |
| 1181 | */ |
| 1182 | uint64_t ndisks = vdc->vdc_ndisks; |
| 1183 | uint64_t groupwidth = vdc->vdc_groupwidth; |
| 1184 | uint64_t wrap = groupwidth; |
| 1185 | |
| 1186 | if (groupstart + groupwidth > ndisks) |
| 1187 | wrap = ndisks - groupstart; |
| 1188 | |
| 1189 | /* The io size in units of the vdev's minimum sector size. */ |
| 1190 | const uint64_t psize = io_size >> ashift; |
| 1191 | |
| 1192 | /* |
| 1193 | * "Quotient": The number of data sectors for this stripe on all but |
| 1194 | * the "big column" child vdevs that also contain "remainder" data. |
| 1195 | */ |
| 1196 | uint64_t q = psize / vdc->vdc_ndata; |
| 1197 |
no test coverage detected