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