mod.rs 20 KB

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