os/device/block/
ram_disk.rs1use super::super::{DeviceType, Driver};
2use super::BlockDriver;
3use crate::sync::SpinLock;
4use alloc::string::String;
5use alloc::sync::Arc;
6use alloc::vec;
7use alloc::vec::Vec;
8
9pub struct RamDisk {
13 data: SpinLock<Vec<u8>>,
15
16 block_size: usize,
18
19 device_id: usize,
21}
22
23impl RamDisk {
24 pub fn new(size: usize, block_size: usize, device_id: usize) -> Arc<Self> {
26 Arc::new(Self {
27 data: SpinLock::new(vec![0u8; size]),
28 block_size,
29 device_id,
30 })
31 }
32
33 pub fn from_bytes(data: Vec<u8>, block_size: usize, device_id: usize) -> Arc<Self> {
35 Arc::new(Self {
36 data: SpinLock::new(data),
37 block_size,
38 device_id,
39 })
40 }
41
42 pub fn raw_data(&self) -> Vec<u8> {
44 self.data.lock().clone()
45 }
46
47 pub fn device_id(&self) -> usize {
49 self.device_id
50 }
51}
52
53impl Driver for RamDisk {
54 fn try_handle_interrupt(&self, _irq: Option<usize>) -> bool {
55 false }
57
58 fn device_type(&self) -> DeviceType {
59 DeviceType::Block
60 }
61
62 fn get_id(&self) -> String {
63 alloc::format!("ramdisk_{}", self.device_id)
64 }
65
66 fn as_block(&self) -> Option<&dyn BlockDriver> {
67 Some(self)
68 }
69}
70
71impl BlockDriver for RamDisk {
73 fn read_block(&self, block_id: usize, buf: &mut [u8]) -> bool {
74 if buf.len() != self.block_size {
75 return false;
76 }
77
78 let data = self.data.lock();
79 let offset = block_id * self.block_size;
80
81 if offset + self.block_size > data.len() {
82 return false;
83 }
84
85 buf.copy_from_slice(&data[offset..offset + self.block_size]);
86 true
87 }
88
89 fn write_block(&self, block_id: usize, buf: &[u8]) -> bool {
90 if buf.len() != self.block_size {
91 return false;
92 }
93
94 let mut data = self.data.lock();
95 let offset = block_id * self.block_size;
96
97 if offset + self.block_size > data.len() {
98 return false;
99 }
100
101 data[offset..offset + self.block_size].copy_from_slice(buf);
102 true
103 }
104
105 fn flush(&self) -> bool {
106 true }
108
109 fn block_size(&self) -> usize {
110 self.block_size
111 }
112
113 fn total_blocks(&self) -> usize {
114 self.data.lock().len() / self.block_size
115 }
116}