SIGN IN SIGN UP

fix(disk): four NVMe SMART fields read sixteen bytes early

`nvme_log.rs` omits Controller Busy Time, which the NVMe Base Specification
places at 111:96 of the SMART / Health Information log page (LID 02h). Every
field below it was read from the next field's offset:

  power_cycles      returned Power On Hours
  power_on_hours    returned Unsafe Shutdowns
  unsafe_shutdowns  returned Media and Data Integrity Errors
  media_errors      returned the error-log entry count

`media_errors` is the field a person uses to decide whether a drive is
failing, and it was reading a different counter. Actual power cycles were
never read at all.

Found by diffing two snapshots for readings that never change, then reading
the ones that survived: a drive reported 2189 power cycles against 43
power-on hours — a power cycle every seventy seconds. That is what made it
visible. The true figures are 2189 hours and 43 unsafe shutdowns. After the
fix the three drives read 254 cycles / 2189 hours, 1183 / 3466 and 100 /
2061, which are 8.6, 2.9 and 20.6 hours per cycle.

It shipped because the test was a tautology.
`health_log_reads_every_field_at_its_specified_offset` built its fixture
from *the parser's own offsets*, so it asserted that the code agreed with
itself — under a name claiming it checked the specification. Four of its
assertions were wrong and it passed.

The fixture now writes at spec offsets with a distinct non-zero value per
field, so a shift by one field cannot pass, and
`the_health_log_fixture_can_tell_the_fields_apart` checks that distinctness
rather than trusting the next author to remember why it matters. Confirmed
by reverting the parser to the old offsets: the test fails with `left: 27,
right: 1892`. It was verified to catch the bug before being trusted.

`controller_busy_time` is now parsed and kept rather than skipped, since
skipping it is what caused this.

HANDOFF's open work item on the ATA SMART path warned that it is "tested
only against buffers this project built". That is no longer hypothetical —
the NVMe path had the same bug, from the same cause. A parse test whose
fixture comes from the parser is a tautology; write it from the spec
document and confirm it fails against the old code.

Verified: fmt, clippy, both cross-target checks, 37 disk unit tests.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A
Adam Erickson committed
7192187ab4f4fcbf482c6948aedcd324e625abc8
Parent: ecd1281