FABRIC-3.md: close BMAPREAD as already-built, fix a real devblock-0 header collision
Confirmed the F.12 handoff: cache_load_devblock() already unpacks/validates metadata on load, same "already built" story as BMAPWRITE. But tracing "validate on insertion" surfaced a real, load-bearing conflict unrelated to blk_meta_t: blk_subsys_attach_device() always runs the generic block-subsystem's own STFR/v2 header check at devblock 0, which would always read a home-blocks drive's 'LAHB' magic as "unrecognized" and leave it permanently write-refused (BLK_FMT_PROVISIONAL) -- or, if force-formatted via blk_subsys_confirm_format(), overwrite homeblocks_sig_t outright, since both want the same devblock 0. This was invisible to CERTVERIFY/WIREBIND/RUNCAP/MINT because none of them traced the generic attach path alongside homeblocks_sig_check(). Fixed: homeblocks_sig_t relocates to devblock 1 (a call-site change only, sig_start_fblock was already a plain parameter); MINT must also run the ordinary format-confirm path at devblock 0 so the drive is writable through the normal block-buffer path.
This commit is contained in:
+60
-4
@@ -159,7 +159,13 @@ decisions get added here, not to `FABRIC-2.md`. Follow the same discipline `FABR
|
||||
gets written to the device, real and unstubbed. Blocked only on `WRITE(10)` itself, already
|
||||
modeled in the graph — nothing else stands between this and working.
|
||||
|
||||
- [ ] Implement reading/validating the block-map from a drive on insertion.
|
||||
- [x] **CLOSED 2026-08-27 (`FABRIC-3.md` §F.13) — already built, not a separate item.**
|
||||
`cache_load_devblock()` already unpacks and validates every devblock's metadata on load.
|
||||
Tracing "on insertion" surfaced a real, separate, previously-unflagged conflict instead:
|
||||
`homeblocks_sig_t` and the block-subsystem's own generic `'STFR'`/v2 header both wanted
|
||||
devblock 0, which would leave a home-blocks drive permanently write-refused or overwrite its
|
||||
own identity header. Fixed by relocating `homeblocks_sig_t` to devblock 1; `MINT` must also
|
||||
run the ordinary format-confirm path at devblock 0.
|
||||
|
||||
- [ ] Design the migration state machine (Section U item 5) — states, transition triggers.
|
||||
Session direction, 2026-08-25: **ACL manages *when* to relocate** (capacity pressure, or a
|
||||
@@ -1438,7 +1444,7 @@ graph TD
|
||||
FIRSTTOUCH["❌ First-touch identity→block-range<br/>allocation (M3) — SCOPED 2026-08-27 (§F.11)"]
|
||||
BMAPFMT["❌ On-drive block-map format (M3)<br/>SCOPED 2026-08-27 (§F.4) — repurpose blk_meta_t"]
|
||||
BMAPWRITE["✅ Write block-map to drive (M3)<br/>CLOSED 2026-08-27 (§F.12) — already built, blocked only on W10"]
|
||||
BMAPREAD["❌ Read/validate block-map on insert (M3)"]
|
||||
BMAPREAD["✅ Read/validate block-map on insert (M3)<br/>CLOSED 2026-08-27 (§F.13) — already built"]
|
||||
MIGSM["🟡 Migration state machine (M3)<br/>partially answered: ACL decides *when*"]
|
||||
UNCLEAN["❌ Unclean-removal handling (M3)<br/>DESIGN CLOSED 2026-08-27 (§F.10), code not yet written"]
|
||||
|
||||
@@ -1471,6 +1477,7 @@ graph TD
|
||||
BMAPFMT --> BMAPWRITE
|
||||
BMAPFMT --> BMAPREAD
|
||||
BMAPFMT --> FIRSTTOUCH
|
||||
BMAPREAD -.->|found: sig must relocate off devblock 0, §F.13| MINT
|
||||
|
||||
CERTVERIFY --> RUNCAP
|
||||
RUNCAP --> MINT
|
||||
@@ -1495,8 +1502,8 @@ graph TD
|
||||
classDef unblocked fill:#a83,stroke:#333,color:#fff
|
||||
classDef open fill:#666,stroke:#333,color:#fff
|
||||
classDef partial fill:#883,stroke:#333,color:#fff
|
||||
class M6,PH8,EXPIRE,MSGSHAPE,HOTPLUG,BMAPWRITE done
|
||||
class W10,STALL,FIRSTTOUCH,BMAPREAD,WIREBIND,BINDSTEP,DETACH,MINT,BMAPFMT,CERTVERIFY,RUNCAP,UNCLEAN blocked
|
||||
class M6,PH8,EXPIRE,MSGSHAPE,HOTPLUG,BMAPWRITE,BMAPREAD done
|
||||
class W10,STALL,FIRSTTOUCH,WIREBIND,BINDSTEP,DETACH,MINT,BMAPFMT,CERTVERIFY,RUNCAP,UNCLEAN blocked
|
||||
class ACLKEY,MSGMIGRATE,SSDSCOPE,ROUNDTRIP,POLYBLOCK open
|
||||
class MIGSM partial
|
||||
```
|
||||
@@ -1559,6 +1566,13 @@ finished). Dashed arrows = softer "gates/informs" relationships.
|
||||
`blk_meta_t` accessors instead of a new table meant "write the map" and "write a block" were
|
||||
never actually two operations. The only reason this hasn't been seen working is `WRITE(10)`
|
||||
itself, already the graph's known hub.
|
||||
- **`BMAPREAD` closed the same way, but tracing it surfaced a real, load-bearing bug that had
|
||||
nothing to do with reading at all** (§F.13) — `homeblocks_sig_t` and the block-subsystem's
|
||||
own generic disk header physically collide at devblock 0. Every earlier node that touched
|
||||
`homeblocks_sig_t` (`CERTVERIFY`, `WIREBIND`, `RUNCAP`, `MINT`) inherited this without anyone
|
||||
noticing, because each only traced `homeblocks_sig_check()` itself, never the ordinary attach
|
||||
path running alongside it. Fixed now (relocate to devblock 1) rather than left to surface
|
||||
later as a real, confusing runtime failure.
|
||||
|
||||
**Not yet done:** an ordered plan (which node to attack first, given the graph). Per Captain
|
||||
Bob's own framing, that's the next pass — "start asking and answering questions iteratively
|
||||
@@ -1870,6 +1884,10 @@ resolved before any design decision was needed:
|
||||
cert + identity-source regions; everything past that is the user's own general block-storage
|
||||
pool directly, consistent with `FIRSTTOUCH`'s pool clarification in §F.6). No GPT-parser
|
||||
node needed in the graph at all — this closes that thread rather than deferring it.
|
||||
**Correction, 2026-08-27 (§F.13): `homeblocks_sig_t` itself moved off devblock 0** to
|
||||
devblock 1 (forth-block 4) once a real collision with the block-subsystem's own generic
|
||||
disk header was found — the "devblocks `0..N`" metadata-region framing above still holds,
|
||||
it just now starts one devblock later than stated here.
|
||||
2. **Single-device USB driver.** `xhci_dev_t`'s BOT/MSC state (`device_ctx`, `bulk_in_ring`,
|
||||
`bulk_out_ring`, `bot_data_buf`) are singular fields, not per-slot arrays — only one USB MSC
|
||||
device is usable at a time today. This looked like it might conflict with the vision's
|
||||
@@ -2097,6 +2115,44 @@ node may have its own distinct question (e.g. whether a home-blocks drive needs
|
||||
validate-on-insert step beyond ordinary lazy per-devblock read-through-cache), left for its own
|
||||
pass rather than assumed away.
|
||||
|
||||
### F.13 — `BMAPREAD` (closed — already built) — and a real header collision found and fixed
|
||||
|
||||
Confirmed the handoff note from `F.12`: `cache_load_devblock()` (`block_subsystem.c:308-322`)
|
||||
already unpacks and validates every devblock's metadata on load (`meta_from_slice()`,
|
||||
magic-checked, resets cleanly on a bad/missing magic) — the read side is exactly as "already
|
||||
built, not a separate item" as the write side. Same closure, no new mechanism needed.
|
||||
|
||||
**But tracing "validate on insertion" turned up a real, previously-unflagged conflict that has
|
||||
nothing to do with `blk_meta_t` at all.** `blk_subsys_attach_device()` — the *general* attach
|
||||
path every device goes through, USB drives included — always calls `blk_format_or_load_disk()`
|
||||
(`block_subsystem.c:581-613`), which reads devblock 0 looking for the block-subsystem's own
|
||||
`'STFR'`/v2 volume header. `homeblocks_sig_t`'s magic is `'LAHB'`, not `'STFR'`, so a minted
|
||||
home-blocks drive always reads as "unrecognized" here and lands in `BLK_FMT_PROVISIONAL` —
|
||||
and `blk_get_buffer()` (`block_subsystem.c:894`) **refuses all writes** to a `PROVISIONAL`
|
||||
slot until `blk_subsys_confirm_format()` is called. That function
|
||||
(`blk_commit_format()`, `block_subsystem.c:546-571`) writes a fresh STFR header to the *same*
|
||||
devblock 0 — which would physically overwrite `homeblocks_sig_t`. Neither outcome (stay
|
||||
`PROVISIONAL` forever, or get STFR-formatted and lose the identity header) works. This was
|
||||
invisible to `CERTVERIFY`/`WIREBIND`/`MINT` because each only ever traced
|
||||
`homeblocks_sig_check()` itself, never the generic attach path running alongside it.
|
||||
|
||||
**Decision made 2026-08-27:** `homeblocks_sig_t` relocates to **devblock 1** (forth-block 4),
|
||||
leaving devblock 0 for the generic STFR/v2 header untouched — no changes to the already-tested
|
||||
block-subsystem code. `homeblocks_sig_check()` already takes its starting forth-block as a
|
||||
plain parameter (`sig_start_fblock`, not hardcoded), so this is a call-site change, not a
|
||||
format-logic change. `MINT` (§F.8) must also run the ordinary `blk_subsys_confirm_format()`
|
||||
path at mint time (writing a ordinary fresh STFR/v2 header at devblock 0) so the drive is
|
||||
immediately writable through the normal block-buffer path, in addition to writing
|
||||
`homeblocks_sig_t`/cert/identity-source starting at devblock 1. `F.8`'s own text has been
|
||||
corrected in place to point here rather than restate this.
|
||||
|
||||
**Not yet scoped (deferred within this node):** whether `MINT`'s STFR-format-then-sig-write
|
||||
sequence needs a specific ordering/atomicity guarantee (e.g. what state a drive is left in if
|
||||
power is lost between the two writes) — real question, not addressed here; the exact
|
||||
`sig_start_fblock` value call sites (`CERTVERIFY`, `WIREBIND`, `RUNCAP`, `MINT`) all need
|
||||
updating from their currently-recorded devblock-0-relative assumption to devblock-1, a
|
||||
mechanical follow-up once any of this is actually coded, not re-litigated here.
|
||||
|
||||
### D.5 — Scope expansion (2026-08-27): identity is common to every VM, not just users
|
||||
|
||||
Surfaced while scoping `ACLKEY`, stated directly: *"the whole object is to deliver a
|
||||
|
||||
Reference in New Issue
Block a user