1 use core::{hint::spin_loop, sync::atomic::Ordering}; 2 3 use alloc::{string::ToString, sync::Arc}; 4 use system_error::SystemError; 5 6 use crate::{ 7 driver::{base::block::disk_info::Partition, disk::ahci}, 8 filesystem::{ 9 devfs::devfs_init, 10 fat::fs::FATFileSystem, 11 procfs::procfs_init, 12 ramfs::RamFS, 13 sysfs::sysfs_init, 14 vfs::{mount::MountFS, syscall::ModeType, AtomicInodeId, FileSystem, FileType}, 15 }, 16 kdebug, kerror, kinfo, 17 process::ProcessManager, 18 }; 19 20 use super::{ 21 file::FileMode, 22 mount::MountFSInode, 23 utils::{rsplit_path, user_path_at}, 24 IndexNode, InodeId, VFS_MAX_FOLLOW_SYMLINK_TIMES, 25 }; 26 27 /// @brief 原子地生成新的Inode号。 28 /// 请注意,所有的inode号都需要通过该函数来生成.全局的inode号,除了以下两个特殊的以外,都是唯一的 29 /// 特殊的两个inode号: 30 /// [0]: 对应'.'目录项 31 /// [1]: 对应'..'目录项 32 pub fn generate_inode_id() -> InodeId { 33 static INO: AtomicInodeId = AtomicInodeId::new(InodeId::new(1)); 34 return INO.fetch_add(InodeId::new(1), Ordering::SeqCst); 35 } 36 37 static mut __ROOT_INODE: Option<Arc<dyn IndexNode>> = None; 38 39 /// @brief 获取全局的根节点 40 #[inline(always)] 41 #[allow(non_snake_case)] 42 pub fn ROOT_INODE() -> Arc<dyn IndexNode> { 43 unsafe { 44 return __ROOT_INODE.as_ref().unwrap().clone(); 45 } 46 } 47 48 /// 初始化虚拟文件系统 49 #[inline(never)] 50 pub fn vfs_init() -> Result<(), SystemError> { 51 // 使用Ramfs作为默认的根文件系统 52 let ramfs = RamFS::new(); 53 let mount_fs = MountFS::new(ramfs, None); 54 let root_inode = mount_fs.root_inode(); 55 56 unsafe { 57 __ROOT_INODE = Some(root_inode.clone()); 58 } 59 60 // 创建文件夹 61 root_inode 62 .create("proc", FileType::Dir, ModeType::from_bits_truncate(0o755)) 63 .expect("Failed to create /proc"); 64 root_inode 65 .create("dev", FileType::Dir, ModeType::from_bits_truncate(0o755)) 66 .expect("Failed to create /dev"); 67 root_inode 68 .create("sys", FileType::Dir, ModeType::from_bits_truncate(0o755)) 69 .expect("Failed to create /sys"); 70 kdebug!("dir in root:{:?}", root_inode.list()); 71 72 procfs_init().expect("Failed to initialize procfs"); 73 74 devfs_init().expect("Failed to initialize devfs"); 75 76 sysfs_init().expect("Failed to initialize sysfs"); 77 78 let root_entries = ROOT_INODE().list().expect("VFS init failed"); 79 if !root_entries.is_empty() { 80 kinfo!("Successfully initialized VFS!"); 81 } 82 return Ok(()); 83 } 84 85 /// @brief 真正执行伪文件系统迁移的过程 86 /// 87 /// @param mountpoint_name 在根目录下的挂载点的名称 88 /// @param inode 原本的挂载点的inode 89 fn do_migrate( 90 new_root_inode: Arc<dyn IndexNode>, 91 mountpoint_name: &str, 92 fs: &MountFS, 93 ) -> Result<(), SystemError> { 94 let r = new_root_inode.find(mountpoint_name); 95 let mountpoint = if let Ok(r) = r { 96 r 97 } else { 98 new_root_inode 99 .create( 100 mountpoint_name, 101 FileType::Dir, 102 ModeType::from_bits_truncate(0o755), 103 ) 104 .unwrap_or_else(|_| panic!("Failed to create '/{mountpoint_name}' in migrating")) 105 }; 106 // 迁移挂载点 107 let inode = mountpoint.arc_any().downcast::<MountFSInode>().unwrap(); 108 inode.do_mount(inode.inode_id(), fs.self_ref())?; 109 110 return Ok(()); 111 } 112 113 /// @brief 迁移伪文件系统的inode 114 /// 请注意,为了避免删掉了伪文件系统内的信息,因此没有在原root inode那里调用unlink. 115 fn migrate_virtual_filesystem(new_fs: Arc<dyn FileSystem>) -> Result<(), SystemError> { 116 kinfo!("VFS: Migrating filesystems..."); 117 118 // ==== 在这里获取要被迁移的文件系统的inode === 119 let binding = ROOT_INODE().find("proc").expect("ProcFS not mounted!").fs(); 120 let proc: &MountFS = binding.as_any_ref().downcast_ref::<MountFS>().unwrap(); 121 let binding = ROOT_INODE().find("dev").expect("DevFS not mounted!").fs(); 122 let dev: &MountFS = binding.as_any_ref().downcast_ref::<MountFS>().unwrap(); 123 let binding = ROOT_INODE().find("sys").expect("SysFs not mounted!").fs(); 124 let sys: &MountFS = binding.as_any_ref().downcast_ref::<MountFS>().unwrap(); 125 126 let new_fs = MountFS::new(new_fs, None); 127 // 获取新的根文件系统的根节点的引用 128 let new_root_inode = new_fs.root_inode(); 129 130 // 把上述文件系统,迁移到新的文件系统下 131 do_migrate(new_root_inode.clone(), "proc", proc)?; 132 do_migrate(new_root_inode.clone(), "dev", dev)?; 133 do_migrate(new_root_inode.clone(), "sys", sys)?; 134 unsafe { 135 // drop旧的Root inode 136 let old_root_inode = __ROOT_INODE.take().unwrap(); 137 drop(old_root_inode); 138 139 // 设置全局的新的ROOT Inode 140 __ROOT_INODE = Some(new_root_inode); 141 } 142 143 kinfo!("VFS: Migrate filesystems done!"); 144 145 return Ok(()); 146 } 147 148 pub fn mount_root_fs() -> Result<(), SystemError> { 149 kinfo!("Try to mount FAT32 as root fs..."); 150 let partiton: Arc<Partition> = ahci::get_disks_by_name("ahci_disk_0".to_string()) 151 .unwrap() 152 .0 153 .lock() 154 .partitions[0] 155 .clone(); 156 157 let fatfs: Result<Arc<FATFileSystem>, SystemError> = FATFileSystem::new(partiton); 158 if fatfs.is_err() { 159 kerror!( 160 "Failed to initialize fatfs, code={:?}", 161 fatfs.as_ref().err() 162 ); 163 loop { 164 spin_loop(); 165 } 166 } 167 let fatfs: Arc<FATFileSystem> = fatfs.unwrap(); 168 let r = migrate_virtual_filesystem(fatfs); 169 if r.is_err() { 170 kerror!("Failed to migrate virtual filesystem to FAT32!"); 171 loop { 172 spin_loop(); 173 } 174 } 175 kinfo!("Successfully migrate rootfs to FAT32!"); 176 177 return Ok(()); 178 } 179 180 /// @brief 创建文件/文件夹 181 pub fn do_mkdir(path: &str, _mode: FileMode) -> Result<u64, SystemError> { 182 let path = path.trim(); 183 184 let inode: Result<Arc<dyn IndexNode>, SystemError> = ROOT_INODE().lookup(path); 185 186 if let Err(errno) = inode { 187 // 文件不存在,且需要创建 188 if errno == SystemError::ENOENT { 189 let (filename, parent_path) = rsplit_path(path); 190 // 查找父目录 191 let parent_inode: Arc<dyn IndexNode> = 192 ROOT_INODE().lookup(parent_path.unwrap_or("/"))?; 193 // 创建文件夹 194 let _create_inode: Arc<dyn IndexNode> = parent_inode.create( 195 filename, 196 FileType::Dir, 197 ModeType::from_bits_truncate(0o755), 198 )?; 199 } else { 200 // 不需要创建文件,因此返回错误码 201 return Err(errno); 202 } 203 } 204 205 return Ok(0); 206 } 207 208 /// @brief 删除文件夹 209 pub fn do_remove_dir(dirfd: i32, path: &str) -> Result<u64, SystemError> { 210 let path = path.trim(); 211 212 let pcb = ProcessManager::current_pcb(); 213 let (inode_begin, remain_path) = user_path_at(&pcb, dirfd, path)?; 214 let (filename, parent_path) = rsplit_path(&remain_path); 215 216 // 最后一项文件项为.时返回EINVAL 217 if filename == "." { 218 return Err(SystemError::EINVAL); 219 } 220 221 // 查找父目录 222 let parent_inode: Arc<dyn IndexNode> = inode_begin 223 .lookup_follow_symlink(parent_path.unwrap_or("/"), VFS_MAX_FOLLOW_SYMLINK_TIMES)?; 224 225 if parent_inode.metadata()?.file_type != FileType::Dir { 226 return Err(SystemError::ENOTDIR); 227 } 228 229 // 在目标点为symlink时也返回ENOTDIR 230 let target_inode = parent_inode.find(filename)?; 231 if target_inode.metadata()?.file_type != FileType::Dir { 232 return Err(SystemError::ENOTDIR); 233 } 234 235 // 删除文件夹 236 parent_inode.rmdir(filename)?; 237 238 return Ok(0); 239 } 240 241 /// @brief 删除文件 242 pub fn do_unlink_at(dirfd: i32, path: &str) -> Result<u64, SystemError> { 243 let path = path.trim(); 244 245 let pcb = ProcessManager::current_pcb(); 246 let (inode_begin, remain_path) = user_path_at(&pcb, dirfd, path)?; 247 let inode: Result<Arc<dyn IndexNode>, SystemError> = 248 inode_begin.lookup_follow_symlink(&remain_path, VFS_MAX_FOLLOW_SYMLINK_TIMES); 249 250 if inode.is_err() { 251 let errno = inode.clone().unwrap_err(); 252 // 文件不存在,且需要创建 253 if errno == SystemError::ENOENT { 254 return Err(SystemError::ENOENT); 255 } 256 } 257 // 禁止在目录上unlink 258 if inode.unwrap().metadata()?.file_type == FileType::Dir { 259 return Err(SystemError::EPERM); 260 } 261 262 let (filename, parent_path) = rsplit_path(path); 263 // 查找父目录 264 let parent_inode: Arc<dyn IndexNode> = inode_begin 265 .lookup_follow_symlink(parent_path.unwrap_or("/"), VFS_MAX_FOLLOW_SYMLINK_TIMES)?; 266 267 if parent_inode.metadata()?.file_type != FileType::Dir { 268 return Err(SystemError::ENOTDIR); 269 } 270 271 // 删除文件 272 parent_inode.unlink(filename)?; 273 274 return Ok(0); 275 } 276 277 // @brief mount filesystem 278 pub fn do_mount(fs: Arc<dyn FileSystem>, mount_point: &str) -> Result<usize, SystemError> { 279 ROOT_INODE() 280 .lookup_follow_symlink(mount_point, VFS_MAX_FOLLOW_SYMLINK_TIMES)? 281 .mount(fs)?; 282 Ok(0) 283 } 284