use crate::file::FileError;
use alloc::sync::Arc;
use alloc::vec::Vec;
use spin::Mutex;
pub const BLOCK_SIZE: usize = 512;
pub trait BlockDevice: Send + Sync {
fn read_block(&self, block_no: usize, buf: &mut [u8]) -> Result<(), FileError>;
fn write_block(&self, block_no: usize, buf: &[u8]) -> Result<(), FileError>;
fn block_count(&self) -> usize;
fn flush(&self) -> Result<(), FileError> {
Ok(())
}
}
pub struct DummyBlockDev {
data: Mutex<Vec<u8>>,
blocks: usize,
}
impl DummyBlockDev {
pub fn new(blocks: usize) -> Self {
Self {
data: Mutex::new(alloc::vec![0u8; blocks * BLOCK_SIZE]),
blocks,
}
}
}
impl BlockDevice for DummyBlockDev {
fn read_block(&self, block_no: usize, buf: &mut [u8]) -> Result<(), FileError> {
if block_no >= self.blocks || buf.len() != BLOCK_SIZE {
return Err(FileError::InvalidOperation);
}
let start = block_no * BLOCK_SIZE;
let data = self.data.lock();
buf.copy_from_slice(&data[start..start + BLOCK_SIZE]);
Ok(())
}
fn write_block(&self, block_no: usize, buf: &[u8]) -> Result<(), FileError> {
if block_no >= self.blocks || buf.len() != BLOCK_SIZE {
return Err(FileError::InvalidOperation);
}
let start = block_no * BLOCK_SIZE;
let mut data = self.data.lock();
data[start..start + BLOCK_SIZE].copy_from_slice(buf);
Ok(())
}
fn block_count(&self) -> usize {
self.blocks
}
}
pub type BlockDeviceHandle = Arc<dyn BlockDevice>;