Phase 8 C (4/n): metadata fence allocator integration + zone I/O
Corrected meta_fence_blocks units from "Forth 1 KiB blocks" to 4 KiB devblocks (matching bam_devblocks/reloc_devblocks) before anything depended on the original meaning -- a clean fix, not a migration. This let the fence fold directly into compute_totals_from_B()'s existing payload4k formula (total_devblocks - 1 - B - R - F) instead of a separate user_blocks subtraction: total_blocks/user_blocks/free_blocks all shrink correctly for free, in both the fresh-format and reload paths, from one formula change. New blk_meta_zone_read()/blk_meta_zone_write() -- raw, unpacked 4 KiB devblock I/O, same shape as the header/BAM/reloc-table regions, addressed by devblock_from_top counting down from the device's last physical devblock. Refuses rather than clamps if the index exceeds the on-disk meta_fence_blocks. C-only, no FORTH word wraps either -- same discipline as vm_zuse_cert_install(), which will be this zone's first real tenant. Verified independently at every step, never trusting the kernel's own report: capacity math cross-checked against a from-scratch Python recomputation of the same formula (exact match); accessor correctness via a temporary probe (written/run/captured/reverted) that wrote a known pattern and read it back, then independently confirmed via a raw read of the disk image at the exact expected physical byte offset. Full 3-arch acceptance boot against the real, untouched disk/artemis.img, probe code fully reverted -- clean, conservation intact. Still open: wiring vm_zuse_cert_install() to actually persist through these accessors, and the MINT word itself. Documented in FABRIC-3.md. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01U14ET9CWAtbQMbYqomKgXd
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
2035ebeac0
commit
6e9c1d3bc2
+44
-1
@@ -362,8 +362,9 @@ static uint32_t choose_B(uint64_t total_devblocks_4k) {
|
||||
static void compute_totals_from_B(blk_volume_meta_t *m) {
|
||||
uint64_t B = m->bam_devblocks;
|
||||
uint64_t R = m->reloc_devblocks; /* reserved relocation-table region, see blk_volume_meta_t's own doc comment */
|
||||
uint64_t F = m->meta_fence_blocks; /* top-of-device system-metadata fence, see blk_volume_meta_t's own doc comment */
|
||||
m->tracked_blocks = 32768ULL * B;
|
||||
uint64_t payload4k = (m->total_devblocks > (1+B+R)) ? (m->total_devblocks - 1 - B - R) : 0;
|
||||
uint64_t payload4k = (m->total_devblocks > (1+B+R+F)) ? (m->total_devblocks - 1 - B - R - F) : 0;
|
||||
uint64_t storable = 3ULL * payload4k;
|
||||
m->total_blocks = (m->tracked_blocks < storable) ? m->tracked_blocks : storable;
|
||||
uint64_t reserved = (uint64_t) BLK_DISK_SYS_RESERVED;
|
||||
@@ -1117,6 +1118,48 @@ int blk_set_volume_meta(const blk_volume_meta_t *meta) {
|
||||
return BLK_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Top-of-device system-metadata fence I/O (Phase 8, 2026-08-26).
|
||||
* Raw, unpacked 4 KiB devblocks -- no Forth-block packing, same shape as
|
||||
* the header/BAM/reloc-table regions. devblock_from_top counts down from
|
||||
* the very last physical devblock of the canonical device (0 = last,
|
||||
* 1 = second-to-last, ...); must be < the on-disk meta_fence_blocks or
|
||||
* this refuses rather than silently reading/writing outside the
|
||||
* reservation. Operates on the same "canonical device" first_disk_slot()
|
||||
* already establishes for blk_get_volume_meta()/the relocation table.
|
||||
* No FORTH word wraps this -- C-only, same discipline as
|
||||
* vm_zuse_cert_install() itself; Zuse's cert is this zone's first tenant.
|
||||
*/
|
||||
int blk_meta_zone_read(uint32_t devblock_from_top, uint8_t buf[4096]) {
|
||||
if (!buf) return BLK_EINVAL;
|
||||
blk_dev_slot_t *slot = first_disk_slot();
|
||||
if (!slot || !slot->dev) return BLK_ENODEV;
|
||||
if (devblock_from_top >= slot->vol_meta.meta_fence_blocks) return BLK_EINVAL;
|
||||
|
||||
uint64_t devblock_idx = slot->vol_meta.total_devblocks - 1ULL - devblock_from_top;
|
||||
uint32_t base1k = (uint32_t) devblock_idx * 4u;
|
||||
for (uint32_t k = 0; k < 4; k++) {
|
||||
if (blkio_read(slot->dev, base1k + k, buf + k * 1024u) != BLKIO_OK)
|
||||
return BLK_EIO;
|
||||
}
|
||||
return BLK_OK;
|
||||
}
|
||||
|
||||
int blk_meta_zone_write(uint32_t devblock_from_top, const uint8_t buf[4096]) {
|
||||
if (!buf) return BLK_EINVAL;
|
||||
blk_dev_slot_t *slot = first_disk_slot();
|
||||
if (!slot || !slot->dev) return BLK_ENODEV;
|
||||
if (devblock_from_top >= slot->vol_meta.meta_fence_blocks) return BLK_EINVAL;
|
||||
|
||||
uint64_t devblock_idx = slot->vol_meta.total_devblocks - 1ULL - devblock_from_top;
|
||||
uint32_t base1k = (uint32_t) devblock_idx * 4u;
|
||||
for (uint32_t k = 0; k < 4; k++) {
|
||||
if (blkio_write(slot->dev, base1k + k, buf + k * 1024u) != BLKIO_OK)
|
||||
return BLK_EIO;
|
||||
}
|
||||
return BLK_OK;
|
||||
}
|
||||
|
||||
int blk_is_valid(uint32_t block_num) {
|
||||
if (!g.initialized) return 0;
|
||||
block_num = resolve_lbn(block_num);
|
||||
|
||||
Reference in New Issue
Block a user