mod.rs 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  1. use core::{
  2. ops::{Deref, DerefMut},
  3. sync::atomic::{AtomicU32, Ordering},
  4. };
  5. use alloc::{
  6. string::String,
  7. sync::{Arc, Weak},
  8. };
  9. use hashbrown::HashMap;
  10. use system_error::SystemError;
  11. use crate::{
  12. driver::base::device::device_number::DeviceNumber,
  13. filesystem::{
  14. devfs::{DevFS, DeviceINode, LockedDevFSInode},
  15. vfs::{syscall::ModeType, utils::DName, IndexNode, Metadata},
  16. },
  17. libs::{rwlock::RwLock, spinlock::SpinLockGuard},
  18. };
  19. use super::block_device::{BlockDevice, BlockId, GeneralBlockRange, LBA_SIZE};
  20. const MINORS_PER_DISK: u32 = 256;
  21. #[derive(Debug)]
  22. pub struct GenDisk {
  23. bdev: Weak<dyn BlockDevice>,
  24. range: GeneralBlockRange,
  25. block_size_log2: u8,
  26. idx: Option<u32>,
  27. device_num: DeviceNumber,
  28. parent: RwLock<Weak<LockedDevFSInode>>,
  29. fs: RwLock<Weak<DevFS>>,
  30. metadata: Metadata,
  31. /// 对应/dev/下的设备名
  32. name: DName,
  33. }
  34. impl GenDisk {
  35. /// 如果gendisk是整个磁盘,则idx为u32::MAX
  36. pub const ENTIRE_DISK_IDX: u32 = u32::MAX;
  37. pub fn new(
  38. bdev: Weak<dyn BlockDevice>,
  39. range: GeneralBlockRange,
  40. idx: Option<u32>,
  41. dev_name: DName,
  42. ) -> Arc<Self> {
  43. let bsizelog2 = bdev.upgrade().unwrap().blk_size_log2();
  44. // 对应整块硬盘的情况
  45. let id = idx.unwrap_or(0);
  46. if id >= MINORS_PER_DISK {
  47. panic!("GenDisk index out of range: {}", id);
  48. }
  49. let ptr = bdev.upgrade().unwrap();
  50. let meta = ptr.blkdev_meta();
  51. let major = meta.major;
  52. let minor = meta.base_minor * MINORS_PER_DISK + id;
  53. // log::info!("New gendisk: major: {}, minor: {}", major, minor);
  54. let device_num = DeviceNumber::new(major, minor);
  55. return Arc::new(GenDisk {
  56. bdev,
  57. range,
  58. block_size_log2: bsizelog2,
  59. idx,
  60. device_num,
  61. parent: RwLock::new(Weak::default()),
  62. fs: RwLock::new(Weak::default()),
  63. metadata: Metadata::new(
  64. crate::filesystem::vfs::FileType::BlockDevice,
  65. ModeType::from_bits_truncate(0o755),
  66. ),
  67. name: dev_name,
  68. });
  69. }
  70. pub fn block_device(&self) -> Arc<dyn BlockDevice> {
  71. return self.bdev.upgrade().unwrap();
  72. }
  73. /// # read_at
  74. ///
  75. /// 读取分区内的数据
  76. ///
  77. /// ## 参数
  78. ///
  79. /// - buf: 输出缓冲区,大小必须为LBA_SIZE的整数倍,否则返回EINVAL
  80. /// - start_block_offset: 分区内的块号
  81. pub fn read_at(
  82. &self,
  83. buf: &mut [u8],
  84. start_block_offset: BlockId,
  85. ) -> Result<usize, SystemError> {
  86. if (buf.len() & (LBA_SIZE - 1)) > 0 {
  87. return Err(SystemError::EINVAL);
  88. }
  89. let blocks = buf.len() / (1 << self.block_size_log2 as usize);
  90. let lba = self.block_offset_2_disk_blkid(start_block_offset);
  91. return self.block_device().read_at(lba, blocks, buf);
  92. }
  93. /// # read_at_bytes
  94. ///
  95. /// 按字节偏移量从分区中读取数据
  96. ///
  97. /// ## 参数
  98. ///
  99. /// - buf: 输出缓冲区
  100. /// - bytes_offset: 分区内的字节偏移量
  101. pub fn read_at_bytes(&self, buf: &mut [u8], bytes_offset: usize) -> Result<usize, SystemError> {
  102. let start_lba = self.range.lba_start;
  103. let bytes_offset = self.disk_blkid_2_bytes(start_lba) + bytes_offset;
  104. return self
  105. .block_device()
  106. .read_at_bytes(bytes_offset, buf.len(), buf);
  107. }
  108. /// # 分区内的字节偏移量转换为磁盘上的字节偏移量
  109. pub fn disk_bytes_offset(&self, bytes_offset: usize) -> usize {
  110. let start_lba = self.range.lba_start;
  111. return self.disk_blkid_2_bytes(start_lba) + bytes_offset;
  112. }
  113. /// # write_at_bytes
  114. ///
  115. /// 按字节偏移量向分区写入数据
  116. ///
  117. /// ## 参数
  118. ///
  119. /// - buf: 输入缓冲区
  120. /// - bytes_offset: 分区内的字节偏移量
  121. pub fn write_at_bytes(&self, buf: &[u8], bytes_offset: usize) -> Result<usize, SystemError> {
  122. let start_lba = self.range.lba_start;
  123. let bytes_offset = self.disk_blkid_2_bytes(start_lba) + bytes_offset;
  124. return self
  125. .block_device()
  126. .write_at_bytes(bytes_offset, buf.len(), buf);
  127. }
  128. /// # write_at
  129. ///
  130. /// 向分区内写入数据
  131. ///
  132. /// ## 参数
  133. ///
  134. /// - buf: 输入缓冲区,大小必须为LBA_SIZE的整数倍,否则返回EINVAL
  135. /// - start_block_offset: 分区内的块号
  136. pub fn write_at(&self, buf: &[u8], start_block_offset: BlockId) -> Result<usize, SystemError> {
  137. if (buf.len() & (LBA_SIZE - 1)) > 0 {
  138. return Err(SystemError::EINVAL);
  139. }
  140. let blocks = buf.len() / (1 << self.block_size_log2 as usize);
  141. let lba = self.block_offset_2_disk_blkid(start_block_offset);
  142. return self.block_device().write_at(lba, blocks, buf);
  143. }
  144. #[inline]
  145. pub fn block_offset_2_disk_blkid(&self, block_offset: BlockId) -> BlockId {
  146. self.range.lba_start + block_offset
  147. }
  148. #[inline]
  149. fn disk_blkid_2_bytes(&self, disk_blkid: BlockId) -> usize {
  150. disk_blkid * LBA_SIZE
  151. }
  152. #[inline]
  153. pub fn idx(&self) -> u32 {
  154. self.idx.unwrap_or(Self::ENTIRE_DISK_IDX)
  155. }
  156. #[inline]
  157. pub fn range(&self) -> &GeneralBlockRange {
  158. &self.range
  159. }
  160. #[inline]
  161. pub fn device_num(&self) -> DeviceNumber {
  162. self.device_num
  163. }
  164. #[inline]
  165. pub fn minor(&self) -> u32 {
  166. self.device_num.minor()
  167. }
  168. /// # sync
  169. /// 同步磁盘
  170. pub fn sync(&self) -> Result<(), SystemError> {
  171. self.block_device().sync()
  172. }
  173. pub fn symlink_name(&self) -> String {
  174. let major = self.device_num.major().data();
  175. let minor = self.device_num.minor();
  176. format!("{}:{}", major, minor)
  177. }
  178. pub fn block_size_log2(&self) -> u8 {
  179. self.block_size_log2
  180. }
  181. }
  182. impl IndexNode for GenDisk {
  183. fn fs(&self) -> Arc<dyn crate::filesystem::vfs::FileSystem> {
  184. self.fs.read().upgrade().unwrap()
  185. }
  186. fn as_any_ref(&self) -> &dyn core::any::Any {
  187. self
  188. }
  189. fn read_at(
  190. &self,
  191. _offset: usize,
  192. _len: usize,
  193. _buf: &mut [u8],
  194. _data: SpinLockGuard<crate::filesystem::vfs::FilePrivateData>,
  195. ) -> Result<usize, SystemError> {
  196. Err(SystemError::EPERM)
  197. }
  198. fn write_at(
  199. &self,
  200. _offset: usize,
  201. _len: usize,
  202. _buf: &[u8],
  203. _data: SpinLockGuard<crate::filesystem::vfs::FilePrivateData>,
  204. ) -> Result<usize, SystemError> {
  205. Err(SystemError::EPERM)
  206. }
  207. fn list(&self) -> Result<alloc::vec::Vec<alloc::string::String>, system_error::SystemError> {
  208. Err(SystemError::ENOSYS)
  209. }
  210. fn metadata(&self) -> Result<crate::filesystem::vfs::Metadata, SystemError> {
  211. Ok(self.metadata.clone())
  212. }
  213. fn dname(&self) -> Result<DName, SystemError> {
  214. Ok(self.name.clone())
  215. }
  216. fn parent(&self) -> Result<Arc<dyn IndexNode>, SystemError> {
  217. let parent = self.parent.read();
  218. if let Some(parent) = parent.upgrade() {
  219. return Ok(parent as Arc<dyn IndexNode>);
  220. }
  221. Err(SystemError::ENOENT)
  222. }
  223. fn close(
  224. &self,
  225. _data: SpinLockGuard<crate::filesystem::vfs::FilePrivateData>,
  226. ) -> Result<(), SystemError> {
  227. Ok(())
  228. }
  229. fn open(
  230. &self,
  231. _data: SpinLockGuard<crate::filesystem::vfs::FilePrivateData>,
  232. _mode: &crate::filesystem::vfs::file::FileMode,
  233. ) -> Result<(), SystemError> {
  234. Ok(())
  235. }
  236. }
  237. impl DeviceINode for GenDisk {
  238. fn set_fs(&self, fs: alloc::sync::Weak<crate::filesystem::devfs::DevFS>) {
  239. *self.fs.write() = fs;
  240. }
  241. fn set_parent(&self, parent: Weak<LockedDevFSInode>) {
  242. *self.parent.write() = parent;
  243. }
  244. }
  245. #[derive(Default)]
  246. pub struct GenDiskMap {
  247. data: HashMap<u32, Arc<GenDisk>>,
  248. max_idx: AtomicU32,
  249. }
  250. impl GenDiskMap {
  251. pub fn new() -> Self {
  252. GenDiskMap {
  253. data: HashMap::new(),
  254. max_idx: AtomicU32::new(1),
  255. }
  256. }
  257. #[inline]
  258. #[allow(dead_code)]
  259. pub fn max_idx(&self) -> u32 {
  260. self.max_idx.load(Ordering::SeqCst)
  261. }
  262. #[inline]
  263. pub fn alloc_idx(&self) -> u32 {
  264. self.max_idx.fetch_add(1, Ordering::SeqCst)
  265. }
  266. pub fn intersects(&self, range: &GeneralBlockRange) -> bool {
  267. for (_, v) in self.iter() {
  268. if range.intersects_with(&v.range).is_some() {
  269. return true;
  270. }
  271. }
  272. return false;
  273. }
  274. }
  275. impl Deref for GenDiskMap {
  276. type Target = HashMap<u32, Arc<GenDisk>>;
  277. fn deref(&self) -> &Self::Target {
  278. &self.data
  279. }
  280. }
  281. impl DerefMut for GenDiskMap {
  282. fn deref_mut(&mut self) -> &mut Self::Target {
  283. &mut self.data
  284. }
  285. }