Skip to main content

ahrightos_fs/
block_dev.rs

1use crate::file::FileError;
2use alloc::sync::Arc;
3use alloc::vec::Vec;
4use spin::Mutex;
5
6pub const BLOCK_SIZE: usize = 512;
7
8pub trait BlockDevice: Send + Sync {
9    fn read_block(&self, block_no: usize, buf: &mut [u8]) -> Result<(), FileError>;
10    fn write_block(&self, block_no: usize, buf: &[u8]) -> Result<(), FileError>;
11    fn block_count(&self) -> usize;
12    fn flush(&self) -> Result<(), FileError> {
13        Ok(())
14    }
15}
16
17pub struct DummyBlockDev {
18    data: Mutex<Vec<u8>>,
19    blocks: usize,
20}
21
22impl DummyBlockDev {
23    pub fn new(blocks: usize) -> Self {
24        Self {
25            data: Mutex::new(alloc::vec![0u8; blocks * BLOCK_SIZE]),
26            blocks,
27        }
28    }
29}
30
31impl BlockDevice for DummyBlockDev {
32    fn read_block(&self, block_no: usize, buf: &mut [u8]) -> Result<(), FileError> {
33        if block_no >= self.blocks || buf.len() != BLOCK_SIZE {
34            return Err(FileError::InvalidOperation);
35        }
36        let start = block_no * BLOCK_SIZE;
37        let data = self.data.lock();
38        buf.copy_from_slice(&data[start..start + BLOCK_SIZE]);
39        Ok(())
40    }
41
42    fn write_block(&self, block_no: usize, buf: &[u8]) -> Result<(), FileError> {
43        if block_no >= self.blocks || buf.len() != BLOCK_SIZE {
44            return Err(FileError::InvalidOperation);
45        }
46        let start = block_no * BLOCK_SIZE;
47        let mut data = self.data.lock();
48        data[start..start + BLOCK_SIZE].copy_from_slice(buf);
49        Ok(())
50    }
51
52    fn block_count(&self) -> usize {
53        self.blocks
54    }
55}
56
57pub type BlockDeviceHandle = Arc<dyn BlockDevice>;