1 use core::{ 2 hint::spin_loop, 3 ptr::null_mut, 4 sync::atomic::{AtomicUsize, Ordering}, 5 }; 6 7 use alloc::{boxed::Box, format, string::ToString, sync::Arc}; 8 9 use crate::{ 10 arch::asm::current::current_pcb, 11 driver::disk::ahci::{self}, 12 filesystem::{ 13 devfs::DevFS, 14 fat::fs::FATFileSystem, 15 procfs::ProcFS, 16 ramfs::RamFS, 17 vfs::{file::File, mount::MountFS, FileSystem, FileType}, 18 }, 19 include::bindings::bindings::PAGE_4K_SIZE, 20 io::SeekFrom, 21 kerror, kinfo, 22 syscall::SystemError, 23 }; 24 25 use super::{file::FileMode, utils::rsplit_path, IndexNode, InodeId}; 26 27 /// @brief 原子地生成新的Inode号。 28 /// 请注意,所有的inode号都需要通过该函数来生成.全局的inode号,除了以下两个特殊的以外,都是唯一的 29 /// 特殊的两个inode号: 30 /// [0]: 对应'.'目录项 31 /// [1]: 对应'..'目录项 32 pub fn generate_inode_id() -> InodeId { 33 static INO: AtomicUsize = AtomicUsize::new(1); 34 return INO.fetch_add(1, Ordering::SeqCst); 35 } 36 37 static mut __ROOT_INODE: *mut Arc<dyn IndexNode> = null_mut(); 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 #[no_mangle] 49 pub extern "C" fn vfs_init() -> i32 { 50 // 使用Ramfs作为默认的根文件系统 51 let ramfs = RamFS::new(); 52 let mount_fs = MountFS::new(ramfs, None); 53 let root_inode = Box::leak(Box::new(mount_fs.root_inode())); 54 55 unsafe { 56 __ROOT_INODE = root_inode; 57 } 58 59 // 创建文件夹 60 root_inode 61 .create("proc", FileType::Dir, 0o777) 62 .expect("Failed to create /proc"); 63 root_inode 64 .create("dev", FileType::Dir, 0o777) 65 .expect("Failed to create /dev"); 66 67 // // 创建procfs实例 68 let procfs: Arc<ProcFS> = ProcFS::new(); 69 70 // procfs挂载 71 let _t = root_inode 72 .find("proc") 73 .expect("Cannot find /proc") 74 .mount(procfs) 75 .expect("Failed to mount procfs."); 76 kinfo!("ProcFS mounted."); 77 78 // 创建 devfs 实例 79 let devfs: Arc<DevFS> = DevFS::new(); 80 // devfs 挂载 81 let _t = root_inode 82 .find("dev") 83 .expect("Cannot find /dev") 84 .mount(devfs) 85 .expect("Failed to mount devfs"); 86 kinfo!("DevFS mounted."); 87 88 let root_inode = ROOT_INODE().list().expect("VFS init failed"); 89 if root_inode.len() > 0 { 90 kinfo!("Successfully initialized VFS!"); 91 } 92 return 0; 93 } 94 95 /// @brief 真正执行伪文件系统迁移的过程 96 /// 97 /// @param mountpoint_name 在根目录下的挂载点的名称 98 /// @param inode 原本的挂载点的inode 99 fn do_migrate( 100 new_root_inode: Arc<dyn IndexNode>, 101 mountpoint_name: &str, 102 fs: &MountFS, 103 ) -> Result<(), SystemError> { 104 let r = new_root_inode.find(mountpoint_name); 105 let mountpoint = if r.is_err() { 106 new_root_inode 107 .create(mountpoint_name, FileType::Dir, 0o777) 108 .expect(format!("Failed to create '/{mountpoint_name}'").as_str()) 109 } else { 110 r.unwrap() 111 }; 112 // 迁移挂载点 113 mountpoint 114 .mount(fs.inner_filesystem()) 115 .expect(format!("Failed to migrate {mountpoint_name}").as_str()); 116 return Ok(()); 117 } 118 119 /// @brief 迁移伪文件系统的inode 120 /// 请注意,为了避免删掉了伪文件系统内的信息,因此没有在原root inode那里调用unlink. 121 fn migrate_virtual_filesystem(new_fs: Arc<dyn FileSystem>) -> Result<(), SystemError> { 122 kinfo!("VFS: Migrating filesystems..."); 123 124 // ==== 在这里获取要被迁移的文件系统的inode === 125 let binding = ROOT_INODE().find("proc").expect("ProcFS not mounted!").fs(); 126 let proc: &MountFS = binding.as_any_ref().downcast_ref::<MountFS>().unwrap(); 127 let binding = ROOT_INODE().find("dev").expect("DevFS not mounted!").fs(); 128 let dev: &MountFS = binding.as_any_ref().downcast_ref::<MountFS>().unwrap(); 129 130 let new_fs = MountFS::new(new_fs, None); 131 // 获取新的根文件系统的根节点的引用 132 let new_root_inode = Box::leak(Box::new(new_fs.root_inode())); 133 134 // 把上述文件系统,迁移到新的文件系统下 135 do_migrate(new_root_inode.clone(), "proc", proc)?; 136 do_migrate(new_root_inode.clone(), "dev", dev)?; 137 138 unsafe { 139 // drop旧的Root inode 140 let old_root_inode: Box<Arc<dyn IndexNode>> = Box::from_raw(__ROOT_INODE); 141 __ROOT_INODE = null_mut(); 142 drop(old_root_inode); 143 144 // 设置全局的新的ROOT Inode 145 __ROOT_INODE = new_root_inode; 146 } 147 148 kinfo!("VFS: Migrate filesystems done!"); 149 150 return Ok(()); 151 } 152 153 #[no_mangle] 154 pub extern "C" fn mount_root_fs() -> i32 { 155 kinfo!("Try to mount FAT32 as root fs..."); 156 let partiton: Arc<crate::io::disk_info::Partition> = 157 ahci::get_disks_by_name("ahci_disk_0".to_string()) 158 .unwrap() 159 .0 160 .lock() 161 .partitions[0] 162 .clone(); 163 164 let fatfs: Result<Arc<FATFileSystem>, SystemError> = FATFileSystem::new(partiton); 165 if fatfs.is_err() { 166 kerror!( 167 "Failed to initialize fatfs, code={:?}", 168 fatfs.as_ref().err() 169 ); 170 loop { 171 spin_loop(); 172 } 173 } 174 let fatfs: Arc<FATFileSystem> = fatfs.unwrap(); 175 let r = migrate_virtual_filesystem(fatfs); 176 if r.is_err() { 177 kerror!("Failed to migrate virtual filesystem to FAT32!"); 178 loop { 179 spin_loop(); 180 } 181 } 182 kinfo!("Successfully migrate rootfs to FAT32!"); 183 184 return 0; 185 } 186 187 /// @brief 为当前进程打开一个文件 188 pub fn do_open(path: &str, mode: FileMode) -> Result<i32, SystemError> { 189 // 文件名过长 190 if path.len() > PAGE_4K_SIZE as usize { 191 return Err(SystemError::ENAMETOOLONG); 192 } 193 194 let inode: Result<Arc<dyn IndexNode>, SystemError> = ROOT_INODE().lookup(path); 195 196 let inode: Arc<dyn IndexNode> = if inode.is_err() { 197 let errno = inode.unwrap_err(); 198 // 文件不存在,且需要创建 199 if mode.contains(FileMode::O_CREAT) 200 && !mode.contains(FileMode::O_DIRECTORY) 201 && errno == SystemError::ENOENT 202 { 203 let (filename, parent_path) = rsplit_path(path); 204 // 查找父目录 205 let parent_inode: Arc<dyn IndexNode> = 206 ROOT_INODE().lookup(parent_path.unwrap_or("/"))?; 207 // 创建文件 208 let inode: Arc<dyn IndexNode> = parent_inode.create(filename, FileType::File, 0o777)?; 209 inode 210 } else { 211 // 不需要创建文件,因此返回错误码 212 return Err(errno); 213 } 214 } else { 215 inode.unwrap() 216 }; 217 218 let file_type: FileType = inode.metadata()?.file_type; 219 // 如果要打开的是文件夹,而目标不是文件夹 220 if mode.contains(FileMode::O_DIRECTORY) && file_type != FileType::Dir { 221 return Err(SystemError::ENOTDIR); 222 } 223 224 // 如果O_TRUNC,并且,打开模式包含O_RDWR或O_WRONLY,清空文件 225 if mode.contains(FileMode::O_TRUNC) 226 && (mode.contains(FileMode::O_RDWR) || mode.contains(FileMode::O_WRONLY)) 227 && file_type == FileType::File 228 { 229 inode.truncate(0)?; 230 } 231 232 // 创建文件对象 233 let mut file: File = File::new(inode, mode)?; 234 235 // 打开模式为“追加” 236 if mode.contains(FileMode::O_APPEND) { 237 file.lseek(SeekFrom::SeekEnd(0))?; 238 } 239 240 // 把文件对象存入pcb 241 return current_pcb().alloc_fd(file, None); 242 } 243 244 /// @brief 根据文件描述符,读取文件数据。尝试读取的数据长度与buf的长度相同。 245 /// 246 /// @param fd 文件描述符编号 247 /// @param buf 输出缓冲区。 248 /// 249 /// @return Ok(usize) 成功读取的数据的字节数 250 /// @return Err(SystemError) 读取失败,返回posix错误码 251 pub fn do_read(fd: i32, buf: &mut [u8]) -> Result<usize, SystemError> { 252 let file: Option<&mut File> = current_pcb().get_file_mut_by_fd(fd); 253 if file.is_none() { 254 return Err(SystemError::EBADF); 255 } 256 let file: &mut File = file.unwrap(); 257 258 return file.read(buf.len(), buf); 259 } 260 261 /// @brief 根据文件描述符,向文件写入数据。尝试写入的数据长度与buf的长度相同。 262 /// 263 /// @param fd 文件描述符编号 264 /// @param buf 输入缓冲区。 265 /// 266 /// @return Ok(usize) 成功写入的数据的字节数 267 /// @return Err(SystemError) 写入失败,返回posix错误码 268 pub fn do_write(fd: i32, buf: &[u8]) -> Result<usize, SystemError> { 269 let file: Option<&mut File> = current_pcb().get_file_mut_by_fd(fd); 270 if file.is_none() { 271 return Err(SystemError::EBADF); 272 } 273 let file: &mut File = file.unwrap(); 274 275 return file.write(buf.len(), buf); 276 } 277 278 /// @brief 调整文件操作指针的位置 279 /// 280 /// @param fd 文件描述符编号 281 /// @param seek 调整的方式 282 /// 283 /// @return Ok(usize) 调整后,文件访问指针相对于文件头部的偏移量 284 /// @return Err(SystemError) 调整失败,返回posix错误码 285 pub fn do_lseek(fd: i32, seek: SeekFrom) -> Result<usize, SystemError> { 286 let file: Option<&mut File> = current_pcb().get_file_mut_by_fd(fd); 287 if file.is_none() { 288 return Err(SystemError::EBADF); 289 } 290 let file: &mut File = file.unwrap(); 291 return file.lseek(seek); 292 } 293 294 /// @brief 创建文件/文件夹 295 pub fn do_mkdir(path: &str, _mode: FileMode) -> Result<u64, SystemError> { 296 // 文件名过长 297 if path.len() > PAGE_4K_SIZE as usize { 298 return Err(SystemError::ENAMETOOLONG); 299 } 300 301 let inode: Result<Arc<dyn IndexNode>, SystemError> = ROOT_INODE().lookup(path); 302 303 if inode.is_err() { 304 let errno = inode.unwrap_err(); 305 // 文件不存在,且需要创建 306 if errno == SystemError::ENOENT { 307 let (filename, parent_path) = rsplit_path(path); 308 // 查找父目录 309 let parent_inode: Arc<dyn IndexNode> = 310 ROOT_INODE().lookup(parent_path.unwrap_or("/"))?; 311 // 创建文件夹 312 let _create_inode: Arc<dyn IndexNode> = 313 parent_inode.create(filename, FileType::Dir, 0o777)?; 314 } else { 315 // 不需要创建文件,因此返回错误码 316 return Err(errno); 317 } 318 } 319 320 return Ok(0); 321 } 322 323 /// @breif 删除文件夹 324 pub fn do_remove_dir(path: &str) -> Result<u64, SystemError> { 325 // 文件名过长 326 if path.len() > PAGE_4K_SIZE as usize { 327 return Err(SystemError::ENAMETOOLONG); 328 } 329 330 let inode: Result<Arc<dyn IndexNode>, SystemError> = ROOT_INODE().lookup(path); 331 332 if inode.is_err() { 333 let errno = inode.unwrap_err(); 334 // 文件不存在 335 if errno == SystemError::ENOENT { 336 return Err(SystemError::ENOENT); 337 } 338 } 339 340 let (filename, parent_path) = rsplit_path(path); 341 // 查找父目录 342 let parent_inode: Arc<dyn IndexNode> = ROOT_INODE().lookup(parent_path.unwrap_or("/"))?; 343 344 if parent_inode.metadata()?.file_type != FileType::Dir { 345 return Err(SystemError::ENOTDIR); 346 } 347 348 let target_inode: Arc<dyn IndexNode> = parent_inode.find(filename)?; 349 if target_inode.metadata()?.file_type != FileType::Dir { 350 return Err(SystemError::ENOTDIR); 351 } 352 353 // 删除文件夹 354 parent_inode.rmdir(filename)?; 355 356 return Ok(0); 357 } 358 359 /// @brief 删除文件 360 pub fn do_unlink_at(path: &str, _mode: FileMode) -> Result<u64, SystemError> { 361 // 文件名过长 362 if path.len() > PAGE_4K_SIZE as usize { 363 return Err(SystemError::ENAMETOOLONG); 364 } 365 366 let inode: Result<Arc<dyn IndexNode>, SystemError> = ROOT_INODE().lookup(path); 367 368 if inode.is_err() { 369 let errno = inode.clone().unwrap_err(); 370 // 文件不存在,且需要创建 371 if errno == SystemError::ENOENT { 372 return Err(SystemError::ENOENT); 373 } 374 } 375 // 禁止在目录上unlink 376 if inode.unwrap().metadata()?.file_type == FileType::Dir { 377 return Err(SystemError::EPERM); 378 } 379 380 let (filename, parent_path) = rsplit_path(path); 381 // 查找父目录 382 let parent_inode: Arc<dyn IndexNode> = ROOT_INODE().lookup(parent_path.unwrap_or("/"))?; 383 384 if parent_inode.metadata()?.file_type != FileType::Dir { 385 return Err(SystemError::ENOTDIR); 386 } 387 388 // 删除文件 389 parent_inode.unlink(filename)?; 390 391 return Ok(0); 392 } 393