1 use core::{hint::spin_loop, sync::atomic::Ordering}; 2 3 use alloc::{format, string::ToString, sync::Arc}; 4 5 use crate::{ 6 driver::{ 7 base::block::disk_info::Partition, 8 disk::ahci::{self}, 9 }, 10 filesystem::{ 11 devfs::devfs_init, 12 fat::fs::FATFileSystem, 13 procfs::procfs_init, 14 ramfs::RamFS, 15 sysfs::sysfs_init, 16 vfs::{mount::MountFS, syscall::ModeType, AtomicInodeId, FileSystem, FileType}, 17 }, 18 kdebug, kerror, kinfo, 19 process::ProcessManager, 20 syscall::SystemError, 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 #[no_mangle] 51 pub extern "C" fn vfs_init() -> i32 { 52 // 使用Ramfs作为默认的根文件系统 53 let ramfs = RamFS::new(); 54 let mount_fs = MountFS::new(ramfs, None); 55 let root_inode = mount_fs.root_inode(); 56 57 unsafe { 58 __ROOT_INODE = Some(root_inode.clone()); 59 } 60 61 // 创建文件夹 62 root_inode 63 .create("proc", FileType::Dir, ModeType::from_bits_truncate(0o755)) 64 .expect("Failed to create /proc"); 65 root_inode 66 .create("dev", FileType::Dir, ModeType::from_bits_truncate(0o755)) 67 .expect("Failed to create /dev"); 68 root_inode 69 .create("sys", FileType::Dir, ModeType::from_bits_truncate(0o755)) 70 .expect("Failed to create /sys"); 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.len() > 0 { 81 kinfo!("Successfully initialized VFS!"); 82 } 83 return 0; 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 r.is_err() { 97 new_root_inode 98 .create( 99 mountpoint_name, 100 FileType::Dir, 101 ModeType::from_bits_truncate(0o755), 102 ) 103 .expect(format!("Failed to create '/{mountpoint_name}' in migrating").as_str()) 104 } else { 105 r.unwrap() 106 }; 107 // 迁移挂载点 108 mountpoint 109 .mount(fs.inner_filesystem()) 110 .expect(format!("Failed to migrate {mountpoint_name} ").as_str()); 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 unsafe { 136 // drop旧的Root inode 137 let old_root_inode = __ROOT_INODE.take().unwrap(); 138 drop(old_root_inode); 139 140 // 设置全局的新的ROOT Inode 141 __ROOT_INODE = Some(new_root_inode); 142 } 143 144 kinfo!("VFS: Migrate filesystems done!"); 145 146 return Ok(()); 147 } 148 149 pub fn mount_root_fs() -> Result<(), SystemError> { 150 kinfo!("Try to mount FAT32 as root fs..."); 151 let partiton: Arc<Partition> = ahci::get_disks_by_name("ahci_disk_0".to_string()) 152 .unwrap() 153 .0 154 .lock() 155 .partitions[0] 156 .clone(); 157 158 let fatfs: Result<Arc<FATFileSystem>, SystemError> = FATFileSystem::new(partiton); 159 if fatfs.is_err() { 160 kerror!( 161 "Failed to initialize fatfs, code={:?}", 162 fatfs.as_ref().err() 163 ); 164 loop { 165 spin_loop(); 166 } 167 } 168 let fatfs: Arc<FATFileSystem> = fatfs.unwrap(); 169 let r = migrate_virtual_filesystem(fatfs); 170 if r.is_err() { 171 kerror!("Failed to migrate virtual filesystem to FAT32!"); 172 loop { 173 spin_loop(); 174 } 175 } 176 kinfo!("Successfully migrate rootfs to FAT32!"); 177 178 return Ok(()); 179 } 180 181 /// @brief 创建文件/文件夹 182 pub fn do_mkdir(path: &str, _mode: FileMode) -> Result<u64, SystemError> { 183 // 文件名过长 184 if path.len() > MAX_PATHLEN as usize { 185 return Err(SystemError::ENAMETOOLONG); 186 } 187 188 let inode: Result<Arc<dyn IndexNode>, SystemError> = ROOT_INODE().lookup(path); 189 190 if inode.is_err() { 191 let errno = inode.unwrap_err(); 192 // 文件不存在,且需要创建 193 if errno == SystemError::ENOENT { 194 let (filename, parent_path) = rsplit_path(path); 195 // 查找父目录 196 let parent_inode: Arc<dyn IndexNode> = 197 ROOT_INODE().lookup(parent_path.unwrap_or("/"))?; 198 // 创建文件夹 199 let _create_inode: Arc<dyn IndexNode> = parent_inode.create( 200 filename, 201 FileType::Dir, 202 ModeType::from_bits_truncate(0o755), 203 )?; 204 } else { 205 // 不需要创建文件,因此返回错误码 206 return Err(errno); 207 } 208 } 209 210 return Ok(0); 211 } 212 213 /// @brief 删除文件夹 214 pub fn do_remove_dir(dirfd: i32, path: &str) -> Result<u64, SystemError> { 215 // 文件名过长 216 if path.len() > MAX_PATHLEN as usize { 217 return Err(SystemError::ENAMETOOLONG); 218 } 219 220 let pcb = ProcessManager::current_pcb(); 221 let (inode_begin, remain_path) = user_path_at(&pcb, dirfd, path)?; 222 223 let inode: Result<Arc<dyn IndexNode>, SystemError> = 224 inode_begin.lookup_follow_symlink(remain_path.as_str(), VFS_MAX_FOLLOW_SYMLINK_TIMES); 225 226 if inode.is_err() { 227 let errno = inode.unwrap_err(); 228 // 文件不存在 229 if errno == SystemError::ENOENT { 230 return Err(SystemError::ENOENT); 231 } 232 } 233 234 let (filename, parent_path) = rsplit_path(&remain_path); 235 // 查找父目录 236 let parent_inode: Arc<dyn IndexNode> = inode_begin 237 .lookup_follow_symlink(parent_path.unwrap_or("/"), VFS_MAX_FOLLOW_SYMLINK_TIMES)?; 238 239 if parent_inode.metadata()?.file_type != FileType::Dir { 240 return Err(SystemError::ENOTDIR); 241 } 242 243 let target_inode: Arc<dyn IndexNode> = parent_inode.find(filename)?; 244 if target_inode.metadata()?.file_type != FileType::Dir { 245 return Err(SystemError::ENOTDIR); 246 } 247 248 // 删除文件夹 249 parent_inode.rmdir(filename)?; 250 251 return Ok(0); 252 } 253 254 /// @brief 删除文件 255 pub fn do_unlink_at(dirfd: i32, path: &str) -> Result<u64, SystemError> { 256 // 文件名过长 257 if path.len() > MAX_PATHLEN as usize { 258 return Err(SystemError::ENAMETOOLONG); 259 } 260 let pcb = ProcessManager::current_pcb(); 261 let (inode_begin, remain_path) = user_path_at(&pcb, dirfd, path)?; 262 263 let inode: Result<Arc<dyn IndexNode>, SystemError> = 264 inode_begin.lookup_follow_symlink(&remain_path, VFS_MAX_FOLLOW_SYMLINK_TIMES); 265 266 if inode.is_err() { 267 let errno = inode.clone().unwrap_err(); 268 // 文件不存在,且需要创建 269 if errno == SystemError::ENOENT { 270 return Err(SystemError::ENOENT); 271 } 272 } 273 // 禁止在目录上unlink 274 if inode.unwrap().metadata()?.file_type == FileType::Dir { 275 return Err(SystemError::EPERM); 276 } 277 278 let (filename, parent_path) = rsplit_path(path); 279 // 查找父目录 280 let parent_inode: Arc<dyn IndexNode> = inode_begin 281 .lookup_follow_symlink(parent_path.unwrap_or("/"), VFS_MAX_FOLLOW_SYMLINK_TIMES)?; 282 283 if parent_inode.metadata()?.file_type != FileType::Dir { 284 return Err(SystemError::ENOTDIR); 285 } 286 287 // 删除文件 288 parent_inode.unlink(filename)?; 289 290 return Ok(0); 291 } 292