mod.rs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603
  1. use core::any::Any;
  2. use core::intrinsics::unlikely;
  3. use crate::filesystem::vfs::FSMAKER;
  4. use crate::libs::rwlock::RwLock;
  5. use crate::{
  6. driver::base::device::device_number::DeviceNumber,
  7. filesystem::vfs::{core::generate_inode_id, FileType},
  8. ipc::pipe::LockedPipeInode,
  9. libs::casting::DowncastArc,
  10. libs::spinlock::{SpinLock, SpinLockGuard},
  11. time::TimeSpec,
  12. };
  13. use alloc::{
  14. collections::BTreeMap,
  15. string::String,
  16. sync::{Arc, Weak},
  17. vec::Vec,
  18. };
  19. use system_error::SystemError;
  20. use super::vfs::{
  21. file::FilePrivateData, syscall::ModeType, FileSystem, FileSystemMaker, FsInfo, IndexNode,
  22. InodeId, Metadata, SpecialNodeData,
  23. };
  24. use super::vfs::{Magic, SuperBlock};
  25. /// RamFS的inode名称的最大长度
  26. const RAMFS_MAX_NAMELEN: usize = 64;
  27. const RAMFS_BLOCK_SIZE: u64 = 512;
  28. /// @brief 内存文件系统的Inode结构体
  29. #[derive(Debug)]
  30. struct LockedRamFSInode(SpinLock<RamFSInode>);
  31. /// @brief 内存文件系统结构体
  32. #[derive(Debug)]
  33. pub struct RamFS {
  34. /// RamFS的root inode
  35. root_inode: Arc<LockedRamFSInode>,
  36. super_block: RwLock<SuperBlock>,
  37. }
  38. /// @brief 内存文件系统的Inode结构体(不包含锁)
  39. #[derive(Debug)]
  40. pub struct RamFSInode {
  41. // parent变量目前只在find函数中使用到
  42. // 所以只有当inode是文件夹的时候,parent才会生效
  43. // 对于文件来说,parent就没什么作用了
  44. // 关于parent的说明: 目录不允许有硬链接
  45. /// 指向父Inode的弱引用
  46. parent: Weak<LockedRamFSInode>,
  47. /// 指向自身的弱引用
  48. self_ref: Weak<LockedRamFSInode>,
  49. /// 子Inode的B树
  50. children: BTreeMap<String, Arc<LockedRamFSInode>>,
  51. /// 当前inode的数据部分
  52. data: Vec<u8>,
  53. /// 当前inode的元数据
  54. metadata: Metadata,
  55. /// 指向inode所在的文件系统对象的指针
  56. fs: Weak<RamFS>,
  57. /// 指向特殊节点
  58. special_node: Option<SpecialNodeData>,
  59. }
  60. impl FileSystem for RamFS {
  61. fn root_inode(&self) -> Arc<dyn super::vfs::IndexNode> {
  62. return self.root_inode.clone();
  63. }
  64. fn info(&self) -> FsInfo {
  65. return FsInfo {
  66. blk_dev_id: 0,
  67. max_name_len: RAMFS_MAX_NAMELEN,
  68. };
  69. }
  70. /// @brief 本函数用于实现动态转换。
  71. /// 具体的文件系统在实现本函数时,最简单的方式就是:直接返回self
  72. fn as_any_ref(&self) -> &dyn Any {
  73. self
  74. }
  75. fn name(&self) -> &str {
  76. "ramfs"
  77. }
  78. fn super_block(&self) -> SuperBlock {
  79. self.super_block.read().clone()
  80. }
  81. }
  82. impl RamFS {
  83. pub fn new() -> Arc<Self> {
  84. let super_block = SuperBlock::new(
  85. Magic::RAMFS_MAGIC,
  86. RAMFS_BLOCK_SIZE,
  87. RAMFS_MAX_NAMELEN as u64,
  88. );
  89. // 初始化root inode
  90. let root: Arc<LockedRamFSInode> = Arc::new(LockedRamFSInode(SpinLock::new(RamFSInode {
  91. parent: Weak::default(),
  92. self_ref: Weak::default(),
  93. children: BTreeMap::new(),
  94. data: Vec::new(),
  95. metadata: Metadata {
  96. dev_id: 0,
  97. inode_id: generate_inode_id(),
  98. size: 0,
  99. blk_size: 0,
  100. blocks: 0,
  101. atime: TimeSpec::default(),
  102. mtime: TimeSpec::default(),
  103. ctime: TimeSpec::default(),
  104. file_type: FileType::Dir,
  105. mode: ModeType::from_bits_truncate(0o777),
  106. nlinks: 1,
  107. uid: 0,
  108. gid: 0,
  109. raw_dev: DeviceNumber::default(),
  110. },
  111. fs: Weak::default(),
  112. special_node: None,
  113. })));
  114. let result: Arc<RamFS> = Arc::new(RamFS {
  115. root_inode: root,
  116. super_block: RwLock::new(super_block),
  117. });
  118. // 对root inode加锁,并继续完成初始化工作
  119. let mut root_guard: SpinLockGuard<RamFSInode> = result.root_inode.0.lock();
  120. root_guard.parent = Arc::downgrade(&result.root_inode);
  121. root_guard.self_ref = Arc::downgrade(&result.root_inode);
  122. root_guard.fs = Arc::downgrade(&result);
  123. // 释放锁
  124. drop(root_guard);
  125. return result;
  126. }
  127. pub fn make_ramfs() -> Result<Arc<dyn FileSystem + 'static>, SystemError> {
  128. let fs = RamFS::new();
  129. return Ok(fs);
  130. }
  131. }
  132. #[distributed_slice(FSMAKER)]
  133. static RAMFSMAKER: FileSystemMaker = FileSystemMaker::new(
  134. "ramfs",
  135. &(RamFS::make_ramfs as fn() -> Result<Arc<dyn FileSystem + 'static>, SystemError>),
  136. );
  137. impl IndexNode for LockedRamFSInode {
  138. fn truncate(&self, len: usize) -> Result<(), SystemError> {
  139. let mut inode = self.0.lock();
  140. //如果是文件夹,则报错
  141. if inode.metadata.file_type == FileType::Dir {
  142. return Err(SystemError::EINVAL);
  143. }
  144. //当前文件长度大于_len才进行截断,否则不操作
  145. if inode.data.len() > len {
  146. inode.data.resize(len, 0);
  147. }
  148. return Ok(());
  149. }
  150. fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> {
  151. return Ok(());
  152. }
  153. fn open(
  154. &self,
  155. _data: &mut FilePrivateData,
  156. _mode: &super::vfs::file::FileMode,
  157. ) -> Result<(), SystemError> {
  158. return Ok(());
  159. }
  160. fn read_at(
  161. &self,
  162. offset: usize,
  163. len: usize,
  164. buf: &mut [u8],
  165. _data: &mut FilePrivateData,
  166. ) -> Result<usize, SystemError> {
  167. if buf.len() < len {
  168. return Err(SystemError::EINVAL);
  169. }
  170. // 加锁
  171. let inode: SpinLockGuard<RamFSInode> = self.0.lock();
  172. // 检查当前inode是否为一个文件夹,如果是的话,就返回错误
  173. if inode.metadata.file_type == FileType::Dir {
  174. return Err(SystemError::EISDIR);
  175. }
  176. let start = inode.data.len().min(offset);
  177. let end = inode.data.len().min(offset + len);
  178. // buffer空间不足
  179. if buf.len() < (end - start) {
  180. return Err(SystemError::ENOBUFS);
  181. }
  182. // 拷贝数据
  183. let src = &inode.data[start..end];
  184. buf[0..src.len()].copy_from_slice(src);
  185. return Ok(src.len());
  186. }
  187. fn write_at(
  188. &self,
  189. offset: usize,
  190. len: usize,
  191. buf: &[u8],
  192. _data: &mut FilePrivateData,
  193. ) -> Result<usize, SystemError> {
  194. if buf.len() < len {
  195. return Err(SystemError::EINVAL);
  196. }
  197. // 加锁
  198. let mut inode: SpinLockGuard<RamFSInode> = self.0.lock();
  199. // 检查当前inode是否为一个文件夹,如果是的话,就返回错误
  200. if inode.metadata.file_type == FileType::Dir {
  201. return Err(SystemError::EISDIR);
  202. }
  203. let data: &mut Vec<u8> = &mut inode.data;
  204. // 如果文件大小比原来的大,那就resize这个数组
  205. if offset + len > data.len() {
  206. data.resize(offset + len, 0);
  207. }
  208. let target = &mut data[offset..offset + len];
  209. target.copy_from_slice(&buf[0..len]);
  210. return Ok(len);
  211. }
  212. fn fs(&self) -> Arc<dyn FileSystem> {
  213. return self.0.lock().fs.upgrade().unwrap();
  214. }
  215. fn as_any_ref(&self) -> &dyn core::any::Any {
  216. self
  217. }
  218. fn metadata(&self) -> Result<Metadata, SystemError> {
  219. let inode = self.0.lock();
  220. let mut metadata = inode.metadata.clone();
  221. metadata.size = inode.data.len() as i64;
  222. return Ok(metadata);
  223. }
  224. fn set_metadata(&self, metadata: &Metadata) -> Result<(), SystemError> {
  225. let mut inode = self.0.lock();
  226. inode.metadata.atime = metadata.atime;
  227. inode.metadata.mtime = metadata.mtime;
  228. inode.metadata.ctime = metadata.ctime;
  229. inode.metadata.mode = metadata.mode;
  230. inode.metadata.uid = metadata.uid;
  231. inode.metadata.gid = metadata.gid;
  232. return Ok(());
  233. }
  234. fn resize(&self, len: usize) -> Result<(), SystemError> {
  235. let mut inode = self.0.lock();
  236. if inode.metadata.file_type == FileType::File {
  237. inode.data.resize(len, 0);
  238. return Ok(());
  239. } else {
  240. return Err(SystemError::EINVAL);
  241. }
  242. }
  243. fn create_with_data(
  244. &self,
  245. name: &str,
  246. file_type: FileType,
  247. mode: ModeType,
  248. data: usize,
  249. ) -> Result<Arc<dyn IndexNode>, SystemError> {
  250. // 获取当前inode
  251. let mut inode = self.0.lock();
  252. // 如果当前inode不是文件夹,则返回
  253. if inode.metadata.file_type != FileType::Dir {
  254. return Err(SystemError::ENOTDIR);
  255. }
  256. // 如果有重名的,则返回
  257. if inode.children.contains_key(name) {
  258. return Err(SystemError::EEXIST);
  259. }
  260. // 创建inode
  261. let result: Arc<LockedRamFSInode> = Arc::new(LockedRamFSInode(SpinLock::new(RamFSInode {
  262. parent: inode.self_ref.clone(),
  263. self_ref: Weak::default(),
  264. children: BTreeMap::new(),
  265. data: Vec::new(),
  266. metadata: Metadata {
  267. dev_id: 0,
  268. inode_id: generate_inode_id(),
  269. size: 0,
  270. blk_size: 0,
  271. blocks: 0,
  272. atime: TimeSpec::default(),
  273. mtime: TimeSpec::default(),
  274. ctime: TimeSpec::default(),
  275. file_type,
  276. mode,
  277. nlinks: 1,
  278. uid: 0,
  279. gid: 0,
  280. raw_dev: DeviceNumber::from(data as u32),
  281. },
  282. fs: inode.fs.clone(),
  283. special_node: None,
  284. })));
  285. // 初始化inode的自引用的weak指针
  286. result.0.lock().self_ref = Arc::downgrade(&result);
  287. // 将子inode插入父inode的B树中
  288. inode.children.insert(String::from(name), result.clone());
  289. return Ok(result);
  290. }
  291. fn link(&self, name: &str, other: &Arc<dyn IndexNode>) -> Result<(), SystemError> {
  292. let other: &LockedRamFSInode = other
  293. .downcast_ref::<LockedRamFSInode>()
  294. .ok_or(SystemError::EPERM)?;
  295. let mut inode: SpinLockGuard<RamFSInode> = self.0.lock();
  296. let mut other_locked: SpinLockGuard<RamFSInode> = other.0.lock();
  297. // 如果当前inode不是文件夹,那么报错
  298. if inode.metadata.file_type != FileType::Dir {
  299. return Err(SystemError::ENOTDIR);
  300. }
  301. // 如果另一个inode是文件夹,那么也报错
  302. if other_locked.metadata.file_type == FileType::Dir {
  303. return Err(SystemError::EISDIR);
  304. }
  305. // 如果当前文件夹下已经有同名文件,也报错。
  306. if inode.children.contains_key(name) {
  307. return Err(SystemError::EEXIST);
  308. }
  309. inode
  310. .children
  311. .insert(String::from(name), other_locked.self_ref.upgrade().unwrap());
  312. // 增加硬链接计数
  313. other_locked.metadata.nlinks += 1;
  314. return Ok(());
  315. }
  316. fn unlink(&self, name: &str) -> Result<(), SystemError> {
  317. let mut inode: SpinLockGuard<RamFSInode> = self.0.lock();
  318. // 如果当前inode不是目录,那么也没有子目录/文件的概念了,因此要求当前inode的类型是目录
  319. if inode.metadata.file_type != FileType::Dir {
  320. return Err(SystemError::ENOTDIR);
  321. }
  322. // 不允许删除当前文件夹,也不允许删除上一个目录
  323. if name == "." || name == ".." {
  324. return Err(SystemError::ENOTEMPTY);
  325. }
  326. // 获得要删除的文件的inode
  327. let to_delete = inode.children.get(name).ok_or(SystemError::ENOENT)?;
  328. if to_delete.0.lock().metadata.file_type == FileType::Dir {
  329. return Err(SystemError::EPERM);
  330. }
  331. // 减少硬链接计数
  332. to_delete.0.lock().metadata.nlinks -= 1;
  333. // 在当前目录中删除这个子目录项
  334. inode.children.remove(name);
  335. return Ok(());
  336. }
  337. fn rmdir(&self, name: &str) -> Result<(), SystemError> {
  338. let mut inode: SpinLockGuard<RamFSInode> = self.0.lock();
  339. // 如果当前inode不是目录,那么也没有子目录/文件的概念了,因此要求当前inode的类型是目录
  340. if inode.metadata.file_type != FileType::Dir {
  341. return Err(SystemError::ENOTDIR);
  342. }
  343. // 获得要删除的文件夹的inode
  344. let to_delete = inode.children.get(name).ok_or(SystemError::ENOENT)?;
  345. if to_delete.0.lock().metadata.file_type != FileType::Dir {
  346. return Err(SystemError::ENOTDIR);
  347. }
  348. to_delete.0.lock().metadata.nlinks -= 1;
  349. // 在当前目录中删除这个子目录项
  350. inode.children.remove(name);
  351. return Ok(());
  352. }
  353. fn move_to(
  354. &self,
  355. old_name: &str,
  356. target: &Arc<dyn IndexNode>,
  357. new_name: &str,
  358. ) -> Result<(), SystemError> {
  359. let inode: Arc<dyn IndexNode> = self.find(old_name)?;
  360. // 修改其对父节点的引用
  361. inode
  362. .downcast_ref::<LockedRamFSInode>()
  363. .ok_or(SystemError::EPERM)?
  364. .0
  365. .lock()
  366. .parent = Arc::downgrade(
  367. &target
  368. .clone()
  369. .downcast_arc::<LockedRamFSInode>()
  370. .ok_or(SystemError::EPERM)?,
  371. );
  372. // 在新的目录下创建一个硬链接
  373. target.link(new_name, &inode)?;
  374. // 取消现有的目录下的这个硬链接
  375. if let Err(e) = self.unlink(old_name) {
  376. // 当操作失败时回退操作
  377. target.unlink(new_name)?;
  378. return Err(e);
  379. }
  380. return Ok(());
  381. }
  382. fn find(&self, name: &str) -> Result<Arc<dyn IndexNode>, SystemError> {
  383. let inode = self.0.lock();
  384. if inode.metadata.file_type != FileType::Dir {
  385. return Err(SystemError::ENOTDIR);
  386. }
  387. match name {
  388. "" | "." => {
  389. return Ok(inode.self_ref.upgrade().ok_or(SystemError::ENOENT)?);
  390. }
  391. ".." => {
  392. return Ok(inode.parent.upgrade().ok_or(SystemError::ENOENT)?);
  393. }
  394. name => {
  395. // 在子目录项中查找
  396. return Ok(inode.children.get(name).ok_or(SystemError::ENOENT)?.clone());
  397. }
  398. }
  399. }
  400. fn get_entry_name(&self, ino: InodeId) -> Result<String, SystemError> {
  401. let inode: SpinLockGuard<RamFSInode> = self.0.lock();
  402. if inode.metadata.file_type != FileType::Dir {
  403. return Err(SystemError::ENOTDIR);
  404. }
  405. match ino.into() {
  406. 0 => {
  407. return Ok(String::from("."));
  408. }
  409. 1 => {
  410. return Ok(String::from(".."));
  411. }
  412. ino => {
  413. // 暴力遍历所有的children,判断inode id是否相同
  414. // TODO: 优化这里,这个地方性能很差!
  415. let mut key: Vec<String> = inode
  416. .children
  417. .keys()
  418. .filter(|k| {
  419. inode
  420. .children
  421. .get(*k)
  422. .unwrap()
  423. .0
  424. .lock()
  425. .metadata
  426. .inode_id
  427. .into()
  428. == ino
  429. })
  430. .cloned()
  431. .collect();
  432. match key.len() {
  433. 0=>{return Err(SystemError::ENOENT);}
  434. 1=>{return Ok(key.remove(0));}
  435. _ => panic!("Ramfs get_entry_name: key.len()={key_len}>1, current inode_id={inode_id:?}, to find={to_find:?}", key_len=key.len(), inode_id = inode.metadata.inode_id, to_find=ino)
  436. }
  437. }
  438. }
  439. }
  440. fn list(&self) -> Result<Vec<String>, SystemError> {
  441. let info = self.metadata()?;
  442. if info.file_type != FileType::Dir {
  443. return Err(SystemError::ENOTDIR);
  444. }
  445. let mut keys: Vec<String> = Vec::new();
  446. keys.push(String::from("."));
  447. keys.push(String::from(".."));
  448. keys.append(&mut self.0.lock().children.keys().cloned().collect());
  449. return Ok(keys);
  450. }
  451. fn mknod(
  452. &self,
  453. filename: &str,
  454. mode: ModeType,
  455. _dev_t: DeviceNumber,
  456. ) -> Result<Arc<dyn IndexNode>, SystemError> {
  457. let mut inode = self.0.lock();
  458. if inode.metadata.file_type != FileType::Dir {
  459. return Err(SystemError::ENOTDIR);
  460. }
  461. // 判断需要创建的类型
  462. if unlikely(mode.contains(ModeType::S_IFREG)) {
  463. // 普通文件
  464. return self.create(filename, FileType::File, mode);
  465. }
  466. let nod = Arc::new(LockedRamFSInode(SpinLock::new(RamFSInode {
  467. parent: inode.self_ref.clone(),
  468. self_ref: Weak::default(),
  469. children: BTreeMap::new(),
  470. data: Vec::new(),
  471. metadata: Metadata {
  472. dev_id: 0,
  473. inode_id: generate_inode_id(),
  474. size: 0,
  475. blk_size: 0,
  476. blocks: 0,
  477. atime: TimeSpec::default(),
  478. mtime: TimeSpec::default(),
  479. ctime: TimeSpec::default(),
  480. file_type: FileType::Pipe,
  481. mode,
  482. nlinks: 1,
  483. uid: 0,
  484. gid: 0,
  485. raw_dev: DeviceNumber::default(),
  486. },
  487. fs: inode.fs.clone(),
  488. special_node: None,
  489. })));
  490. nod.0.lock().self_ref = Arc::downgrade(&nod);
  491. if mode.contains(ModeType::S_IFIFO) {
  492. nod.0.lock().metadata.file_type = FileType::Pipe;
  493. // 创建pipe文件
  494. let pipe_inode = LockedPipeInode::new();
  495. // 设置special_node
  496. nod.0.lock().special_node = Some(SpecialNodeData::Pipe(pipe_inode));
  497. } else if mode.contains(ModeType::S_IFBLK) {
  498. nod.0.lock().metadata.file_type = FileType::BlockDevice;
  499. unimplemented!()
  500. } else if mode.contains(ModeType::S_IFCHR) {
  501. nod.0.lock().metadata.file_type = FileType::CharDevice;
  502. unimplemented!()
  503. }
  504. inode
  505. .children
  506. .insert(String::from(filename).to_uppercase(), nod.clone());
  507. Ok(nod)
  508. }
  509. fn special_node(&self) -> Option<super::vfs::SpecialNodeData> {
  510. return self.0.lock().special_node.clone();
  511. }
  512. /// # 用于重命名内存中的文件或目录
  513. fn rename(&self, _old_name: &str, _new_name: &str) -> Result<(), SystemError> {
  514. let old_inode: Arc<dyn IndexNode> = self.find(_old_name)?;
  515. // 在新的目录下创建一个硬链接
  516. self.link(_new_name, &old_inode)?;
  517. // 取消现有的目录下的这个硬链接
  518. if let Err(err) = self.unlink(_old_name) {
  519. // 如果取消失败,那就取消新的目录下的硬链接
  520. self.unlink(_new_name)?;
  521. return Err(err);
  522. }
  523. return Ok(());
  524. }
  525. }