#[derive(Clone, Copy, PartialEq, Eq)] #[allow(dead_code)] pub enum BlockError { NoDevice, Io, Unsupported, Invalid, } pub trait BlockDevice { fn sector_size(&self) -> usize { 512 } fn read_sector(&mut self, lba: u64, buffer: &mut [u8]) -> Result<(), BlockError>; fn write_sector(&mut self, _lba: u64, _buffer: &[u8]) -> Result<(), BlockError> { Err(BlockError::Unsupported) } fn read_at(&mut self, offset: u64, buffer: &mut [u8]) -> Result<(), BlockError> { let sector_size = self.sector_size(); if sector_size == 0 { return Err(BlockError::Invalid); } let mut done = 0; let mut scratch = [0u8; 512]; while done < buffer.len() { let absolute = offset + done as u64; let lba = absolute / sector_size as u64; let sector_offset = (absolute % sector_size as u64) as usize; self.read_sector(lba, &mut scratch)?; let chunk = (sector_size - sector_offset).min(buffer.len() - done); buffer[done..done + chunk] .copy_from_slice(&scratch[sector_offset..sector_offset + chunk]); done += chunk; } Ok(()) } fn write_at(&mut self, offset: u64, buffer: &[u8]) -> Result<(), BlockError> { let sector_size = self.sector_size(); if sector_size == 0 { return Err(BlockError::Invalid); } let mut done = 0; let mut scratch = [0u8; 512]; while done < buffer.len() { let absolute = offset + done as u64; let lba = absolute / sector_size as u64; let sector_offset = (absolute % sector_size as u64) as usize; self.read_sector(lba, &mut scratch)?; let chunk = (sector_size - sector_offset).min(buffer.len() - done); scratch[sector_offset..sector_offset + chunk] .copy_from_slice(&buffer[done..done + chunk]); self.write_sector(lba, &scratch)?; done += chunk; } Ok(()) } }