feat(storage): ext4-only disk via mkfs.ext4 -d; drop FAT16; feature-gated mount (ro on unknown ro_compat); ext4 read spans blocks, delete clears inode, mkdir counts dir; virtio-blk writes; test-qemu e2fsck gate

This commit is contained in:
2026-10-27 17:09:35 +01:00
parent 4030dd4315
commit 0fd568cdad
24 changed files with 390 additions and 809 deletions

View File

@@ -60,3 +60,37 @@ pub fn read_sector(
true
}
/// Request types (virtio spec 5.2.6).
const T_OUT: u32 = 1;
/// Device configuration: the disk's size in 512-byte sectors (le64).
pub const CONFIG_CAPACITY: usize = 0x100;
/// Writes one sector from `buf`; true once the device reports success.
pub fn write_sector(
mmio: &impl MmioAccess,
queue: &VirtioQueue,
dma: &DmaAddrs,
sector: u32,
buf: &[u8],
) -> bool {
if buf.len() < SECTOR_SIZE { return false; }
unsafe {
core::ptr::copy_nonoverlapping(buf.as_ptr(), dma.data_va.raw() as *mut u8, SECTOR_SIZE);
let hdr = dma.header_va.raw() as *mut BlockReqHeader;
core::ptr::write_volatile(&raw mut (*hdr).req_type, T_OUT);
core::ptr::write_volatile(&raw mut (*hdr).reserved, 0);
core::ptr::write_volatile(&raw mut (*hdr).sector, sector as u64);
core::ptr::write_volatile(dma.status_va.raw() as *mut u8, 0xFF);
}
// The device reads the data this time; only the status is written back.
let descs = [
Descriptor { addr: dma.header_pa.raw() as u64, len: 16, writable: false },
Descriptor { addr: dma.data_pa.raw() as u64, len: SECTOR_SIZE as u32, writable: false },
Descriptor { addr: dma.status_pa.raw() as u64, len: 1, writable: true },
];
if !queue.submit(mmio, &descs) { return false; }
unsafe { core::ptr::read_volatile(dma.status_va.raw() as *const u8) == 0 }
}