1 use core::fmt::Formatter; 2 3 use alloc::sync::Arc; 4 use hashbrown::HashMap; 5 use system_error::SystemError; 6 use unified_init::macros::unified_init; 7 8 use crate::{ 9 driver::base::block::gendisk::GenDisk, 10 filesystem::mbr::MbrDiskPartionTable, 11 init::initcall::INITCALL_POSTCORE, 12 libs::spinlock::{SpinLock, SpinLockGuard}, 13 }; 14 15 use super::{ 16 block_device::{BlockDevName, BlockDevice, GeneralBlockRange}, 17 gendisk::GenDiskMap, 18 }; 19 20 static mut BLOCK_DEV_MANAGER: Option<BlockDevManager> = None; 21 22 #[inline] 23 pub fn block_dev_manager() -> &'static BlockDevManager { 24 unsafe { BLOCK_DEV_MANAGER.as_ref().unwrap() } 25 } 26 27 #[unified_init(INITCALL_POSTCORE)] 28 pub fn block_dev_manager_init() -> Result<(), SystemError> { 29 unsafe { 30 BLOCK_DEV_MANAGER = Some(BlockDevManager::new()); 31 } 32 Ok(()) 33 } 34 35 /// 磁盘设备管理器 36 pub struct BlockDevManager { 37 inner: SpinLock<InnerBlockDevManager>, 38 } 39 40 struct InnerBlockDevManager { 41 disks: HashMap<BlockDevName, Arc<dyn BlockDevice>>, 42 } 43 impl BlockDevManager { 44 pub fn new() -> Self { 45 BlockDevManager { 46 inner: SpinLock::new(InnerBlockDevManager { 47 disks: HashMap::new(), 48 }), 49 } 50 } 51 52 fn inner(&self) -> SpinLockGuard<InnerBlockDevManager> { 53 self.inner.lock() 54 } 55 56 /// 注册磁盘设备 57 pub fn register(&self, dev: Arc<dyn BlockDevice>) -> Result<(), SystemError> { 58 let mut inner = self.inner(); 59 let dev_name = dev.dev_name(); 60 if inner.disks.contains_key(dev_name) { 61 return Err(SystemError::EEXIST); 62 } 63 inner.disks.insert(dev_name.clone(), dev.clone()); 64 65 let mut out_remove = || { 66 inner.disks.remove(dev_name); 67 }; 68 69 // 检测分区表,并创建gendisk 70 self.check_partitions(&dev).inspect_err(|_| out_remove())?; 71 Ok(()) 72 } 73 74 /// 检测分区表,并创建gendisk 75 fn check_partitions(&self, dev: &Arc<dyn BlockDevice>) -> Result<(), SystemError> { 76 if self.check_mbr(dev).is_ok() { 77 return Ok(()); 78 } 79 80 // use entire disk as a gendisk 81 self.register_entire_disk_as_gendisk(dev) 82 } 83 84 fn check_mbr(&self, dev: &Arc<dyn BlockDevice>) -> Result<(), SystemError> { 85 let mbr = MbrDiskPartionTable::from_disk(dev.clone())?; 86 let piter = mbr.partitions_raw(); 87 for p in piter { 88 self.register_gendisk_with_range(dev, p.try_into()?)?; 89 } 90 Ok(()) 91 } 92 93 /// 将整个磁盘注册为gendisk 94 fn register_entire_disk_as_gendisk( 95 &self, 96 dev: &Arc<dyn BlockDevice>, 97 ) -> Result<(), SystemError> { 98 let range = dev.disk_range(); 99 self.register_gendisk_with_range(dev, range) 100 } 101 102 fn register_gendisk_with_range( 103 &self, 104 dev: &Arc<dyn BlockDevice>, 105 range: GeneralBlockRange, 106 ) -> Result<(), SystemError> { 107 let weak_dev = Arc::downgrade(dev); 108 let gendisk = GenDisk::new( 109 weak_dev, 110 range, 111 Some(dev.blkdev_meta().inner().gendisks.alloc_idx()), 112 ); 113 self.register_gendisk(dev, gendisk) 114 } 115 116 fn register_gendisk( 117 &self, 118 dev: &Arc<dyn BlockDevice>, 119 gendisk: Arc<GenDisk>, 120 ) -> Result<(), SystemError> { 121 let blk_meta = dev.blkdev_meta(); 122 let idx = gendisk.idx(); 123 let mut meta_inner = blk_meta.inner(); 124 // 检查是否重复 125 if meta_inner.gendisks.intersects(gendisk.range()) { 126 return Err(SystemError::EEXIST); 127 } 128 129 meta_inner.gendisks.insert(idx, gendisk.clone()); 130 dev.callback_gendisk_registered(&gendisk).inspect_err(|_| { 131 meta_inner.gendisks.remove(&idx); 132 })?; 133 Ok(()) 134 } 135 136 /// 卸载磁盘设备 137 pub fn unregister(&self, dev: &Arc<dyn BlockDevice>) { 138 let mut inner = self.inner(); 139 inner.disks.remove(dev.dev_name()); 140 // todo: 这里应该callback一下磁盘设备,但是现在还没实现热插拔,所以暂时没做这里 141 todo!("BlockDevManager: unregister disk") 142 } 143 144 /// 通过路径查找gendisk 145 /// 146 /// # 参数 147 /// 148 /// - `path`: 分区路径 `/dev/sda1` 或者 `sda1`,或者是`/dev/sda` 149 pub fn lookup_gendisk_by_path(&self, path: &str) -> Option<Arc<GenDisk>> { 150 let (devname, partno) = self.path2devname(path)?; 151 let inner = self.inner(); 152 for dev in inner.disks.values() { 153 if dev.dev_name().as_str() == devname { 154 return dev.blkdev_meta().inner().gendisks.get(&partno).cloned(); 155 } 156 } 157 None 158 } 159 160 /// 打印所有的gendisk的路径 161 pub fn print_gendisks(&self) { 162 let mut disks = alloc::vec::Vec::new(); 163 164 let inner = self.inner(); 165 for dev in inner.disks.values() { 166 let meta = dev.blkdev_meta().inner(); 167 for idx in meta.gendisks.keys() { 168 if idx == &GenDisk::ENTIRE_DISK_IDX { 169 disks.push(format!("/dev/{}", dev.dev_name())); 170 } else { 171 disks.push(format!("/dev/{}{}", dev.dev_name(), idx)); 172 } 173 } 174 } 175 176 log::debug!("All gendisks: {:?}", disks); 177 } 178 179 /// 将路径转换为设备名以及分区号 180 /// 181 /// 例如: sda1 -> (sda, 1) nvme0n1p1 -> (nvme0n1, 1) 182 fn path2devname<'a>(&self, mut path: &'a str) -> Option<(&'a str, u32)> { 183 // 去除开头的"/dev/" 184 if path.starts_with("/dev/") { 185 path = path.strip_prefix("/dev/")?; 186 } 187 188 let mut partno = GenDisk::ENTIRE_DISK_IDX; 189 // 截取末尾数字 190 let mut last_digit = path.len(); 191 while last_digit > 0 && path.chars().nth(last_digit - 1).unwrap().is_ascii_digit() { 192 last_digit -= 1; 193 } 194 if last_digit == 0 { 195 return (path, GenDisk::ENTIRE_DISK_IDX).into(); 196 } 197 198 if last_digit < path.len() { 199 partno = path[last_digit..].parse().ok()?; 200 } 201 202 let path = &path[..last_digit]; 203 204 Some((path, partno)) 205 } 206 } 207 208 pub struct BlockDevMeta { 209 pub devname: BlockDevName, 210 inner: SpinLock<InnerBlockDevMeta>, 211 } 212 213 pub struct InnerBlockDevMeta { 214 pub gendisks: GenDiskMap, 215 } 216 217 impl BlockDevMeta { 218 pub fn new(devname: BlockDevName) -> Self { 219 BlockDevMeta { 220 devname, 221 inner: SpinLock::new(InnerBlockDevMeta { 222 gendisks: GenDiskMap::new(), 223 }), 224 } 225 } 226 227 fn inner(&self) -> SpinLockGuard<InnerBlockDevMeta> { 228 self.inner.lock() 229 } 230 } 231 232 impl core::fmt::Debug for BlockDevMeta { 233 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result { 234 f.debug_struct("BlockDevMeta") 235 .field("devname", &self.devname) 236 .finish() 237 } 238 } 239