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::{EBADF, ENAMETOOLONG, ENOENT, ENOTDIR, EPERM, PAGE_4K_SIZE}, 20 io::SeekFrom, 21 kerror, kinfo, 22 }; 23 24 use super::{file::FileMode, utils::rsplit_path, IndexNode, InodeId}; 25 26 /// @brief 原子地生成新的Inode号。 27 /// 请注意,所有的inode号都需要通过该函数来生成.全局的inode号,除了以下两个特殊的以外,都是唯一的 28 /// 特殊的两个inode号: 29 /// [0]: 对应'.'目录项 30 /// [1]: 对应'..'目录项 31 pub fn generate_inode_id() -> InodeId { 32 static INO: AtomicUsize = AtomicUsize::new(1); 33 return INO.fetch_add(1, Ordering::SeqCst); 34 } 35 36 static mut __ROOT_INODE: *mut Arc<dyn IndexNode> = null_mut(); 37 38 /// @brief 获取全局的根节点 39 #[inline(always)] 40 #[allow(non_snake_case)] 41 pub fn ROOT_INODE() -> Arc<dyn IndexNode> { 42 unsafe { 43 return __ROOT_INODE.as_ref().unwrap().clone(); 44 } 45 } 46 47 #[no_mangle] 48 pub extern "C" fn vfs_init() -> i32 { 49 // 使用Ramfs作为默认的根文件系统 50 let ramfs = RamFS::new(); 51 let mount_fs = MountFS::new(ramfs, None); 52 let root_inode = Box::leak(Box::new(mount_fs.root_inode())); 53 54 unsafe { 55 __ROOT_INODE = root_inode; 56 } 57 58 // 创建文件夹 59 root_inode 60 .create("proc", FileType::Dir, 0o777) 61 .expect("Failed to create /proc"); 62 root_inode 63 .create("dev", FileType::Dir, 0o777) 64 .expect("Failed to create /dev"); 65 66 // // 创建procfs实例 67 let procfs: Arc<ProcFS> = ProcFS::new(); 68 69 // procfs挂载 70 let _t = root_inode 71 .find("proc") 72 .expect("Cannot find /proc") 73 .mount(procfs) 74 .expect("Failed to mount procfs."); 75 kinfo!("ProcFS mounted."); 76 77 // 创建 devfs 实例 78 let devfs: Arc<DevFS> = DevFS::new(); 79 // devfs 挂载 80 let _t = root_inode 81 .find("dev") 82 .expect("Cannot find /dev") 83 .mount(devfs) 84 .expect("Failed to mount devfs"); 85 kinfo!("DevFS mounted."); 86 87 let root_inode = ROOT_INODE().list().expect("VFS init failed"); 88 if root_inode.len() > 0 { 89 kinfo!("Successfully initialized VFS!"); 90 } 91 return 0; 92 } 93 94 /// @brief 真正执行伪文件系统迁移的过程 95 /// 96 /// @param mountpoint_name 在根目录下的挂载点的名称 97 /// @param inode 原本的挂载点的inode 98 fn do_migrate( 99 new_root_inode: Arc<dyn IndexNode>, 100 mountpoint_name: &str, 101 fs: &MountFS, 102 ) -> Result<(), i32> { 103 let r = new_root_inode.find(mountpoint_name); 104 let mountpoint = if r.is_err() { 105 new_root_inode 106 .create(mountpoint_name, FileType::Dir, 0o777) 107 .expect(format!("Failed to create '/{mountpoint_name}'").as_str()) 108 } else { 109 r.unwrap() 110 }; 111 // 迁移挂载点 112 mountpoint 113 .mount(fs.inner_filesystem()) 114 .expect(format!("Failed to migrate {mountpoint_name}").as_str()); 115 116 return Ok(()); 117 } 118 119 /// @brief 迁移伪文件系统的inode 120 /// 请注意,为了避免删掉了伪文件系统内的信息,因此没有在原root inode那里调用unlink. 121 fn migrate_virtual_filesystem(new_fs: Arc<dyn FileSystem>) -> Result<(), i32> { 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>, i32> = 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, i32> { 189 // 文件名过长 190 if path.len() > PAGE_4K_SIZE as usize { 191 return Err(-(ENAMETOOLONG as i32)); 192 } 193 194 let inode: Result<Arc<dyn IndexNode>, i32> = 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 == -(ENOENT as i32) 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(-(ENOTDIR as i32)); 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); 242 } 243 244 /// @brief 根据文件描述符,读取文件数据。尝试读取的数据长度与buf的长度相同。 245 /// 246 /// @param fd 文件描述符编号 247 /// @param buf 输出缓冲区。 248 /// 249 /// @return Ok(usize) 成功读取的数据的字节数 250 /// @return Err(i32) 读取失败,返回posix错误码 251 pub fn do_read(fd: i32, buf: &mut [u8]) -> Result<usize, i32> { 252 let file: Option<&mut File> = current_pcb().get_file_mut_by_fd(fd); 253 if file.is_none() { 254 return Err(-(EBADF as i32)); 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(i32) 写入失败,返回posix错误码 268 pub fn do_write(fd: i32, buf: &[u8]) -> Result<usize, i32> { 269 let file: Option<&mut File> = current_pcb().get_file_mut_by_fd(fd); 270 if file.is_none() { 271 return Err(-(EBADF as i32)); 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(i32) 调整失败,返回posix错误码 285 pub fn do_lseek(fd: i32, seek: SeekFrom) -> Result<usize, i32> { 286 let file: Option<&mut File> = current_pcb().get_file_mut_by_fd(fd); 287 if file.is_none() { 288 return Err(-(EBADF as i32)); 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, i32> { 296 // 文件名过长 297 if path.len() > PAGE_4K_SIZE as usize { 298 return Err(-(ENAMETOOLONG as i32)); 299 } 300 301 let inode: Result<Arc<dyn IndexNode>, i32> = ROOT_INODE().lookup(path); 302 303 if inode.is_err() { 304 let errno = inode.unwrap_err(); 305 // 文件不存在,且需要创建 306 if errno == -(ENOENT as i32) { 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, i32> { 325 // 文件名过长 326 if path.len() > PAGE_4K_SIZE as usize { 327 return Err(-(ENAMETOOLONG as i32)); 328 } 329 330 let inode: Result<Arc<dyn IndexNode>, i32> = ROOT_INODE().lookup(path); 331 332 if inode.is_err() { 333 let errno = inode.unwrap_err(); 334 // 文件不存在 335 if errno == -(ENOENT as i32) { 336 return Err(-(ENOENT as i32)); 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(-(ENOTDIR as i32)); 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(-(ENOTDIR as i32)); 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, i32> { 361 // 文件名过长 362 if path.len() > PAGE_4K_SIZE as usize { 363 return Err(-(ENAMETOOLONG as i32)); 364 } 365 366 let inode: Result<Arc<dyn IndexNode>, i32> = ROOT_INODE().lookup(path); 367 368 if inode.is_err() { 369 let errno = inode.clone().unwrap_err(); 370 // 文件不存在,且需要创建 371 if errno == -(ENOENT as i32) { 372 return Err(-(ENOENT as i32)); 373 } 374 } 375 // 禁止在目录上unlink 376 if inode.unwrap().metadata()?.file_type == FileType::Dir { 377 return Err(-(EPERM as i32)); 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(-(ENOTDIR as i32)); 386 } 387 388 // 删除文件 389 parent_inode.unlink(filename)?; 390 391 return Ok(0); 392 } 393