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