xref: /DragonOS/kernel/src/driver/base/block/block_device.rs (revision eb49bb993a39964f92494ec3effafed3fb9adfd8)
1b087521eSChiichen /// 引入Module
2ae5ede03SLoGin use crate::{
3*eb49bb99S曾俊     driver::{
4*eb49bb99S曾俊         base::{
5c566df45SLoGin             device::{
6c566df45SLoGin                 device_number::{DeviceNumber, Major},
7c566df45SLoGin                 Device, DeviceError, IdTable, BLOCKDEVS,
8c566df45SLoGin             },
9ae5ede03SLoGin             map::{
10ae5ede03SLoGin                 DeviceStruct, DEV_MAJOR_DYN_END, DEV_MAJOR_DYN_EXT_END, DEV_MAJOR_DYN_EXT_START,
11c566df45SLoGin                 DEV_MAJOR_HASH_SIZE, DEV_MAJOR_MAX,
12ae5ede03SLoGin             },
13ae5ede03SLoGin         },
14*eb49bb99S曾俊         block::cache::{cached_block_device::BlockCache, BlockCacheError, BLOCK_SIZE},
15*eb49bb99S曾俊     },
16ae5ede03SLoGin     kerror,
17ae5ede03SLoGin };
1891e9d4abSLoGin 
19b087521eSChiichen use alloc::{sync::Arc, vec::Vec};
20b087521eSChiichen use core::any::Any;
2191e9d4abSLoGin use system_error::SystemError;
22b087521eSChiichen 
23b087521eSChiichen use super::disk_info::Partition;
24b087521eSChiichen 
25b087521eSChiichen /// 该文件定义了 Device 和 BlockDevice 的接口
26b087521eSChiichen /// Notice 设备错误码使用 Posix 规定的 int32_t 的错误码表示,而不是自己定义错误enum
27b087521eSChiichen 
28b087521eSChiichen // 使用方法:
29b087521eSChiichen // 假设 blk_dev 是块设备
30b087521eSChiichen // <blk_dev as Device>::read_at() 调用的是Device的函数
31b087521eSChiichen // <blk_dev as BlockDevice>::read_at() 调用的是BlockDevice的函数
32b087521eSChiichen 
33b087521eSChiichen /// 定义类型
34b087521eSChiichen pub type BlockId = usize;
35b087521eSChiichen 
36b087521eSChiichen /// 定义常量
37b087521eSChiichen pub const BLK_SIZE_LOG2_LIMIT: u8 = 12; // 设定块设备的块大小不能超过 1 << 12.
38b087521eSChiichen /// 在DragonOS中,我们认为磁盘的每个LBA大小均为512字节。(注意,文件系统的1个扇区可能事实上是多个LBA)
39b087521eSChiichen pub const LBA_SIZE: usize = 512;
40b087521eSChiichen 
41b087521eSChiichen /// @brief 块设备的迭代器
42b087521eSChiichen /// @usage 某次操作读/写块设备的[L,R]范围内的字节,
43b087521eSChiichen ///        那么可以使用此结构体进行迭代遍历,每次调用next()返回一个BlockRange
44b087521eSChiichen pub struct BlockIter {
45b087521eSChiichen     pub begin: usize, // 迭代器的起始位置 -> 块设备的地址 (单位是字节)
46b087521eSChiichen     pub end: usize,
47b087521eSChiichen     pub blk_size_log2: u8,
48b087521eSChiichen     pub multiblock: bool, // 是否启用连续整块同时遍历
49b087521eSChiichen }
50b087521eSChiichen 
51b087521eSChiichen /// @brief Range搭配迭代器BlockIter使用,[L,R]区间被分割成多个小的Range
52b087521eSChiichen ///        Range要么是整块,要么是一块的某一部分
53b087521eSChiichen /// 细节: range = [begin, end) 左闭右开
54b087521eSChiichen pub struct BlockRange {
55b087521eSChiichen     pub lba_start: usize, // 起始块的lba_id
56b087521eSChiichen     pub lba_end: usize,   // 终止块的lba_id
57b087521eSChiichen     pub begin: usize, // 起始位置在块内的偏移量, 如果BlockIter启用Multiblock,则是多个块的偏移量
58b087521eSChiichen     pub end: usize,   // 结束位置在块内的偏移量,单位是字节
59b087521eSChiichen     pub blk_size_log2: u8,
60b087521eSChiichen }
61b087521eSChiichen 
62b087521eSChiichen impl BlockIter {
63b087521eSChiichen     #[allow(dead_code)]
64b087521eSChiichen     pub fn new(start_addr: usize, end_addr: usize, blk_size_log2: u8) -> BlockIter {
65b087521eSChiichen         return BlockIter {
66b087521eSChiichen             begin: start_addr,
67b087521eSChiichen             end: end_addr,
68b5b571e0SLoGin             blk_size_log2,
69b087521eSChiichen             multiblock: false,
70b087521eSChiichen         };
71b087521eSChiichen     }
72b087521eSChiichen     pub fn new_multiblock(start_addr: usize, end_addr: usize, blk_size_log2: u8) -> BlockIter {
73b087521eSChiichen         return BlockIter {
74b087521eSChiichen             begin: start_addr,
75b087521eSChiichen             end: end_addr,
76b5b571e0SLoGin 
77b5b571e0SLoGin             blk_size_log2,
78b087521eSChiichen             multiblock: true,
79b087521eSChiichen         };
80b087521eSChiichen     }
81b087521eSChiichen 
82b087521eSChiichen     /// 获取下一个整块或者不完整的块
83b087521eSChiichen     pub fn next_block(&mut self) -> BlockRange {
84b087521eSChiichen         let blk_size_log2 = self.blk_size_log2;
85b087521eSChiichen         let blk_size = 1usize << self.blk_size_log2;
86b087521eSChiichen         let lba_id = self.begin / blk_size;
87b087521eSChiichen         let begin = self.begin % blk_size;
88b087521eSChiichen         let end = if lba_id == self.end / blk_size {
89b087521eSChiichen             self.end % blk_size
90b087521eSChiichen         } else {
91b087521eSChiichen             blk_size
92b087521eSChiichen         };
93b087521eSChiichen 
94b087521eSChiichen         self.begin += end - begin;
95b087521eSChiichen 
96b087521eSChiichen         return BlockRange {
97b087521eSChiichen             lba_start: lba_id,
98b087521eSChiichen             lba_end: lba_id + 1,
99b5b571e0SLoGin             begin,
100b5b571e0SLoGin             end,
101b5b571e0SLoGin             blk_size_log2,
102b087521eSChiichen         };
103b087521eSChiichen     }
104b087521eSChiichen 
105b087521eSChiichen     /// 如果能返回多个连续的整块,则返回;否则调用next_block()返回不完整的块
106b087521eSChiichen     pub fn next_multiblock(&mut self) -> BlockRange {
107b087521eSChiichen         let blk_size_log2 = self.blk_size_log2;
108b087521eSChiichen         let blk_size = 1usize << self.blk_size_log2;
109b087521eSChiichen         let lba_start = self.begin / blk_size;
110b087521eSChiichen         let lba_end = self.end / blk_size;
111b087521eSChiichen 
112b087521eSChiichen         // 如果不是整块,先返回非整块的小部分
113b087521eSChiichen         if __bytes_to_lba(self.begin, blk_size)
114b087521eSChiichen             != __bytes_to_lba(self.begin + blk_size - 1, blk_size)
115b087521eSChiichen             || lba_start == lba_end
116b087521eSChiichen         {
117b087521eSChiichen             return self.next_block();
118b087521eSChiichen         }
119b087521eSChiichen 
120b087521eSChiichen         let begin = self.begin % blk_size; // 因为是多个整块,这里必然是0
121b087521eSChiichen         let end = __lba_to_bytes(lba_end, blk_size) - self.begin;
122b087521eSChiichen 
123b087521eSChiichen         self.begin += end - begin;
124b087521eSChiichen 
125b087521eSChiichen         return BlockRange {
126b5b571e0SLoGin             lba_start,
127b5b571e0SLoGin             lba_end,
128b5b571e0SLoGin             begin,
129b5b571e0SLoGin             end,
130b5b571e0SLoGin             blk_size_log2,
131b087521eSChiichen         };
132b087521eSChiichen     }
133b087521eSChiichen }
134b087521eSChiichen 
135b087521eSChiichen /// BlockIter 函数实现
136b087521eSChiichen impl Iterator for BlockIter {
137b087521eSChiichen     type Item = BlockRange;
138b087521eSChiichen 
139b087521eSChiichen     fn next(&mut self) -> Option<<Self as Iterator>::Item> {
140b087521eSChiichen         if self.begin >= self.end {
141b087521eSChiichen             return None;
142b087521eSChiichen         }
143b087521eSChiichen         if self.multiblock {
144b087521eSChiichen             return Some(self.next_multiblock());
145b087521eSChiichen         } else {
146b087521eSChiichen             return Some(self.next_block());
147b087521eSChiichen         }
148b087521eSChiichen     }
149b087521eSChiichen }
150b087521eSChiichen 
151b087521eSChiichen /// BlockRange 函数实现
152b087521eSChiichen impl BlockRange {
153b087521eSChiichen     #[allow(dead_code)]
154b087521eSChiichen     pub fn is_empty(&self) -> bool {
155b087521eSChiichen         return self.end == self.begin;
156b087521eSChiichen     }
157b087521eSChiichen     pub fn len(&self) -> usize {
158b087521eSChiichen         return self.end - self.begin;
159b087521eSChiichen     }
160b087521eSChiichen     /// 判断是不是整块
161b087521eSChiichen     pub fn is_full(&self) -> bool {
162b087521eSChiichen         return self.len() == (1usize << self.blk_size_log2);
163b087521eSChiichen     }
164b087521eSChiichen     /// 判断是不是多个整块连在一起
165b087521eSChiichen     pub fn is_multi(&self) -> bool {
166b087521eSChiichen         return self.len() >= (1usize << self.blk_size_log2)
167b087521eSChiichen             && (self.len() % (1usize << self.blk_size_log2) == 0);
168b087521eSChiichen     }
169b087521eSChiichen     /// 获取 BlockRange 在块设备内部的起始位置 (单位是字节)
170b087521eSChiichen     pub fn origin_begin(&self) -> usize {
171b087521eSChiichen         return (self.lba_start << self.blk_size_log2) + self.begin;
172b087521eSChiichen     }
173b087521eSChiichen     /// 获取 BlockRange 在块设备内部的结尾位置 (单位是字节)
174b087521eSChiichen     pub fn origin_end(&self) -> usize {
175b087521eSChiichen         return (self.lba_start << self.blk_size_log2) + self.end;
176b087521eSChiichen     }
177b087521eSChiichen }
178b087521eSChiichen 
179b087521eSChiichen /// 从字节地址转换到lba id
180b087521eSChiichen #[inline]
181b087521eSChiichen pub fn __bytes_to_lba(addr: usize, blk_size: usize) -> BlockId {
182b087521eSChiichen     return addr / blk_size;
183b087521eSChiichen }
184b087521eSChiichen 
185b087521eSChiichen /// 从lba id转换到字节地址, 返回lba_id的最左侧字节
186b087521eSChiichen #[inline]
187b087521eSChiichen pub fn __lba_to_bytes(lba_id: usize, blk_size: usize) -> BlockId {
188b087521eSChiichen     return lba_id * blk_size;
189b087521eSChiichen }
190b087521eSChiichen 
191b087521eSChiichen /// @brief 块设备应该实现的操作
192b087521eSChiichen pub trait BlockDevice: Device {
193b087521eSChiichen     /// @brief: 在块设备中,从第lba_id_start个块开始,读取count个块数据,存放到buf中
194b087521eSChiichen     ///
195b087521eSChiichen     /// @parameter lba_id_start: 起始块
196b087521eSChiichen     /// @parameter count: 读取块的数量
197b087521eSChiichen     /// @parameter buf: 目标数组
198b087521eSChiichen     /// @return: 如果操作成功,返回 Ok(操作的长度) 其中单位是字节;
199b087521eSChiichen     ///          否则返回Err(错误码),其中错误码为负数;
200b087521eSChiichen     ///          如果操作异常,但是并没有检查出什么错误,将返回Err(已操作的长度)
201*eb49bb99S曾俊     fn read_at_sync(
202b087521eSChiichen         &self,
203b087521eSChiichen         lba_id_start: BlockId,
204b087521eSChiichen         count: usize,
205b087521eSChiichen         buf: &mut [u8],
206b087521eSChiichen     ) -> Result<usize, SystemError>;
207b087521eSChiichen 
208b087521eSChiichen     /// @brief: 在块设备中,从第lba_id_start个块开始,把buf中的count个块数据,存放到设备中
209b087521eSChiichen     /// @parameter lba_id_start: 起始块
210b087521eSChiichen     /// @parameter count: 写入块的数量
211b087521eSChiichen     /// @parameter buf: 目标数组
212b087521eSChiichen     /// @return: 如果操作成功,返回 Ok(操作的长度) 其中单位是字节;
213b087521eSChiichen     ///          否则返回Err(错误码),其中错误码为负数;
214b087521eSChiichen     ///          如果操作异常,但是并没有检查出什么错误,将返回Err(已操作的长度)
215*eb49bb99S曾俊     fn write_at_sync(
216b087521eSChiichen         &self,
217b087521eSChiichen         lba_id_start: BlockId,
218b087521eSChiichen         count: usize,
219b087521eSChiichen         buf: &[u8],
220b087521eSChiichen     ) -> Result<usize, SystemError>;
221b087521eSChiichen 
222b087521eSChiichen     /// @brief: 同步磁盘信息,把所有的dirty数据写回硬盘 - 待实现
223b087521eSChiichen     fn sync(&self) -> Result<(), SystemError>;
224b087521eSChiichen 
225b087521eSChiichen     /// @brief: 每个块设备都必须固定自己块大小,而且该块大小必须是2的幂次
226b087521eSChiichen     /// @return: 返回一个固定量,硬编码(编程的时候固定的常量).
227b087521eSChiichen     fn blk_size_log2(&self) -> u8;
228b087521eSChiichen 
229b087521eSChiichen     // TODO: 待实现 open, close
230b087521eSChiichen 
231b087521eSChiichen     /// @brief 本函数用于实现动态转换。
232b087521eSChiichen     /// 具体的文件系统在实现本函数时,最简单的方式就是:直接返回self
233b087521eSChiichen     fn as_any_ref(&self) -> &dyn Any;
234b087521eSChiichen 
235b087521eSChiichen     /// @brief 本函数用于将BlockDevice转换为Device。
236b087521eSChiichen     /// 由于实现了BlockDevice的结构体,本身也实现了Device Trait, 因此转换是可能的。
237b087521eSChiichen     /// 思路:在BlockDevice的结构体中新增一个self_ref变量,返回self_ref.upgrade()即可。
238b087521eSChiichen     fn device(&self) -> Arc<dyn Device>;
239b087521eSChiichen 
240b087521eSChiichen     /// @brief 返回块设备的块大小(单位:字节)
241b087521eSChiichen     fn block_size(&self) -> usize;
242b087521eSChiichen 
243b087521eSChiichen     /// @brief 返回当前磁盘上的所有分区的Arc指针数组
244b087521eSChiichen     fn partitions(&self) -> Vec<Arc<Partition>>;
245b087521eSChiichen 
246*eb49bb99S曾俊     /// # 函数的功能
247*eb49bb99S曾俊     /// 经由Cache对块设备的读操作
248*eb49bb99S曾俊     fn read_at(
249*eb49bb99S曾俊         &self,
250*eb49bb99S曾俊         lba_id_start: BlockId,
251*eb49bb99S曾俊         count: usize,
252*eb49bb99S曾俊         buf: &mut [u8],
253*eb49bb99S曾俊     ) -> Result<usize, SystemError> {
254*eb49bb99S曾俊         self.cache_read(lba_id_start, count, buf)
255*eb49bb99S曾俊     }
256*eb49bb99S曾俊 
257*eb49bb99S曾俊     /// # 函数的功能
258*eb49bb99S曾俊     ///  经由Cache对块设备的写操作
259*eb49bb99S曾俊     fn write_at(
260*eb49bb99S曾俊         &self,
261*eb49bb99S曾俊         lba_id_start: BlockId,
262*eb49bb99S曾俊         count: usize,
263*eb49bb99S曾俊         buf: &[u8],
264*eb49bb99S曾俊     ) -> Result<usize, SystemError> {
265*eb49bb99S曾俊         self.cache_write(lba_id_start, count, buf)
266*eb49bb99S曾俊     }
267*eb49bb99S曾俊 
268*eb49bb99S曾俊     /// # 函数的功能
269*eb49bb99S曾俊     /// 其功能对外而言和read_at函数完全一致,但是加入blockcache的功能
270*eb49bb99S曾俊     fn cache_read(
271*eb49bb99S曾俊         &self,
272*eb49bb99S曾俊         lba_id_start: BlockId,
273*eb49bb99S曾俊         count: usize,
274*eb49bb99S曾俊         buf: &mut [u8],
275*eb49bb99S曾俊     ) -> Result<usize, SystemError> {
276*eb49bb99S曾俊         let cache_response = BlockCache::read(lba_id_start, count, buf);
277*eb49bb99S曾俊         if let Err(e) = cache_response {
278*eb49bb99S曾俊             match e {
279*eb49bb99S曾俊                 BlockCacheError::StaticParameterError => {
280*eb49bb99S曾俊                     BlockCache::init();
281*eb49bb99S曾俊                     let ans = self.read_at_sync(lba_id_start, count, buf)?;
282*eb49bb99S曾俊                     return Ok(ans);
283*eb49bb99S曾俊                 }
284*eb49bb99S曾俊                 BlockCacheError::BlockFaultError(fail_vec) => {
285*eb49bb99S曾俊                     let ans = self.read_at_sync(lba_id_start, count, buf)?;
286*eb49bb99S曾俊                     let _ = BlockCache::insert(fail_vec, buf);
287*eb49bb99S曾俊                     return Ok(ans);
288*eb49bb99S曾俊                 }
289*eb49bb99S曾俊                 _ => {
290*eb49bb99S曾俊                     let ans = self.read_at_sync(lba_id_start, count, buf)?;
291*eb49bb99S曾俊                     return Ok(ans);
292*eb49bb99S曾俊                 }
293*eb49bb99S曾俊             }
294*eb49bb99S曾俊         } else {
295*eb49bb99S曾俊             return Ok(count * BLOCK_SIZE);
296*eb49bb99S曾俊         }
297*eb49bb99S曾俊     }
298*eb49bb99S曾俊 
299*eb49bb99S曾俊     /// # 函数功能
300*eb49bb99S曾俊     /// 其功能对外而言和write_at函数完全一致,但是加入blockcache的功能
301*eb49bb99S曾俊     fn cache_write(
302*eb49bb99S曾俊         &self,
303*eb49bb99S曾俊         lba_id_start: BlockId,
304*eb49bb99S曾俊         count: usize,
305*eb49bb99S曾俊         buf: &[u8],
306*eb49bb99S曾俊     ) -> Result<usize, SystemError> {
307*eb49bb99S曾俊         let _cache_response = BlockCache::immediate_write(lba_id_start, count, buf);
308*eb49bb99S曾俊         self.write_at_sync(lba_id_start, count, buf)
309*eb49bb99S曾俊     }
310*eb49bb99S曾俊 
311b087521eSChiichen     fn write_at_bytes(&self, offset: usize, len: usize, buf: &[u8]) -> Result<usize, SystemError> {
312b087521eSChiichen         if len > buf.len() {
313b087521eSChiichen             return Err(SystemError::E2BIG);
314b087521eSChiichen         }
315b087521eSChiichen 
316b087521eSChiichen         let iter = BlockIter::new_multiblock(offset, offset + len, self.blk_size_log2());
317b087521eSChiichen         let multi = iter.multiblock;
318b087521eSChiichen 
319b087521eSChiichen         for range in iter {
320b087521eSChiichen             let buf_begin = range.origin_begin() - offset; // 本次读操作的起始位置/已经读了这么多字节
321b087521eSChiichen             let buf_end = range.origin_end() - offset;
322b087521eSChiichen             let buf_slice = &buf[buf_begin..buf_end];
323b5b571e0SLoGin             let count: usize = range.lba_end - range.lba_start;
324b087521eSChiichen             let full = multi && range.is_multi() || !multi && range.is_full();
325b087521eSChiichen 
326b087521eSChiichen             if full {
327b087521eSChiichen                 self.write_at(range.lba_start, count, buf_slice)?;
328b087521eSChiichen             } else {
329b087521eSChiichen                 if self.blk_size_log2() > BLK_SIZE_LOG2_LIMIT {
330b087521eSChiichen                     return Err(SystemError::E2BIG);
331b087521eSChiichen                 }
332b087521eSChiichen 
333b5b571e0SLoGin                 let mut temp = vec![0; 1usize << self.blk_size_log2()];
334b087521eSChiichen                 // 由于块设备每次读写都是整块的,在不完整写入之前,必须把不完整的地方补全
3350facf623SLoGin                 self.read_at(range.lba_start, 1, &mut temp[..])?;
336b087521eSChiichen                 // 把数据从临时buffer复制到目标buffer
337b5b571e0SLoGin                 temp[range.begin..range.end].copy_from_slice(buf_slice);
338b087521eSChiichen                 self.write_at(range.lba_start, 1, &temp[..])?;
339b087521eSChiichen             }
340b087521eSChiichen         }
341b087521eSChiichen         return Ok(len);
342b087521eSChiichen     }
343b087521eSChiichen 
344b087521eSChiichen     fn read_at_bytes(
345b087521eSChiichen         &self,
346b087521eSChiichen         offset: usize,
347b087521eSChiichen         len: usize,
348b087521eSChiichen         buf: &mut [u8],
349b087521eSChiichen     ) -> Result<usize, SystemError> {
350b087521eSChiichen         if len > buf.len() {
351b087521eSChiichen             return Err(SystemError::E2BIG);
352b087521eSChiichen         }
353b087521eSChiichen 
354b087521eSChiichen         let iter = BlockIter::new_multiblock(offset, offset + len, self.blk_size_log2());
355b087521eSChiichen         let multi = iter.multiblock;
356b087521eSChiichen 
357b087521eSChiichen         // 枚举每一个range
358b087521eSChiichen         for range in iter {
359b087521eSChiichen             let buf_begin = range.origin_begin() - offset; // 本次读操作的起始位置/已经读了这么多字节
360b087521eSChiichen             let buf_end = range.origin_end() - offset;
361b087521eSChiichen             let buf_slice = &mut buf[buf_begin..buf_end];
362b5b571e0SLoGin             let count: usize = range.lba_end - range.lba_start;
363b087521eSChiichen             let full = multi && range.is_multi() || !multi && range.is_full();
364b087521eSChiichen 
3651effcfe5SGnoCiYeH             // 读取整个block作为有效数据
366b087521eSChiichen             if full {
367b087521eSChiichen                 // 调用 BlockDevice::read_at() 直接把引用传进去,不是把整个数组move进去
3681effcfe5SGnoCiYeH                 self.read_at(range.lba_start, count, buf_slice)?;
369b087521eSChiichen             } else {
370b087521eSChiichen                 // 判断块的长度不能超过最大值
371b087521eSChiichen                 if self.blk_size_log2() > BLK_SIZE_LOG2_LIMIT {
372b087521eSChiichen                     return Err(SystemError::E2BIG);
373b087521eSChiichen                 }
374b087521eSChiichen 
375b5b571e0SLoGin                 let mut temp = vec![0; 1usize << self.blk_size_log2()];
376b087521eSChiichen                 self.read_at(range.lba_start, 1, &mut temp[..])?;
377b087521eSChiichen 
378b087521eSChiichen                 // 把数据从临时buffer复制到目标buffer
379b087521eSChiichen                 buf_slice.copy_from_slice(&temp[range.begin..range.end]);
380b087521eSChiichen             }
381b087521eSChiichen         }
382b087521eSChiichen         return Ok(len);
383b087521eSChiichen     }
384b087521eSChiichen }
385ae5ede03SLoGin 
386ae5ede03SLoGin /// @brief 块设备框架函数集
387ae5ede03SLoGin pub struct BlockDeviceOps;
388ae5ede03SLoGin 
389ae5ede03SLoGin impl BlockDeviceOps {
390ae5ede03SLoGin     /// @brief: 主设备号转下标
391ae5ede03SLoGin     /// @parameter: major: 主设备号
392ae5ede03SLoGin     /// @return: 返回下标
393ae5ede03SLoGin     #[allow(dead_code)]
394c566df45SLoGin     fn major_to_index(major: Major) -> usize {
395b5b571e0SLoGin         return (major.data() % DEV_MAJOR_HASH_SIZE) as usize;
396ae5ede03SLoGin     }
397ae5ede03SLoGin 
398ae5ede03SLoGin     /// @brief: 动态获取主设备号
399ae5ede03SLoGin     /// @parameter: None
400ae5ede03SLoGin     /// @return: 如果成功,返回主设备号,否则,返回错误码
401ae5ede03SLoGin     #[allow(dead_code)]
402c566df45SLoGin     fn find_dynamic_major() -> Result<Major, SystemError> {
403ae5ede03SLoGin         let blockdevs = BLOCKDEVS.lock();
404ae5ede03SLoGin         // 寻找主设备号为234~255的设备
405c566df45SLoGin         for index in ((DEV_MAJOR_DYN_END.data())..DEV_MAJOR_HASH_SIZE).rev() {
406c566df45SLoGin             if let Some(item) = blockdevs.get(index as usize) {
407ae5ede03SLoGin                 if item.is_empty() {
408c566df45SLoGin                     return Ok(Major::new(index)); // 返回可用的主设备号
409ae5ede03SLoGin                 }
410ae5ede03SLoGin             }
411ae5ede03SLoGin         }
412ae5ede03SLoGin         // 寻找主设备号在384~511的设备
413c566df45SLoGin         for index in
414c566df45SLoGin             ((DEV_MAJOR_DYN_EXT_END.data() + 1)..(DEV_MAJOR_DYN_EXT_START.data() + 1)).rev()
415c566df45SLoGin         {
416b5b571e0SLoGin             if let Some(blockdevss) = blockdevs.get(Self::major_to_index(Major::new(index))) {
417ae5ede03SLoGin                 let mut flag = true;
418ae5ede03SLoGin                 for item in blockdevss {
419b5b571e0SLoGin                     if item.device_number().major() == Major::new(index) {
420ae5ede03SLoGin                         flag = false;
421ae5ede03SLoGin                         break;
422ae5ede03SLoGin                     }
423ae5ede03SLoGin                 }
424ae5ede03SLoGin                 if flag {
425ae5ede03SLoGin                     // 如果数组中不存在主设备号等于index的设备
426c566df45SLoGin                     return Ok(Major::new(index)); // 返回可用的主设备号
427ae5ede03SLoGin                 }
428ae5ede03SLoGin             }
429ae5ede03SLoGin         }
430ae5ede03SLoGin         return Err(SystemError::EBUSY);
431ae5ede03SLoGin     }
432ae5ede03SLoGin 
433ae5ede03SLoGin     /// @brief: 注册设备号,该函数需要指定主设备号
434ae5ede03SLoGin     /// @parameter: from: 主设备号
435ae5ede03SLoGin     ///             count: 次设备号数量
436ae5ede03SLoGin     ///             name: 字符设备名
437ae5ede03SLoGin     /// @return: 如果注册成功,返回设备号,否则,返回错误码
438ae5ede03SLoGin     #[allow(dead_code)]
439ae5ede03SLoGin     pub fn register_blockdev_region(
440ae5ede03SLoGin         from: DeviceNumber,
441c566df45SLoGin         count: u32,
442ae5ede03SLoGin         name: &'static str,
443ae5ede03SLoGin     ) -> Result<DeviceNumber, SystemError> {
444ae5ede03SLoGin         Self::__register_blockdev_region(from, count, name)
445ae5ede03SLoGin     }
446ae5ede03SLoGin 
447ae5ede03SLoGin     /// @brief: 注册设备号,该函数自动分配主设备号
448ae5ede03SLoGin     /// @parameter: baseminor: 主设备号
449ae5ede03SLoGin     ///             count: 次设备号数量
450ae5ede03SLoGin     ///             name: 字符设备名
451ae5ede03SLoGin     /// @return: 如果注册成功,返回,否则,返回false
452ae5ede03SLoGin     #[allow(dead_code)]
453ae5ede03SLoGin     pub fn alloc_blockdev_region(
454c566df45SLoGin         baseminor: u32,
455c566df45SLoGin         count: u32,
456ae5ede03SLoGin         name: &'static str,
457ae5ede03SLoGin     ) -> Result<DeviceNumber, SystemError> {
458c566df45SLoGin         Self::__register_blockdev_region(
459c566df45SLoGin             DeviceNumber::new(Major::UNNAMED_MAJOR, baseminor),
460c566df45SLoGin             count,
461c566df45SLoGin             name,
462c566df45SLoGin         )
463ae5ede03SLoGin     }
464ae5ede03SLoGin 
465ae5ede03SLoGin     /// @brief: 注册设备号
466ae5ede03SLoGin     /// @parameter: device_number: 设备号,主设备号如果为0,则动态分配
467ae5ede03SLoGin     ///             minorct: 次设备号数量
468ae5ede03SLoGin     ///             name: 字符设备名
469ae5ede03SLoGin     /// @return: 如果注册成功,返回设备号,否则,返回错误码
470ae5ede03SLoGin     fn __register_blockdev_region(
471ae5ede03SLoGin         device_number: DeviceNumber,
472c566df45SLoGin         minorct: u32,
473ae5ede03SLoGin         name: &'static str,
474ae5ede03SLoGin     ) -> Result<DeviceNumber, SystemError> {
475ae5ede03SLoGin         let mut major = device_number.major();
476ae5ede03SLoGin         let baseminor = device_number.minor();
477ae5ede03SLoGin         if major >= DEV_MAJOR_MAX {
478ae5ede03SLoGin             kerror!(
479c566df45SLoGin                 "DEV {} major requested {:?} is greater than the maximum {}\n",
480ae5ede03SLoGin                 name,
481ae5ede03SLoGin                 major,
482c566df45SLoGin                 DEV_MAJOR_MAX.data() - 1
483ae5ede03SLoGin             );
484ae5ede03SLoGin         }
485c566df45SLoGin         if minorct > DeviceNumber::MINOR_MASK + 1 - baseminor {
486ae5ede03SLoGin             kerror!("DEV {} minor range requested ({}-{}) is out of range of maximum range ({}-{}) for a single major\n",
487c566df45SLoGin                 name, baseminor, baseminor + minorct - 1, 0, DeviceNumber::MINOR_MASK);
488ae5ede03SLoGin         }
489c566df45SLoGin         let blockdev = DeviceStruct::new(DeviceNumber::new(major, baseminor), minorct, name);
490c566df45SLoGin         if major == Major::UNNAMED_MAJOR {
491ae5ede03SLoGin             // 如果主设备号为0,则自动分配主设备号
492ae5ede03SLoGin             major = Self::find_dynamic_major().expect("Find synamic major error.\n");
493ae5ede03SLoGin         }
494ae5ede03SLoGin         if let Some(items) = BLOCKDEVS.lock().get_mut(Self::major_to_index(major)) {
495ae5ede03SLoGin             let mut insert_index: usize = 0;
496ae5ede03SLoGin             for (index, item) in items.iter().enumerate() {
497ae5ede03SLoGin                 insert_index = index;
498ae5ede03SLoGin                 match item.device_number().major().cmp(&major) {
499ae5ede03SLoGin                     core::cmp::Ordering::Less => continue,
500ae5ede03SLoGin                     core::cmp::Ordering::Greater => {
501ae5ede03SLoGin                         break; // 大于则向后插入
502ae5ede03SLoGin                     }
503ae5ede03SLoGin                     core::cmp::Ordering::Equal => {
504ae5ede03SLoGin                         if item.device_number().minor() + item.minorct() <= baseminor {
505ae5ede03SLoGin                             continue; // 下一个主设备号大于或者次设备号大于被插入的次设备号最大值
506ae5ede03SLoGin                         }
507ae5ede03SLoGin                         if item.base_minor() >= baseminor + minorct {
508ae5ede03SLoGin                             break; // 在此处插入
509ae5ede03SLoGin                         }
510ae5ede03SLoGin                         return Err(SystemError::EBUSY); // 存在重合的次设备号
511ae5ede03SLoGin                     }
512ae5ede03SLoGin                 }
513ae5ede03SLoGin             }
514ae5ede03SLoGin             items.insert(insert_index, blockdev);
515ae5ede03SLoGin         }
516c566df45SLoGin 
517c566df45SLoGin         return Ok(DeviceNumber::new(major, baseminor));
518ae5ede03SLoGin     }
519ae5ede03SLoGin 
520ae5ede03SLoGin     /// @brief: 注销设备号
521ae5ede03SLoGin     /// @parameter: major: 主设备号,如果为0,动态分配
522ae5ede03SLoGin     ///             baseminor: 起始次设备号
523ae5ede03SLoGin     ///             minorct: 次设备号数量
524ae5ede03SLoGin     /// @return: 如果注销成功,返回(),否则,返回错误码
525ae5ede03SLoGin     fn __unregister_blockdev_region(
526ae5ede03SLoGin         device_number: DeviceNumber,
527c566df45SLoGin         minorct: u32,
528ae5ede03SLoGin     ) -> Result<(), SystemError> {
529ae5ede03SLoGin         if let Some(items) = BLOCKDEVS
530ae5ede03SLoGin             .lock()
531ae5ede03SLoGin             .get_mut(Self::major_to_index(device_number.major()))
532ae5ede03SLoGin         {
533ae5ede03SLoGin             for (index, item) in items.iter().enumerate() {
534ae5ede03SLoGin                 if item.device_number() == device_number && item.minorct() == minorct {
535ae5ede03SLoGin                     // 设备号和数量都相等
536ae5ede03SLoGin                     items.remove(index);
537ae5ede03SLoGin                     return Ok(());
538ae5ede03SLoGin                 }
539ae5ede03SLoGin             }
540ae5ede03SLoGin         }
541ae5ede03SLoGin         return Err(SystemError::EBUSY);
542ae5ede03SLoGin     }
543ae5ede03SLoGin 
544ae5ede03SLoGin     /// @brief: 块设备注册
545ae5ede03SLoGin     /// @parameter: cdev: 字符设备实例
546ae5ede03SLoGin     ///             dev_t: 字符设备号
547ae5ede03SLoGin     ///             range: 次设备号范围
548ae5ede03SLoGin     /// @return: none
549ae5ede03SLoGin     #[allow(dead_code)]
55006d5e247SLoGin     pub fn bdev_add(_bdev: Arc<dyn BlockDevice>, id_table: IdTable) -> Result<(), DeviceError> {
551c566df45SLoGin         if id_table.device_number().data() == 0 {
552ae5ede03SLoGin             kerror!("Device number can't be 0!\n");
553ae5ede03SLoGin         }
55406d5e247SLoGin         todo!("bdev_add")
55506d5e247SLoGin         // return device_manager().add_device(bdev.id_table(), bdev.device());
556ae5ede03SLoGin     }
557ae5ede03SLoGin 
558ae5ede03SLoGin     /// @brief: block设备注销
559ae5ede03SLoGin     /// @parameter: dev_t: 字符设备号
560ae5ede03SLoGin     ///             range: 次设备号范围
561ae5ede03SLoGin     /// @return: none
562ae5ede03SLoGin     #[allow(dead_code)]
563ae5ede03SLoGin     pub fn bdev_del(_devnum: DeviceNumber, _range: usize) {
564ae5ede03SLoGin         unimplemented!();
565ae5ede03SLoGin     }
566ae5ede03SLoGin }
567