1use alloc::sync::Arc;
18
19use ax_driver::prelude::*;
20use spin::Mutex;
21
22const BLOCK_SIZE: usize = 512;
23
24#[derive(Clone)]
26pub struct Disk {
27 block_id: u64,
28 offset: usize,
29 dev: Arc<Mutex<AxBlockDevice>>,
30}
31
32impl Disk {
33 pub fn new(dev: AxBlockDevice) -> Self {
35 assert_eq!(BLOCK_SIZE, dev.block_size());
36 Self {
37 block_id: 0,
38 offset: 0,
39 dev: Arc::new(Mutex::new(dev)),
40 }
41 }
42
43 pub fn size(&self) -> u64 {
45 let dev = self.dev.lock();
46 dev.num_blocks() * BLOCK_SIZE as u64
47 }
48
49 pub fn position(&self) -> u64 {
51 self.block_id * BLOCK_SIZE as u64 + self.offset as u64
52 }
53
54 pub fn set_position(&mut self, pos: u64) {
56 self.block_id = pos / BLOCK_SIZE as u64;
57 self.offset = pos as usize % BLOCK_SIZE;
58 }
59
60 pub fn read_one(&mut self, buf: &mut [u8]) -> DevResult<usize> {
62 let read_size = if self.offset == 0 && buf.len() >= BLOCK_SIZE {
63 let mut dev = self.dev.lock();
65 dev.read_block(self.block_id, &mut buf[0..BLOCK_SIZE])?;
66 self.block_id += 1;
67 BLOCK_SIZE
68 } else {
69 let mut data = [0u8; BLOCK_SIZE];
71 let start = self.offset;
72 let count = buf.len().min(BLOCK_SIZE - self.offset);
73
74 {
75 let mut dev = self.dev.lock();
76 dev.read_block(self.block_id, &mut data)?;
77 }
78 buf[..count].copy_from_slice(&data[start..start + count]);
79 self.offset += count;
80 if self.offset >= BLOCK_SIZE {
81 self.block_id += 1;
82 self.offset -= BLOCK_SIZE;
83 }
84 count
85 };
86 Ok(read_size)
87 }
88
89 pub fn write_one(&mut self, buf: &[u8]) -> DevResult<usize> {
91 let write_size = if self.offset == 0 && buf.len() >= BLOCK_SIZE {
92 let mut dev = self.dev.lock();
94 dev.write_block(self.block_id, &buf[0..BLOCK_SIZE])?;
95 self.block_id += 1;
96 BLOCK_SIZE
97 } else {
98 let mut data = [0u8; BLOCK_SIZE];
100 let start = self.offset;
101 let count = buf.len().min(BLOCK_SIZE - self.offset);
102
103 let mut dev = self.dev.lock();
104 dev.read_block(self.block_id, &mut data)?;
105 data[start..start + count].copy_from_slice(&buf[..count]);
106 dev.write_block(self.block_id, &data)?;
107
108 self.offset += count;
109 if self.offset >= BLOCK_SIZE {
110 self.block_id += 1;
111 self.offset -= BLOCK_SIZE;
112 }
113 count
114 };
115 Ok(write_size)
116 }
117}
118
119pub struct Partition {
121 disk: Arc<Mutex<Disk>>,
122 start_lba: u64,
123 end_lba: u64,
124 position: u64,
125}
126
127impl Partition {
128 pub fn new(disk: Disk, start_lba: u64, end_lba: u64) -> Self {
130 Self {
131 disk: Arc::new(Mutex::new(disk)),
132 start_lba,
133 end_lba,
134 position: 0,
135 }
136 }
137
138 pub fn size(&self) -> u64 {
140 (self.end_lba - self.start_lba + 1) * BLOCK_SIZE as u64
141 }
142
143 pub fn position(&self) -> u64 {
145 self.position
146 }
147
148 pub fn set_position(&mut self, pos: u64) {
150 self.position = pos.min(self.size());
151 }
152
153 pub fn read_one(&mut self, buf: &mut [u8]) -> DevResult<usize> {
155 if self.position >= self.size() {
156 return Ok(0);
157 }
158
159 let remaining = self.size() - self.position;
160 let to_read = buf.len().min(remaining as usize);
161 let buf = &mut buf[..to_read];
162
163 let abs_pos = self.start_lba * BLOCK_SIZE as u64 + self.position;
165
166 let read_len = {
168 let mut disk = self.disk.lock();
169 disk.set_position(abs_pos);
170 disk.read_one(buf)?
171 };
172
173 self.position += read_len as u64;
174 Ok(read_len)
175 }
176
177 pub fn write_one(&mut self, buf: &[u8]) -> DevResult<usize> {
179 if self.position >= self.size() {
180 return Ok(0);
181 }
182
183 let remaining = self.size() - self.position;
184 let to_write = buf.len().min(remaining as usize);
185 let buf = &buf[..to_write];
186
187 let abs_pos = self.start_lba * BLOCK_SIZE as u64 + self.position;
189
190 let write_len = {
192 let mut disk = self.disk.lock();
193 disk.set_position(abs_pos);
194 disk.write_one(buf)?
195 };
196
197 self.position += write_len as u64;
198 Ok(write_len)
199 }
200}