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 71 kdebug!("dir in root:{:?}", root_inode.list()); 72 73 procfs_init().expect("Failed to initialize procfs"); 74 75 devfs_init().expect("Failed to initialize devfs"); 76 77 sysfs_init().expect("Failed to initialize sysfs"); 78 79 let root_entries = ROOT_INODE().list().expect("VFS init failed"); 80 if !root_entries.is_empty() { 81 kinfo!("Successfully initialized VFS!"); 82 } 83 return Ok(()); 84 } 85 86 /// @brief 真正执行伪文件系统迁移的过程 87 /// 88 /// @param mountpoint_name 在根目录下的挂载点的名称 89 /// @param inode 原本的挂载点的inode 90 fn do_migrate( 91 new_root_inode: Arc<dyn IndexNode>, 92 mountpoint_name: &str, 93 fs: &MountFS, 94 ) -> Result<(), SystemError> { 95 let r = new_root_inode.find(mountpoint_name); 96 let mountpoint = if let Ok(r) = r { 97 r 98 } else { 99 new_root_inode 100 .create( 101 mountpoint_name, 102 FileType::Dir, 103 ModeType::from_bits_truncate(0o755), 104 ) 105 .unwrap_or_else(|_| panic!("Failed to create '/{mountpoint_name}' in migrating")) 106 }; 107 // 迁移挂载点 108 let inode = mountpoint.arc_any().downcast::<MountFSInode>().unwrap(); 109 inode.do_mount(inode.inode_id(), fs.self_ref())?; 110 111 return Ok(()); 112 } 113 114 /// @brief 迁移伪文件系统的inode 115 /// 请注意,为了避免删掉了伪文件系统内的信息,因此没有在原root inode那里调用unlink. 116 fn migrate_virtual_filesystem(new_fs: Arc<dyn FileSystem>) -> Result<(), SystemError> { 117 kinfo!("VFS: Migrating filesystems..."); 118 119 // ==== 在这里获取要被迁移的文件系统的inode === 120 let binding = ROOT_INODE().find("proc").expect("ProcFS not mounted!").fs(); 121 let proc: &MountFS = binding.as_any_ref().downcast_ref::<MountFS>().unwrap(); 122 let binding = ROOT_INODE().find("dev").expect("DevFS not mounted!").fs(); 123 let dev: &MountFS = binding.as_any_ref().downcast_ref::<MountFS>().unwrap(); 124 let binding = ROOT_INODE().find("sys").expect("SysFs not mounted!").fs(); 125 let sys: &MountFS = binding.as_any_ref().downcast_ref::<MountFS>().unwrap(); 126 127 let new_fs = MountFS::new(new_fs, None); 128 // 获取新的根文件系统的根节点的引用 129 let new_root_inode = new_fs.root_inode(); 130 131 // 把上述文件系统,迁移到新的文件系统下 132 do_migrate(new_root_inode.clone(), "proc", proc)?; 133 do_migrate(new_root_inode.clone(), "dev", dev)?; 134 do_migrate(new_root_inode.clone(), "sys", sys)?; 135 136 unsafe { 137 // drop旧的Root inode 138 let old_root_inode = __ROOT_INODE.take().unwrap(); 139 drop(old_root_inode); 140 141 // 设置全局的新的ROOT Inode 142 __ROOT_INODE = Some(new_root_inode); 143 } 144 145 kinfo!("VFS: Migrate filesystems done!"); 146 147 return Ok(()); 148 } 149 150 pub fn mount_root_fs() -> Result<(), SystemError> { 151 kinfo!("Try to mount FAT32 as root fs..."); 152 let partiton: Arc<Partition> = ahci::get_disks_by_name("ahci_disk_0".to_string()) 153 .unwrap() 154 .0 155 .lock() 156 .partitions[0] 157 .clone(); 158 159 let fatfs: Result<Arc<FATFileSystem>, SystemError> = FATFileSystem::new(partiton); 160 if fatfs.is_err() { 161 kerror!( 162 "Failed to initialize fatfs, code={:?}", 163 fatfs.as_ref().err() 164 ); 165 loop { 166 spin_loop(); 167 } 168 } 169 let fatfs: Arc<FATFileSystem> = fatfs.unwrap(); 170 let r = migrate_virtual_filesystem(fatfs); 171 if r.is_err() { 172 kerror!("Failed to migrate virtual filesystem to FAT32!"); 173 loop { 174 spin_loop(); 175 } 176 } 177 kinfo!("Successfully migrate rootfs to FAT32!"); 178 179 return Ok(()); 180 } 181 182 /// @brief 创建文件/文件夹 183 pub fn do_mkdir(path: &str, _mode: FileMode) -> Result<u64, SystemError> { 184 let path = path.trim(); 185 186 let inode: Result<Arc<dyn IndexNode>, SystemError> = ROOT_INODE().lookup(path); 187 188 if let Err(errno) = inode { 189 // 文件不存在,且需要创建 190 if errno == SystemError::ENOENT { 191 let (filename, parent_path) = rsplit_path(path); 192 // 查找父目录 193 let parent_inode: Arc<dyn IndexNode> = 194 ROOT_INODE().lookup(parent_path.unwrap_or("/"))?; 195 // 创建文件夹 196 let _create_inode: Arc<dyn IndexNode> = parent_inode.create( 197 filename, 198 FileType::Dir, 199 ModeType::from_bits_truncate(0o755), 200 )?; 201 } else { 202 // 不需要创建文件,因此返回错误码 203 return Err(errno); 204 } 205 } 206 207 return Ok(0); 208 } 209 210 /// @brief 删除文件夹 211 pub fn do_remove_dir(dirfd: i32, path: &str) -> Result<u64, SystemError> { 212 let path = path.trim(); 213 214 let pcb = ProcessManager::current_pcb(); 215 let (inode_begin, remain_path) = user_path_at(&pcb, dirfd, path)?; 216 let (filename, parent_path) = rsplit_path(&remain_path); 217 218 // 最后一项文件项为.时返回EINVAL 219 if filename == "." { 220 return Err(SystemError::EINVAL); 221 } 222 223 // 查找父目录 224 let parent_inode: Arc<dyn IndexNode> = inode_begin 225 .lookup_follow_symlink(parent_path.unwrap_or("/"), VFS_MAX_FOLLOW_SYMLINK_TIMES)?; 226 227 if parent_inode.metadata()?.file_type != FileType::Dir { 228 return Err(SystemError::ENOTDIR); 229 } 230 231 // 在目标点为symlink时也返回ENOTDIR 232 let target_inode = parent_inode.find(filename)?; 233 if target_inode.metadata()?.file_type != FileType::Dir { 234 return Err(SystemError::ENOTDIR); 235 } 236 237 // 删除文件夹 238 parent_inode.rmdir(filename)?; 239 240 return Ok(0); 241 } 242 243 /// @brief 删除文件 244 pub fn do_unlink_at(dirfd: i32, path: &str) -> Result<u64, SystemError> { 245 let path = path.trim(); 246 247 let pcb = ProcessManager::current_pcb(); 248 let (inode_begin, remain_path) = user_path_at(&pcb, dirfd, path)?; 249 let inode: Result<Arc<dyn IndexNode>, SystemError> = 250 inode_begin.lookup_follow_symlink(&remain_path, VFS_MAX_FOLLOW_SYMLINK_TIMES); 251 252 if inode.is_err() { 253 let errno = inode.clone().unwrap_err(); 254 // 文件不存在,且需要创建 255 if errno == SystemError::ENOENT { 256 return Err(SystemError::ENOENT); 257 } 258 } 259 // 禁止在目录上unlink 260 if inode.unwrap().metadata()?.file_type == FileType::Dir { 261 return Err(SystemError::EPERM); 262 } 263 264 let (filename, parent_path) = rsplit_path(path); 265 // 查找父目录 266 let parent_inode: Arc<dyn IndexNode> = inode_begin 267 .lookup_follow_symlink(parent_path.unwrap_or("/"), VFS_MAX_FOLLOW_SYMLINK_TIMES)?; 268 269 if parent_inode.metadata()?.file_type != FileType::Dir { 270 return Err(SystemError::ENOTDIR); 271 } 272 273 // 删除文件 274 parent_inode.unlink(filename)?; 275 276 return Ok(0); 277 } 278 279 // @brief mount filesystem 280 pub fn do_mount(fs: Arc<dyn FileSystem>, mount_point: &str) -> Result<usize, SystemError> { 281 ROOT_INODE() 282 .lookup_follow_symlink(mount_point, VFS_MAX_FOLLOW_SYMLINK_TIMES)? 283 .mount(fs)?; 284 Ok(0) 285 } 286