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

Function vdev_draid_xlate

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

Source from the content-addressed store, hash-verified

2239}
2240
2241static void
2242vdev_draid_xlate(vdev_t *cvd, const range_seg64_t *logical_rs,
2243 range_seg64_t *physical_rs, range_seg64_t *remain_rs)
2244{
2245 vdev_t *raidvd = cvd->vdev_parent;
2246 ASSERT(raidvd->vdev_ops == &vdev_draid_ops);
2247
2248 vdev_draid_config_t *vdc = raidvd->vdev_tsd;
2249 uint64_t ashift = raidvd->vdev_top->vdev_ashift;
2250
2251 /* Make sure the offsets are block-aligned */
2252 ASSERT0(logical_rs->rs_start % (1 << ashift));
2253 ASSERT0(logical_rs->rs_end % (1 << ashift));
2254
2255 uint64_t logical_start = logical_rs->rs_start;
2256 uint64_t logical_end = logical_rs->rs_end;
2257
2258 /*
2259 * Unaligned ranges must be skipped. All metaslabs are correctly
2260 * aligned so this should not happen, but this case is handled in
2261 * case it's needed by future callers.
2262 */
2263 uint64_t astart = vdev_draid_get_astart(raidvd, logical_start);
2264 if (astart != logical_start) {
2265 physical_rs->rs_start = logical_start;
2266 physical_rs->rs_end = logical_start;
2267 remain_rs->rs_start = MIN(astart, logical_end);
2268 remain_rs->rs_end = logical_end;
2269 return;
2270 }
2271
2272 /*
2273 * Unlike with mirrors and raidz a dRAID logical range can map
2274 * to multiple non-contiguous physical ranges. This is handled by
2275 * limiting the size of the logical range to a single group and
2276 * setting the remain argument such that it describes the remaining
2277 * unmapped logical range. This is stricter than absolutely
2278 * necessary but helps simplify the logic below.
2279 */
2280 uint64_t group = vdev_draid_offset_to_group(raidvd, logical_start);
2281 uint64_t nextstart = vdev_draid_group_to_offset(raidvd, group + 1);
2282 if (logical_end > nextstart)
2283 logical_end = nextstart;
2284
2285 /* Find the starting offset for each vdev in the group */
2286 uint64_t perm, groupstart;
2287 uint64_t start = vdev_draid_logical_to_physical(raidvd,
2288 logical_start, &perm, &groupstart);
2289 uint64_t end = start;
2290
2291 uint8_t *base;
2292 uint64_t iter, id;
2293 vdev_draid_get_perm(vdc, perm, &base, &iter);
2294
2295 /*
2296 * Check if the passed child falls within the group. If it does
2297 * update the start and end to reflect the physical range.
2298 * Otherwise, leave them unmodified which will result in an empty

Callers

nothing calls this directly

Calls 6

vdev_draid_get_astartFunction · 0.85
vdev_draid_get_permFunction · 0.85
vdev_draid_permute_idFunction · 0.85

Tested by

no test coverage detected