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