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