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