mirror of
https://github.com/ZeroOSProject/ZeroOS.git
synced 2026-09-13 00:24:41 +08:00
68 lines
2.0 KiB
Rust
68 lines
2.0 KiB
Rust
#[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(())
|
|
}
|
|
}
|