16b4e7a29SLoGin use core::{hint::spin_loop, sync::atomic::Ordering}; 2004e86ffSlogin 3b5b571e0SLoGin use alloc::{string::ToString, sync::Arc}; 491e9d4abSLoGin use system_error::SystemError; 5004e86ffSlogin 6004e86ffSlogin use crate::{ 782df0a13Shmt driver::{base::block::disk_info::Partition, disk::ahci}, 8004e86ffSlogin filesystem::{ 9b087521eSChiichen devfs::devfs_init, 10004e86ffSlogin fat::fs::FATFileSystem, 11b087521eSChiichen procfs::procfs_init, 12004e86ffSlogin ramfs::RamFS, 13b087521eSChiichen sysfs::sysfs_init, 146b4e7a29SLoGin vfs::{mount::MountFS, syscall::ModeType, AtomicInodeId, FileSystem, FileType}, 15004e86ffSlogin }, 16*1074eb34SSamuel Dai kerror, kinfo, 17bf4a4899SLoGin process::ProcessManager, 18004e86ffSlogin }; 19004e86ffSlogin 20bf4a4899SLoGin use super::{ 21*1074eb34SSamuel Dai fcntl::AtFlags, 22bf4a4899SLoGin file::FileMode, 23*1074eb34SSamuel Dai mount::{init_mountlist, MOUNT_LIST}, 24*1074eb34SSamuel Dai syscall::UmountFlag, 25bf4a4899SLoGin utils::{rsplit_path, user_path_at}, 2682df0a13Shmt IndexNode, InodeId, VFS_MAX_FOLLOW_SYMLINK_TIMES, 27bf4a4899SLoGin }; 28004e86ffSlogin 29004e86ffSlogin /// @brief 原子地生成新的Inode号。 30004e86ffSlogin /// 请注意,所有的inode号都需要通过该函数来生成.全局的inode号,除了以下两个特殊的以外,都是唯一的 31004e86ffSlogin /// 特殊的两个inode号: 32004e86ffSlogin /// [0]: 对应'.'目录项 33004e86ffSlogin /// [1]: 对应'..'目录项 34004e86ffSlogin pub fn generate_inode_id() -> InodeId { 356b4e7a29SLoGin static INO: AtomicInodeId = AtomicInodeId::new(InodeId::new(1)); 366b4e7a29SLoGin return INO.fetch_add(InodeId::new(1), Ordering::SeqCst); 37004e86ffSlogin } 38004e86ffSlogin 397ae679ddSLoGin static mut __ROOT_INODE: Option<Arc<dyn IndexNode>> = None; 40004e86ffSlogin 41004e86ffSlogin /// @brief 获取全局的根节点 42004e86ffSlogin #[inline(always)] 43004e86ffSlogin #[allow(non_snake_case)] 44004e86ffSlogin pub fn ROOT_INODE() -> Arc<dyn IndexNode> { 45004e86ffSlogin unsafe { 46004e86ffSlogin return __ROOT_INODE.as_ref().unwrap().clone(); 47004e86ffSlogin } 48004e86ffSlogin } 49004e86ffSlogin 505b59005fSLoGin /// 初始化虚拟文件系统 515b59005fSLoGin #[inline(never)] 525b59005fSLoGin pub fn vfs_init() -> Result<(), SystemError> { 53004e86ffSlogin // 使用Ramfs作为默认的根文件系统 54004e86ffSlogin let ramfs = RamFS::new(); 55004e86ffSlogin let mount_fs = MountFS::new(ramfs, None); 567ae679ddSLoGin let root_inode = mount_fs.root_inode(); 57*1074eb34SSamuel Dai init_mountlist(); 58004e86ffSlogin unsafe { 597ae679ddSLoGin __ROOT_INODE = Some(root_inode.clone()); 60004e86ffSlogin } 61004e86ffSlogin 62b087521eSChiichen procfs_init().expect("Failed to initialize procfs"); 63004e86ffSlogin 64b087521eSChiichen devfs_init().expect("Failed to initialize devfs"); 65004e86ffSlogin 66b087521eSChiichen sysfs_init().expect("Failed to initialize sysfs"); 67dd9f1fc1STingHuang 687ae679ddSLoGin let root_entries = ROOT_INODE().list().expect("VFS init failed"); 69b5b571e0SLoGin if !root_entries.is_empty() { 70004e86ffSlogin kinfo!("Successfully initialized VFS!"); 71004e86ffSlogin } 725b59005fSLoGin return Ok(()); 73004e86ffSlogin } 74004e86ffSlogin 75004e86ffSlogin /// @brief 迁移伪文件系统的inode 76004e86ffSlogin /// 请注意,为了避免删掉了伪文件系统内的信息,因此没有在原root inode那里调用unlink. 77676b8ef6SMork fn migrate_virtual_filesystem(new_fs: Arc<dyn FileSystem>) -> Result<(), SystemError> { 78004e86ffSlogin kinfo!("VFS: Migrating filesystems..."); 79004e86ffSlogin 80004e86ffSlogin let new_fs = MountFS::new(new_fs, None); 81004e86ffSlogin // 获取新的根文件系统的根节点的引用 827ae679ddSLoGin let new_root_inode = new_fs.root_inode(); 83004e86ffSlogin 84*1074eb34SSamuel Dai // ==== 在这里获取要被迁移的文件系统的inode并迁移 === 85*1074eb34SSamuel Dai // 因为是换根所以路径没有变化 86*1074eb34SSamuel Dai // 不需要重新注册挂载目录 87*1074eb34SSamuel Dai new_root_inode 88*1074eb34SSamuel Dai .mkdir("proc", ModeType::from_bits_truncate(0o755)) 89*1074eb34SSamuel Dai .expect("Unable to create /proc") 90*1074eb34SSamuel Dai .mount_from(ROOT_INODE().find("proc").expect("proc not mounted!")) 91*1074eb34SSamuel Dai .expect("Failed to migrate filesystem of proc"); 92*1074eb34SSamuel Dai new_root_inode 93*1074eb34SSamuel Dai .mkdir("dev", ModeType::from_bits_truncate(0o755)) 94*1074eb34SSamuel Dai .expect("Unable to create /dev") 95*1074eb34SSamuel Dai .mount_from(ROOT_INODE().find("dev").expect("dev not mounted!")) 96*1074eb34SSamuel Dai .expect("Failed to migrate filesystem of dev"); 97*1074eb34SSamuel Dai new_root_inode 98*1074eb34SSamuel Dai .mkdir("sys", ModeType::from_bits_truncate(0o755)) 99*1074eb34SSamuel Dai .expect("Unable to create /sys") 100*1074eb34SSamuel Dai .mount_from(ROOT_INODE().find("sys").expect("sys not mounted!")) 101*1074eb34SSamuel Dai .expect("Failed to migrate filesystem of sys"); 102c719ddc6SSaga1718 103004e86ffSlogin unsafe { 104004e86ffSlogin // drop旧的Root inode 1057ae679ddSLoGin let old_root_inode = __ROOT_INODE.take().unwrap(); 106004e86ffSlogin // 设置全局的新的ROOT Inode 107*1074eb34SSamuel Dai __ROOT_INODE = Some(new_root_inode.clone()); 108*1074eb34SSamuel Dai drop(old_root_inode); 109004e86ffSlogin } 110004e86ffSlogin 111004e86ffSlogin kinfo!("VFS: Migrate filesystems done!"); 112004e86ffSlogin 113004e86ffSlogin return Ok(()); 114004e86ffSlogin } 115004e86ffSlogin 1161496ba7bSLoGin pub fn mount_root_fs() -> Result<(), SystemError> { 117004e86ffSlogin kinfo!("Try to mount FAT32 as root fs..."); 118b087521eSChiichen let partiton: Arc<Partition> = ahci::get_disks_by_name("ahci_disk_0".to_string()) 119004e86ffSlogin .unwrap() 120004e86ffSlogin .0 121004e86ffSlogin .lock() 122004e86ffSlogin .partitions[0] 123004e86ffSlogin .clone(); 124004e86ffSlogin 125676b8ef6SMork let fatfs: Result<Arc<FATFileSystem>, SystemError> = FATFileSystem::new(partiton); 126004e86ffSlogin if fatfs.is_err() { 127004e86ffSlogin kerror!( 128004e86ffSlogin "Failed to initialize fatfs, code={:?}", 129004e86ffSlogin fatfs.as_ref().err() 130004e86ffSlogin ); 131004e86ffSlogin loop { 132004e86ffSlogin spin_loop(); 133004e86ffSlogin } 134004e86ffSlogin } 135004e86ffSlogin let fatfs: Arc<FATFileSystem> = fatfs.unwrap(); 136004e86ffSlogin let r = migrate_virtual_filesystem(fatfs); 137004e86ffSlogin if r.is_err() { 138004e86ffSlogin kerror!("Failed to migrate virtual filesystem to FAT32!"); 139004e86ffSlogin loop { 140004e86ffSlogin spin_loop(); 141004e86ffSlogin } 142004e86ffSlogin } 143004e86ffSlogin kinfo!("Successfully migrate rootfs to FAT32!"); 144004e86ffSlogin 1451496ba7bSLoGin return Ok(()); 146004e86ffSlogin } 147004e86ffSlogin 148004e86ffSlogin /// @brief 创建文件/文件夹 149*1074eb34SSamuel Dai pub fn do_mkdir_at( 150*1074eb34SSamuel Dai dirfd: i32, 151*1074eb34SSamuel Dai path: &str, 152*1074eb34SSamuel Dai mode: FileMode, 153*1074eb34SSamuel Dai ) -> Result<Arc<dyn IndexNode>, SystemError> { 154*1074eb34SSamuel Dai // kdebug!("Call do mkdir at"); 155*1074eb34SSamuel Dai let (mut current_inode, path) = 156*1074eb34SSamuel Dai user_path_at(&ProcessManager::current_pcb(), dirfd, path.trim())?; 157*1074eb34SSamuel Dai let (name, parent) = rsplit_path(&path); 158*1074eb34SSamuel Dai if let Some(parent) = parent { 159*1074eb34SSamuel Dai current_inode = current_inode.lookup(parent)?; 160004e86ffSlogin } 161*1074eb34SSamuel Dai // kdebug!("mkdir at {:?}", current_inode.metadata()?.inode_id); 162*1074eb34SSamuel Dai return current_inode.mkdir(name, ModeType::from_bits_truncate(mode.bits())); 163004e86ffSlogin } 164004e86ffSlogin 165821bb9a2SXshine /// @brief 删除文件夹 166bf4a4899SLoGin pub fn do_remove_dir(dirfd: i32, path: &str) -> Result<u64, SystemError> { 16782df0a13Shmt let path = path.trim(); 168004e86ffSlogin 169bf4a4899SLoGin let pcb = ProcessManager::current_pcb(); 1700fb515b0SLoGin let (inode_begin, remain_path) = user_path_at(&pcb, dirfd, path)?; 171bf4a4899SLoGin let (filename, parent_path) = rsplit_path(&remain_path); 1725eeefb8cSChenzx 1735eeefb8cSChenzx // 最后一项文件项为.时返回EINVAL 1745eeefb8cSChenzx if filename == "." { 1755eeefb8cSChenzx return Err(SystemError::EINVAL); 1765eeefb8cSChenzx } 1775eeefb8cSChenzx 178004e86ffSlogin // 查找父目录 179bf4a4899SLoGin let parent_inode: Arc<dyn IndexNode> = inode_begin 180bf4a4899SLoGin .lookup_follow_symlink(parent_path.unwrap_or("/"), VFS_MAX_FOLLOW_SYMLINK_TIMES)?; 181004e86ffSlogin 182004e86ffSlogin if parent_inode.metadata()?.file_type != FileType::Dir { 183676b8ef6SMork return Err(SystemError::ENOTDIR); 184004e86ffSlogin } 185004e86ffSlogin 1865eeefb8cSChenzx // 在目标点为symlink时也返回ENOTDIR 1875eeefb8cSChenzx let target_inode = parent_inode.find(filename)?; 188004e86ffSlogin if target_inode.metadata()?.file_type != FileType::Dir { 189676b8ef6SMork return Err(SystemError::ENOTDIR); 190004e86ffSlogin } 191004e86ffSlogin 192004e86ffSlogin // 删除文件夹 193004e86ffSlogin parent_inode.rmdir(filename)?; 194004e86ffSlogin 195004e86ffSlogin return Ok(0); 196004e86ffSlogin } 197004e86ffSlogin 198004e86ffSlogin /// @brief 删除文件 199bf4a4899SLoGin pub fn do_unlink_at(dirfd: i32, path: &str) -> Result<u64, SystemError> { 20082df0a13Shmt let path = path.trim(); 20182df0a13Shmt 202bf4a4899SLoGin let pcb = ProcessManager::current_pcb(); 2030fb515b0SLoGin let (inode_begin, remain_path) = user_path_at(&pcb, dirfd, path)?; 204bf4a4899SLoGin let inode: Result<Arc<dyn IndexNode>, SystemError> = 205bf4a4899SLoGin inode_begin.lookup_follow_symlink(&remain_path, VFS_MAX_FOLLOW_SYMLINK_TIMES); 206004e86ffSlogin 207004e86ffSlogin if inode.is_err() { 208004e86ffSlogin let errno = inode.clone().unwrap_err(); 209004e86ffSlogin // 文件不存在,且需要创建 210676b8ef6SMork if errno == SystemError::ENOENT { 211676b8ef6SMork return Err(SystemError::ENOENT); 212004e86ffSlogin } 213004e86ffSlogin } 214004e86ffSlogin // 禁止在目录上unlink 215004e86ffSlogin if inode.unwrap().metadata()?.file_type == FileType::Dir { 216676b8ef6SMork return Err(SystemError::EPERM); 217004e86ffSlogin } 218004e86ffSlogin 219004e86ffSlogin let (filename, parent_path) = rsplit_path(path); 220004e86ffSlogin // 查找父目录 221bf4a4899SLoGin let parent_inode: Arc<dyn IndexNode> = inode_begin 222bf4a4899SLoGin .lookup_follow_symlink(parent_path.unwrap_or("/"), VFS_MAX_FOLLOW_SYMLINK_TIMES)?; 223004e86ffSlogin 224004e86ffSlogin if parent_inode.metadata()?.file_type != FileType::Dir { 225676b8ef6SMork return Err(SystemError::ENOTDIR); 226004e86ffSlogin } 227004e86ffSlogin 228004e86ffSlogin // 删除文件 229004e86ffSlogin parent_inode.unlink(filename)?; 230004e86ffSlogin 231004e86ffSlogin return Ok(0); 232004e86ffSlogin } 2331d37ca6dSDonkey Kane 234*1074eb34SSamuel Dai /// # do_mount - 挂载文件系统 235*1074eb34SSamuel Dai /// 236*1074eb34SSamuel Dai /// 将给定的文件系统挂载到指定的挂载点。 237*1074eb34SSamuel Dai /// 238*1074eb34SSamuel Dai /// 此函数会检查是否已经挂载了相同的文件系统,如果已经挂载,则返回错误。 239*1074eb34SSamuel Dai /// 它还会处理符号链接,并确保挂载点是有效的。 240*1074eb34SSamuel Dai /// 241*1074eb34SSamuel Dai /// ## 参数 242*1074eb34SSamuel Dai /// 243*1074eb34SSamuel Dai /// - `fs`: Arc<dyn FileSystem>,要挂载的文件系统。 244*1074eb34SSamuel Dai /// - `mount_point`: &str,挂载点路径。 245*1074eb34SSamuel Dai /// 246*1074eb34SSamuel Dai /// ## 返回值 247*1074eb34SSamuel Dai /// 248*1074eb34SSamuel Dai /// - `Ok(Arc<MountFS>)`: 挂载成功后返回挂载的文件系统。 249*1074eb34SSamuel Dai /// - `Err(SystemError)`: 挂载失败时返回错误。 250*1074eb34SSamuel Dai pub fn do_mount(fs: Arc<dyn FileSystem>, mount_point: &str) -> Result<Arc<MountFS>, SystemError> { 251*1074eb34SSamuel Dai let (current_node, rest_path) = user_path_at( 252*1074eb34SSamuel Dai &ProcessManager::current_pcb(), 253*1074eb34SSamuel Dai AtFlags::AT_FDCWD.bits(), 254*1074eb34SSamuel Dai mount_point, 255*1074eb34SSamuel Dai )?; 256*1074eb34SSamuel Dai let inode = current_node.lookup_follow_symlink(&rest_path, VFS_MAX_FOLLOW_SYMLINK_TIMES)?; 257*1074eb34SSamuel Dai if let Some((_, rest, _fs)) = MOUNT_LIST().get_mount_point(mount_point) { 258*1074eb34SSamuel Dai if rest.is_empty() { 259*1074eb34SSamuel Dai return Err(SystemError::EBUSY); 260*1074eb34SSamuel Dai } 261*1074eb34SSamuel Dai } 262*1074eb34SSamuel Dai // 移至IndexNode.mount()来记录 263*1074eb34SSamuel Dai return inode.mount(fs); 264*1074eb34SSamuel Dai } 265*1074eb34SSamuel Dai 266*1074eb34SSamuel Dai /// # do_mount_mkdir - 在指定挂载点创建目录并挂载文件系统 267*1074eb34SSamuel Dai /// 268*1074eb34SSamuel Dai /// 在指定的挂载点创建一个目录,并将其挂载到文件系统中。如果挂载点已经存在,并且不是空的, 269*1074eb34SSamuel Dai /// 则会返回错误。成功时,会返回一个新的挂载文件系统的引用。 270*1074eb34SSamuel Dai /// 271*1074eb34SSamuel Dai /// ## 参数 272*1074eb34SSamuel Dai /// 273*1074eb34SSamuel Dai /// - `fs`: FileSystem - 文件系统的引用,用于创建和挂载目录。 274*1074eb34SSamuel Dai /// - `mount_point`: &str - 挂载点路径,用于创建和挂载目录。 275*1074eb34SSamuel Dai /// 276*1074eb34SSamuel Dai /// ## 返回值 277*1074eb34SSamuel Dai /// 278*1074eb34SSamuel Dai /// - `Ok(Arc<MountFS>)`: 成功挂载文件系统后,返回挂载文件系统的共享引用。 279*1074eb34SSamuel Dai /// - `Err(SystemError)`: 挂载失败时,返回系统错误。 280*1074eb34SSamuel Dai pub fn do_mount_mkdir( 281*1074eb34SSamuel Dai fs: Arc<dyn FileSystem>, 282*1074eb34SSamuel Dai mount_point: &str, 283*1074eb34SSamuel Dai ) -> Result<Arc<MountFS>, SystemError> { 284*1074eb34SSamuel Dai let inode = do_mkdir_at( 285*1074eb34SSamuel Dai AtFlags::AT_FDCWD.bits(), 286*1074eb34SSamuel Dai mount_point, 287*1074eb34SSamuel Dai FileMode::from_bits_truncate(0o755), 288*1074eb34SSamuel Dai )?; 289*1074eb34SSamuel Dai if let Some((_, rest, _fs)) = MOUNT_LIST().get_mount_point(mount_point) { 290*1074eb34SSamuel Dai if rest.is_empty() { 291*1074eb34SSamuel Dai return Err(SystemError::EBUSY); 292*1074eb34SSamuel Dai } 293*1074eb34SSamuel Dai } 294*1074eb34SSamuel Dai return inode.mount(fs); 295*1074eb34SSamuel Dai } 296*1074eb34SSamuel Dai 297*1074eb34SSamuel Dai /// # do_umount2 - 执行卸载文件系统的函数 298*1074eb34SSamuel Dai /// 299*1074eb34SSamuel Dai /// 这个函数用于卸载指定的文件系统。 300*1074eb34SSamuel Dai /// 301*1074eb34SSamuel Dai /// ## 参数 302*1074eb34SSamuel Dai /// 303*1074eb34SSamuel Dai /// - dirfd: i32 - 目录文件描述符,用于指定要卸载的文件系统的根目录。 304*1074eb34SSamuel Dai /// - target: &str - 要卸载的文件系统的目标路径。 305*1074eb34SSamuel Dai /// - _flag: UmountFlag - 卸载标志,目前未使用。 306*1074eb34SSamuel Dai /// 307*1074eb34SSamuel Dai /// ## 返回值 308*1074eb34SSamuel Dai /// 309*1074eb34SSamuel Dai /// - Ok(Arc<MountFS>): 成功时返回文件系统的 Arc 引用。 310*1074eb34SSamuel Dai /// - Err(SystemError): 出错时返回系统错误。 311*1074eb34SSamuel Dai /// 312*1074eb34SSamuel Dai /// ## 错误处理 313*1074eb34SSamuel Dai /// 314*1074eb34SSamuel Dai /// 如果指定的路径没有对应的文件系统,或者在尝试卸载时发生错误,将返回错误。 315*1074eb34SSamuel Dai pub fn do_umount2( 316*1074eb34SSamuel Dai dirfd: i32, 317*1074eb34SSamuel Dai target: &str, 318*1074eb34SSamuel Dai _flag: UmountFlag, 319*1074eb34SSamuel Dai ) -> Result<Arc<MountFS>, SystemError> { 320*1074eb34SSamuel Dai let (work, rest) = user_path_at(&ProcessManager::current_pcb(), dirfd, target)?; 321*1074eb34SSamuel Dai let path = work.absolute_path()? + &rest; 322*1074eb34SSamuel Dai let do_umount = || -> Result<Arc<MountFS>, SystemError> { 323*1074eb34SSamuel Dai if let Some(fs) = MOUNT_LIST().remove(path) { 324*1074eb34SSamuel Dai // Todo: 占用检测 325*1074eb34SSamuel Dai fs.umount()?; 326*1074eb34SSamuel Dai return Ok(fs); 327*1074eb34SSamuel Dai } 328*1074eb34SSamuel Dai return Err(SystemError::EINVAL); 329*1074eb34SSamuel Dai }; 330*1074eb34SSamuel Dai return do_umount(); 3311d37ca6dSDonkey Kane } 332