core.rs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. use core::{hint::spin_loop, sync::atomic::Ordering};
  2. use alloc::sync::Arc;
  3. use log::{error, info};
  4. use system_error::SystemError;
  5. use crate::{
  6. driver::base::block::{gendisk::GenDisk, manager::block_dev_manager},
  7. filesystem::{
  8. devfs::devfs_init,
  9. fat::fs::FATFileSystem,
  10. procfs::procfs_init,
  11. ramfs::RamFS,
  12. sysfs::sysfs_init,
  13. vfs::{mount::MountFS, syscall::ModeType, AtomicInodeId, FileSystem, FileType},
  14. },
  15. process::ProcessManager,
  16. };
  17. use super::{
  18. fcntl::AtFlags,
  19. file::FileMode,
  20. mount::{init_mountlist, MOUNT_LIST},
  21. syscall::UmountFlag,
  22. utils::{rsplit_path, user_path_at},
  23. IndexNode, InodeId, VFS_MAX_FOLLOW_SYMLINK_TIMES,
  24. };
  25. /// 当没有指定根文件系统时,尝试的根文件系统列表
  26. const ROOTFS_TRY_LIST: [&str; 4] = ["/dev/sda1", "/dev/sda", "/dev/vda1", "/dev/vda"];
  27. kernel_cmdline_param_kv!(ROOTFS_PATH_PARAM, root, "");
  28. /// @brief 原子地生成新的Inode号。
  29. /// 请注意,所有的inode号都需要通过该函数来生成.全局的inode号,除了以下两个特殊的以外,都是唯一的
  30. /// 特殊的两个inode号:
  31. /// [0]: 对应'.'目录项
  32. /// [1]: 对应'..'目录项
  33. pub fn generate_inode_id() -> InodeId {
  34. static INO: AtomicInodeId = AtomicInodeId::new(InodeId::new(1));
  35. return INO.fetch_add(InodeId::new(1), Ordering::SeqCst);
  36. }
  37. static mut __ROOT_INODE: Option<Arc<dyn IndexNode>> = None;
  38. /// @brief 获取全局的根节点
  39. #[inline(always)]
  40. #[allow(non_snake_case)]
  41. pub fn ROOT_INODE() -> Arc<dyn IndexNode> {
  42. unsafe {
  43. return __ROOT_INODE.as_ref().unwrap().clone();
  44. }
  45. }
  46. /// 初始化虚拟文件系统
  47. #[inline(never)]
  48. pub fn vfs_init() -> Result<(), SystemError> {
  49. // 使用Ramfs作为默认的根文件系统
  50. let ramfs = RamFS::new();
  51. let mount_fs = MountFS::new(ramfs, None);
  52. let root_inode = mount_fs.root_inode();
  53. init_mountlist();
  54. unsafe {
  55. __ROOT_INODE = Some(root_inode.clone());
  56. }
  57. procfs_init().expect("Failed to initialize procfs");
  58. devfs_init().expect("Failed to initialize devfs");
  59. sysfs_init().expect("Failed to initialize sysfs");
  60. let root_entries = ROOT_INODE().list().expect("VFS init failed");
  61. if !root_entries.is_empty() {
  62. info!("Successfully initialized VFS!");
  63. }
  64. return Ok(());
  65. }
  66. /// @brief 迁移伪文件系统的inode
  67. /// 请注意,为了避免删掉了伪文件系统内的信息,因此没有在原root inode那里调用unlink.
  68. fn migrate_virtual_filesystem(new_fs: Arc<dyn FileSystem>) -> Result<(), SystemError> {
  69. info!("VFS: Migrating filesystems...");
  70. let new_fs = MountFS::new(new_fs, None);
  71. // 获取新的根文件系统的根节点的引用
  72. let new_root_inode = new_fs.root_inode();
  73. // ==== 在这里获取要被迁移的文件系统的inode并迁移 ===
  74. // 因为是换根所以路径没有变化
  75. // 不需要重新注册挂载目录
  76. new_root_inode
  77. .mkdir("proc", ModeType::from_bits_truncate(0o755))
  78. .expect("Unable to create /proc")
  79. .mount_from(ROOT_INODE().find("proc").expect("proc not mounted!"))
  80. .expect("Failed to migrate filesystem of proc");
  81. new_root_inode
  82. .mkdir("dev", ModeType::from_bits_truncate(0o755))
  83. .expect("Unable to create /dev")
  84. .mount_from(ROOT_INODE().find("dev").expect("dev not mounted!"))
  85. .expect("Failed to migrate filesystem of dev");
  86. new_root_inode
  87. .mkdir("sys", ModeType::from_bits_truncate(0o755))
  88. .expect("Unable to create /sys")
  89. .mount_from(ROOT_INODE().find("sys").expect("sys not mounted!"))
  90. .expect("Failed to migrate filesystem of sys");
  91. unsafe {
  92. // drop旧的Root inode
  93. let old_root_inode = __ROOT_INODE.take().unwrap();
  94. // 设置全局的新的ROOT Inode
  95. __ROOT_INODE = Some(new_root_inode.clone());
  96. drop(old_root_inode);
  97. }
  98. info!("VFS: Migrate filesystems done!");
  99. return Ok(());
  100. }
  101. fn try_find_gendisk_as_rootfs(path: &str) -> Option<Arc<GenDisk>> {
  102. if let Some(gd) = block_dev_manager().lookup_gendisk_by_path(path) {
  103. info!("Use {} as rootfs", path);
  104. return Some(gd);
  105. }
  106. return None;
  107. }
  108. pub fn mount_root_fs() -> Result<(), SystemError> {
  109. info!("Try to mount root fs...");
  110. block_dev_manager().print_gendisks();
  111. let gendisk = if let Some(rootfs_dev_path) = ROOTFS_PATH_PARAM.value_str() {
  112. try_find_gendisk_as_rootfs(rootfs_dev_path)
  113. .unwrap_or_else(|| panic!("Failed to find rootfs device {}", rootfs_dev_path))
  114. } else {
  115. ROOTFS_TRY_LIST
  116. .iter()
  117. .find_map(|&path| try_find_gendisk_as_rootfs(path))
  118. .ok_or(SystemError::ENODEV)?
  119. };
  120. let fatfs: Result<Arc<FATFileSystem>, SystemError> = FATFileSystem::new(gendisk);
  121. if fatfs.is_err() {
  122. error!(
  123. "Failed to initialize fatfs, code={:?}",
  124. fatfs.as_ref().err()
  125. );
  126. loop {
  127. spin_loop();
  128. }
  129. }
  130. let fatfs: Arc<FATFileSystem> = fatfs.unwrap();
  131. let r = migrate_virtual_filesystem(fatfs);
  132. if r.is_err() {
  133. error!("Failed to migrate virtual filesystem to FAT32!");
  134. loop {
  135. spin_loop();
  136. }
  137. }
  138. info!("Successfully migrate rootfs to FAT32!");
  139. return Ok(());
  140. }
  141. /// @brief 创建文件/文件夹
  142. pub fn do_mkdir_at(
  143. dirfd: i32,
  144. path: &str,
  145. mode: FileMode,
  146. ) -> Result<Arc<dyn IndexNode>, SystemError> {
  147. // debug!("Call do mkdir at");
  148. let (mut current_inode, path) =
  149. user_path_at(&ProcessManager::current_pcb(), dirfd, path.trim())?;
  150. let (name, parent) = rsplit_path(&path);
  151. if let Some(parent) = parent {
  152. current_inode = current_inode.lookup(parent)?;
  153. }
  154. // debug!("mkdir at {:?}", current_inode.metadata()?.inode_id);
  155. return current_inode.mkdir(name, ModeType::from_bits_truncate(mode.bits()));
  156. }
  157. /// @brief 删除文件夹
  158. pub fn do_remove_dir(dirfd: i32, path: &str) -> Result<u64, SystemError> {
  159. let path = path.trim();
  160. let pcb = ProcessManager::current_pcb();
  161. let (inode_begin, remain_path) = user_path_at(&pcb, dirfd, path)?;
  162. let (filename, parent_path) = rsplit_path(&remain_path);
  163. // 最后一项文件项为.时返回EINVAL
  164. if filename == "." {
  165. return Err(SystemError::EINVAL);
  166. }
  167. // 查找父目录
  168. let parent_inode: Arc<dyn IndexNode> = inode_begin
  169. .lookup_follow_symlink(parent_path.unwrap_or("/"), VFS_MAX_FOLLOW_SYMLINK_TIMES)?;
  170. if parent_inode.metadata()?.file_type != FileType::Dir {
  171. return Err(SystemError::ENOTDIR);
  172. }
  173. // 在目标点为symlink时也返回ENOTDIR
  174. let target_inode = parent_inode.find(filename)?;
  175. if target_inode.metadata()?.file_type != FileType::Dir {
  176. return Err(SystemError::ENOTDIR);
  177. }
  178. // 删除文件夹
  179. parent_inode.rmdir(filename)?;
  180. return Ok(0);
  181. }
  182. /// @brief 删除文件
  183. pub fn do_unlink_at(dirfd: i32, path: &str) -> Result<u64, SystemError> {
  184. let path = path.trim();
  185. let pcb = ProcessManager::current_pcb();
  186. let (inode_begin, remain_path) = user_path_at(&pcb, dirfd, path)?;
  187. let inode: Result<Arc<dyn IndexNode>, SystemError> =
  188. inode_begin.lookup_follow_symlink(&remain_path, VFS_MAX_FOLLOW_SYMLINK_TIMES);
  189. if inode.is_err() {
  190. let errno = inode.clone().unwrap_err();
  191. // 文件不存在,且需要创建
  192. if errno == SystemError::ENOENT {
  193. return Err(SystemError::ENOENT);
  194. }
  195. }
  196. // 禁止在目录上unlink
  197. if inode.unwrap().metadata()?.file_type == FileType::Dir {
  198. return Err(SystemError::EPERM);
  199. }
  200. let (filename, parent_path) = rsplit_path(&remain_path);
  201. // 查找父目录
  202. let parent_inode: Arc<dyn IndexNode> = inode_begin
  203. .lookup_follow_symlink(parent_path.unwrap_or("/"), VFS_MAX_FOLLOW_SYMLINK_TIMES)?;
  204. if parent_inode.metadata()?.file_type != FileType::Dir {
  205. return Err(SystemError::ENOTDIR);
  206. }
  207. // 删除文件
  208. parent_inode.unlink(filename)?;
  209. return Ok(0);
  210. }
  211. /// # do_mount - 挂载文件系统
  212. ///
  213. /// 将给定的文件系统挂载到指定的挂载点。
  214. ///
  215. /// 此函数会检查是否已经挂载了相同的文件系统,如果已经挂载,则返回错误。
  216. /// 它还会处理符号链接,并确保挂载点是有效的。
  217. ///
  218. /// ## 参数
  219. ///
  220. /// - `fs`: Arc<dyn FileSystem>,要挂载的文件系统。
  221. /// - `mount_point`: &str,挂载点路径。
  222. ///
  223. /// ## 返回值
  224. ///
  225. /// - `Ok(Arc<MountFS>)`: 挂载成功后返回挂载的文件系统。
  226. /// - `Err(SystemError)`: 挂载失败时返回错误。
  227. pub fn do_mount(fs: Arc<dyn FileSystem>, mount_point: &str) -> Result<Arc<MountFS>, SystemError> {
  228. let (current_node, rest_path) = user_path_at(
  229. &ProcessManager::current_pcb(),
  230. AtFlags::AT_FDCWD.bits(),
  231. mount_point,
  232. )?;
  233. let inode = current_node.lookup_follow_symlink(&rest_path, VFS_MAX_FOLLOW_SYMLINK_TIMES)?;
  234. if let Some((_, rest, _fs)) = MOUNT_LIST().get_mount_point(mount_point) {
  235. if rest.is_empty() {
  236. return Err(SystemError::EBUSY);
  237. }
  238. }
  239. // 移至IndexNode.mount()来记录
  240. return inode.mount(fs);
  241. }
  242. /// # do_mount_mkdir - 在指定挂载点创建目录并挂载文件系统
  243. ///
  244. /// 在指定的挂载点创建一个目录,并将其挂载到文件系统中。如果挂载点已经存在,并且不是空的,
  245. /// 则会返回错误。成功时,会返回一个新的挂载文件系统的引用。
  246. ///
  247. /// ## 参数
  248. ///
  249. /// - `fs`: FileSystem - 文件系统的引用,用于创建和挂载目录。
  250. /// - `mount_point`: &str - 挂载点路径,用于创建和挂载目录。
  251. ///
  252. /// ## 返回值
  253. ///
  254. /// - `Ok(Arc<MountFS>)`: 成功挂载文件系统后,返回挂载文件系统的共享引用。
  255. /// - `Err(SystemError)`: 挂载失败时,返回系统错误。
  256. pub fn do_mount_mkdir(
  257. fs: Arc<dyn FileSystem>,
  258. mount_point: &str,
  259. ) -> Result<Arc<MountFS>, SystemError> {
  260. let inode = do_mkdir_at(
  261. AtFlags::AT_FDCWD.bits(),
  262. mount_point,
  263. FileMode::from_bits_truncate(0o755),
  264. )?;
  265. if let Some((_, rest, _fs)) = MOUNT_LIST().get_mount_point(mount_point) {
  266. if rest.is_empty() {
  267. return Err(SystemError::EBUSY);
  268. }
  269. }
  270. return inode.mount(fs);
  271. }
  272. /// # do_umount2 - 执行卸载文件系统的函数
  273. ///
  274. /// 这个函数用于卸载指定的文件系统。
  275. ///
  276. /// ## 参数
  277. ///
  278. /// - dirfd: i32 - 目录文件描述符,用于指定要卸载的文件系统的根目录。
  279. /// - target: &str - 要卸载的文件系统的目标路径。
  280. /// - _flag: UmountFlag - 卸载标志,目前未使用。
  281. ///
  282. /// ## 返回值
  283. ///
  284. /// - Ok(Arc<MountFS>): 成功时返回文件系统的 Arc 引用。
  285. /// - Err(SystemError): 出错时返回系统错误。
  286. ///
  287. /// ## 错误处理
  288. ///
  289. /// 如果指定的路径没有对应的文件系统,或者在尝试卸载时发生错误,将返回错误。
  290. pub fn do_umount2(
  291. dirfd: i32,
  292. target: &str,
  293. _flag: UmountFlag,
  294. ) -> Result<Arc<MountFS>, SystemError> {
  295. let (work, rest) = user_path_at(&ProcessManager::current_pcb(), dirfd, target)?;
  296. let path = work.absolute_path()? + &rest;
  297. let do_umount = || -> Result<Arc<MountFS>, SystemError> {
  298. if let Some(fs) = MOUNT_LIST().remove(path) {
  299. // Todo: 占用检测
  300. fs.umount()?;
  301. return Ok(fs);
  302. }
  303. return Err(SystemError::EINVAL);
  304. };
  305. return do_umount();
  306. }