# DF-4715 — vinumraid5 second-bad-subdisk stale loop indexes plex->sdnos[] by COUNT, not by ordinal → healthy subdisks force-marked stale

## What this proves

When a RAID-5 write meets a second unusable data subdisk (or any unusable
data subdisk while the parity subdisk is down), bre5() "makes all involved
subdisks stale" (`sys/dev/raid/vinum/vinumraid5.c:413-417`). The loop
indexes `plex->sdnos[sdno]` with `sdno` running `0..m.sdcount-1` — a
COUNT of participating subdisks, not their ordinals. Unless the request
starts at ordinal 0, the wrong (healthy) subdisks are force-marked
`sd_stale` ("invalid data") and the state change is saved to disk.

Guest-verified: 3-sd RAID-5 plex, write spanning data ordinals 1 and 2
with both down → refusal path fires → **s0 (the healthy parity subdisk,
ordinal 0) transitions up→stale** while the actually-involved (already
down) subdisks are untouched. On the fixed kernel (ordinal walk) s0 stays
up.

Impact: spurious degradation of healthy subdisks on an array that is
already failing (double fault): further reads/writes of stripes whose
parity was healthy now fail or take recovery paths; an admin reacting to
the bogus "stale" labels may re-initialize good subdisks. Data-integrity
mislabeling + availability loss (local DoS amplifier).

## Setup / trigger

Same array as DF-4714 (`../DF-4714/setup_vinum.sh`). Trigger is embedded
in `../DF-4714/run.sh` step [2] and reproduced by `run.sh` here:

`vinum setstate -f down rv.p0.s1; vinum setstate -f down rv.p0.s2;` then
ONE 32KB write at volume sectors [128,192) (EIO expected) →
`vinum list` shows the wrong subdisk staled.

## Fix validation

Included in DF-4714's fix.diff (same block): the loop now walks the
participating ordinals (firstsdno + parity-skip + wrap). Patched kernel:
same write EIOs but **s0 stays up** (`../DF-4714/run.patched.log` step 2).
