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