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