xref: /DragonOS/kernel/src/driver/base/block/gendisk.rs (revision 9fa0e95eeed8630a8a69c874090af2f10e8eee02)
1*9fa0e95eSLoGin use core::{
2*9fa0e95eSLoGin     ops::{Deref, DerefMut},
3*9fa0e95eSLoGin     sync::atomic::{AtomicU32, Ordering},
4*9fa0e95eSLoGin };
5*9fa0e95eSLoGin 
6*9fa0e95eSLoGin use alloc::sync::{Arc, Weak};
7*9fa0e95eSLoGin use hashbrown::HashMap;
8*9fa0e95eSLoGin use system_error::SystemError;
9*9fa0e95eSLoGin 
10*9fa0e95eSLoGin use super::block_device::{BlockDevice, BlockId, GeneralBlockRange, LBA_SIZE};
11*9fa0e95eSLoGin 
12*9fa0e95eSLoGin #[derive(Debug)]
13*9fa0e95eSLoGin pub struct GenDisk {
14*9fa0e95eSLoGin     bdev: Weak<dyn BlockDevice>,
15*9fa0e95eSLoGin     range: GeneralBlockRange,
16*9fa0e95eSLoGin     block_size_log2: u8,
17*9fa0e95eSLoGin     idx: Option<u32>,
18*9fa0e95eSLoGin }
19*9fa0e95eSLoGin 
20*9fa0e95eSLoGin impl GenDisk {
21*9fa0e95eSLoGin     /// 如果gendisk是整个磁盘,则idx为u32::MAX
22*9fa0e95eSLoGin     pub const ENTIRE_DISK_IDX: u32 = u32::MAX;
23*9fa0e95eSLoGin 
new( bdev: Weak<dyn BlockDevice>, range: GeneralBlockRange, idx: Option<u32>, ) -> Arc<Self>24*9fa0e95eSLoGin     pub fn new(
25*9fa0e95eSLoGin         bdev: Weak<dyn BlockDevice>,
26*9fa0e95eSLoGin         range: GeneralBlockRange,
27*9fa0e95eSLoGin         idx: Option<u32>,
28*9fa0e95eSLoGin     ) -> Arc<Self> {
29*9fa0e95eSLoGin         let bsizelog2 = bdev.upgrade().unwrap().blk_size_log2();
30*9fa0e95eSLoGin 
31*9fa0e95eSLoGin         return Arc::new(GenDisk {
32*9fa0e95eSLoGin             bdev,
33*9fa0e95eSLoGin             range,
34*9fa0e95eSLoGin             block_size_log2: bsizelog2,
35*9fa0e95eSLoGin             idx,
36*9fa0e95eSLoGin         });
37*9fa0e95eSLoGin     }
38*9fa0e95eSLoGin 
block_device(&self) -> Arc<dyn BlockDevice>39*9fa0e95eSLoGin     pub fn block_device(&self) -> Arc<dyn BlockDevice> {
40*9fa0e95eSLoGin         return self.bdev.upgrade().unwrap();
41*9fa0e95eSLoGin     }
42*9fa0e95eSLoGin 
43*9fa0e95eSLoGin     /// # read_at
44*9fa0e95eSLoGin     ///
45*9fa0e95eSLoGin     /// 读取分区内的数据
46*9fa0e95eSLoGin     ///
47*9fa0e95eSLoGin     /// ## 参数
48*9fa0e95eSLoGin     ///
49*9fa0e95eSLoGin     /// - buf: 输出缓冲区,大小必须为LBA_SIZE的整数倍,否则返回EINVAL
50*9fa0e95eSLoGin     /// - start_block_offset: 分区内的块号
read_at( &self, buf: &mut [u8], start_block_offset: BlockId, ) -> Result<usize, SystemError>51*9fa0e95eSLoGin     pub fn read_at(
52*9fa0e95eSLoGin         &self,
53*9fa0e95eSLoGin         buf: &mut [u8],
54*9fa0e95eSLoGin         start_block_offset: BlockId,
55*9fa0e95eSLoGin     ) -> Result<usize, SystemError> {
56*9fa0e95eSLoGin         if (buf.len() & (LBA_SIZE - 1)) > 0 {
57*9fa0e95eSLoGin             return Err(SystemError::EINVAL);
58*9fa0e95eSLoGin         }
59*9fa0e95eSLoGin 
60*9fa0e95eSLoGin         let blocks = buf.len() / (1 << self.block_size_log2 as usize);
61*9fa0e95eSLoGin         let lba = self.block_offset_2_disk_blkid(start_block_offset);
62*9fa0e95eSLoGin 
63*9fa0e95eSLoGin         return self.block_device().read_at(lba, blocks, buf);
64*9fa0e95eSLoGin     }
65*9fa0e95eSLoGin 
66*9fa0e95eSLoGin     /// # read_at_bytes
67*9fa0e95eSLoGin     ///
68*9fa0e95eSLoGin     /// 按字节偏移量从分区中读取数据
69*9fa0e95eSLoGin     ///
70*9fa0e95eSLoGin     /// ## 参数
71*9fa0e95eSLoGin     ///
72*9fa0e95eSLoGin     /// - buf: 输出缓冲区
73*9fa0e95eSLoGin     /// - bytes_offset: 分区内的字节偏移量
read_at_bytes(&self, buf: &mut [u8], bytes_offset: usize) -> Result<usize, SystemError>74*9fa0e95eSLoGin     pub fn read_at_bytes(&self, buf: &mut [u8], bytes_offset: usize) -> Result<usize, SystemError> {
75*9fa0e95eSLoGin         let start_lba = self.range.lba_start;
76*9fa0e95eSLoGin         let bytes_offset = self.disk_blkid_2_bytes(start_lba) + bytes_offset;
77*9fa0e95eSLoGin         return self
78*9fa0e95eSLoGin             .block_device()
79*9fa0e95eSLoGin             .read_at_bytes(bytes_offset, buf.len(), buf);
80*9fa0e95eSLoGin     }
81*9fa0e95eSLoGin 
82*9fa0e95eSLoGin     /// # 分区内的字节偏移量转换为磁盘上的字节偏移量
disk_bytes_offset(&self, bytes_offset: usize) -> usize83*9fa0e95eSLoGin     pub fn disk_bytes_offset(&self, bytes_offset: usize) -> usize {
84*9fa0e95eSLoGin         let start_lba = self.range.lba_start;
85*9fa0e95eSLoGin         return self.disk_blkid_2_bytes(start_lba) + bytes_offset;
86*9fa0e95eSLoGin     }
87*9fa0e95eSLoGin 
88*9fa0e95eSLoGin     /// # write_at_bytes
89*9fa0e95eSLoGin     ///
90*9fa0e95eSLoGin     /// 按字节偏移量向分区写入数据
91*9fa0e95eSLoGin     ///
92*9fa0e95eSLoGin     /// ## 参数
93*9fa0e95eSLoGin     ///
94*9fa0e95eSLoGin     /// - buf: 输入缓冲区
95*9fa0e95eSLoGin     /// - bytes_offset: 分区内的字节偏移量
write_at_bytes(&self, buf: &[u8], bytes_offset: usize) -> Result<usize, SystemError>96*9fa0e95eSLoGin     pub fn write_at_bytes(&self, buf: &[u8], bytes_offset: usize) -> Result<usize, SystemError> {
97*9fa0e95eSLoGin         let start_lba = self.range.lba_start;
98*9fa0e95eSLoGin         let bytes_offset = self.disk_blkid_2_bytes(start_lba) + bytes_offset;
99*9fa0e95eSLoGin         return self
100*9fa0e95eSLoGin             .block_device()
101*9fa0e95eSLoGin             .write_at_bytes(bytes_offset, buf.len(), buf);
102*9fa0e95eSLoGin     }
103*9fa0e95eSLoGin 
104*9fa0e95eSLoGin     /// # write_at
105*9fa0e95eSLoGin     ///
106*9fa0e95eSLoGin     /// 向分区内写入数据
107*9fa0e95eSLoGin     ///
108*9fa0e95eSLoGin     /// ## 参数
109*9fa0e95eSLoGin     ///
110*9fa0e95eSLoGin     /// - buf: 输入缓冲区,大小必须为LBA_SIZE的整数倍,否则返回EINVAL
111*9fa0e95eSLoGin     /// - start_block_offset: 分区内的块号
write_at(&self, buf: &[u8], start_block_offset: BlockId) -> Result<usize, SystemError>112*9fa0e95eSLoGin     pub fn write_at(&self, buf: &[u8], start_block_offset: BlockId) -> Result<usize, SystemError> {
113*9fa0e95eSLoGin         if (buf.len() & (LBA_SIZE - 1)) > 0 {
114*9fa0e95eSLoGin             return Err(SystemError::EINVAL);
115*9fa0e95eSLoGin         }
116*9fa0e95eSLoGin 
117*9fa0e95eSLoGin         let blocks = buf.len() / (1 << self.block_size_log2 as usize);
118*9fa0e95eSLoGin         let lba = self.block_offset_2_disk_blkid(start_block_offset);
119*9fa0e95eSLoGin         return self.block_device().write_at(lba, blocks, buf);
120*9fa0e95eSLoGin     }
121*9fa0e95eSLoGin 
122*9fa0e95eSLoGin     #[inline]
block_offset_2_disk_blkid(&self, block_offset: BlockId) -> BlockId123*9fa0e95eSLoGin     fn block_offset_2_disk_blkid(&self, block_offset: BlockId) -> BlockId {
124*9fa0e95eSLoGin         self.range.lba_start + block_offset
125*9fa0e95eSLoGin     }
126*9fa0e95eSLoGin 
127*9fa0e95eSLoGin     #[inline]
disk_blkid_2_bytes(&self, disk_blkid: BlockId) -> usize128*9fa0e95eSLoGin     fn disk_blkid_2_bytes(&self, disk_blkid: BlockId) -> usize {
129*9fa0e95eSLoGin         disk_blkid * LBA_SIZE
130*9fa0e95eSLoGin     }
131*9fa0e95eSLoGin 
132*9fa0e95eSLoGin     #[inline]
idx(&self) -> u32133*9fa0e95eSLoGin     pub fn idx(&self) -> u32 {
134*9fa0e95eSLoGin         self.idx.unwrap_or(Self::ENTIRE_DISK_IDX)
135*9fa0e95eSLoGin     }
136*9fa0e95eSLoGin 
137*9fa0e95eSLoGin     #[inline]
range(&self) -> &GeneralBlockRange138*9fa0e95eSLoGin     pub fn range(&self) -> &GeneralBlockRange {
139*9fa0e95eSLoGin         &self.range
140*9fa0e95eSLoGin     }
141*9fa0e95eSLoGin 
142*9fa0e95eSLoGin     /// # sync
143*9fa0e95eSLoGin     /// 同步磁盘
sync(&self) -> Result<(), SystemError>144*9fa0e95eSLoGin     pub fn sync(&self) -> Result<(), SystemError> {
145*9fa0e95eSLoGin         self.block_device().sync()
146*9fa0e95eSLoGin     }
147*9fa0e95eSLoGin }
148*9fa0e95eSLoGin 
149*9fa0e95eSLoGin #[derive(Default)]
150*9fa0e95eSLoGin pub struct GenDiskMap {
151*9fa0e95eSLoGin     data: HashMap<u32, Arc<GenDisk>>,
152*9fa0e95eSLoGin     max_idx: AtomicU32,
153*9fa0e95eSLoGin }
154*9fa0e95eSLoGin 
155*9fa0e95eSLoGin impl GenDiskMap {
new() -> Self156*9fa0e95eSLoGin     pub fn new() -> Self {
157*9fa0e95eSLoGin         GenDiskMap {
158*9fa0e95eSLoGin             data: HashMap::new(),
159*9fa0e95eSLoGin             max_idx: AtomicU32::new(1),
160*9fa0e95eSLoGin         }
161*9fa0e95eSLoGin     }
162*9fa0e95eSLoGin 
163*9fa0e95eSLoGin     #[inline]
max_idx(&self) -> u32164*9fa0e95eSLoGin     pub fn max_idx(&self) -> u32 {
165*9fa0e95eSLoGin         self.max_idx.load(Ordering::SeqCst)
166*9fa0e95eSLoGin     }
167*9fa0e95eSLoGin 
168*9fa0e95eSLoGin     #[inline]
alloc_idx(&self) -> u32169*9fa0e95eSLoGin     pub fn alloc_idx(&self) -> u32 {
170*9fa0e95eSLoGin         self.max_idx.fetch_add(1, Ordering::SeqCst)
171*9fa0e95eSLoGin     }
172*9fa0e95eSLoGin 
intersects(&self, range: &GeneralBlockRange) -> bool173*9fa0e95eSLoGin     pub fn intersects(&self, range: &GeneralBlockRange) -> bool {
174*9fa0e95eSLoGin         for (_, v) in self.iter() {
175*9fa0e95eSLoGin             if range.intersects_with(&v.range).is_some() {
176*9fa0e95eSLoGin                 return true;
177*9fa0e95eSLoGin             }
178*9fa0e95eSLoGin         }
179*9fa0e95eSLoGin         return false;
180*9fa0e95eSLoGin     }
181*9fa0e95eSLoGin }
182*9fa0e95eSLoGin 
183*9fa0e95eSLoGin impl Deref for GenDiskMap {
184*9fa0e95eSLoGin     type Target = HashMap<u32, Arc<GenDisk>>;
185*9fa0e95eSLoGin 
deref(&self) -> &Self::Target186*9fa0e95eSLoGin     fn deref(&self) -> &Self::Target {
187*9fa0e95eSLoGin         &self.data
188*9fa0e95eSLoGin     }
189*9fa0e95eSLoGin }
190*9fa0e95eSLoGin 
191*9fa0e95eSLoGin impl DerefMut for GenDiskMap {
deref_mut(&mut self) -> &mut Self::Target192*9fa0e95eSLoGin     fn deref_mut(&mut self) -> &mut Self::Target {
193*9fa0e95eSLoGin         &mut self.data
194*9fa0e95eSLoGin     }
195*9fa0e95eSLoGin }
196