-
Improvement
-
Resolution: Unresolved
-
Medium
-
None
-
None
-
None
-
3
-
9223372036854775807
Problem
lod_primary_pick() takes a write extent but never uses it. A mirror is a first-class pick only when every inited OST on it is available.
That check is too strict: one inactive OST outside the write range disqualifies the whole mirror, even though the write could succeed. The pick then falls back to a lme_prefer or any remaining mirror that may itself contain an unavailable OST, or fails with ENODATA when no mirror is fully healthy.
Why not a plain overlap check
if (!lu_extent_is_overlapped(extent, &lod_comp->llc_extent)) continue;
That would replace all-OST-health with overlap-OST-health as the first-class pick.
The first write on an RDONLY FLR file picks a primary and stays on it until resync. After the pick, lod_stale_components() marks overlapping components on the other mirrors stale, and lme_stale is mirror-wide, so those mirrors drop out. Later writes go through lod_declare_update_write_pending(), which does not call lod_primary_pick() again. A later write outside the first range can then hit an inactive OST ignored at pick time. Example: mirror A (preferred) is healthy on [0, 1MiB) but has an inactive OST on [1MiB, EOF); mirror B is fully healthy. A write to [0, 64KiB) would pick A, and a later write at 2MiB has nowhere else to go.
Also LAYOUT_INTENT_TRUNC to 0 is [0, 0), which overlaps nothing and would skip the check entirely.
Proposed change
Keep all-OST-health first. Add overlap-health as an intermediate fallback:
- all inited OSTs available (current; prefer lme_prefer)
- only OSTs overlapping extent available (new; prefer lme_prefer)
- lme_prefer with some unavailable OST
- any remaining non-stale, non-parity mirror
Empty extents keep the all-OST check.
Tests
sanity-flr: prefer a fully healthy mirror when one exists; if none, pick a mirror healthy only in the write range; trunc-to-0 still runs the all-OST check.