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

Function vdev_draid_map_alloc_row

freebsd/contrib/openzfs/module/zfs/vdev_draid.c:1140–1285  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1138}
1139
1140static uint64_t
1141vdev_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

Callers 1

vdev_draid_map_allocFunction · 0.85

Calls 11

vdev_draid_get_permFunction · 0.85
vdev_draid_permute_idFunction · 0.85
abd_alloc_linearFunction · 0.85
vdev_draid_asizeFunction · 0.70

Tested by

no test coverage detected