1004e86ffSlogin use core::{ 2004e86ffSlogin hint::spin_loop, 3004e86ffSlogin ptr::null_mut, 4004e86ffSlogin sync::atomic::{AtomicUsize, Ordering}, 5004e86ffSlogin }; 6004e86ffSlogin 7004e86ffSlogin use alloc::{boxed::Box, format, string::ToString, sync::Arc}; 8004e86ffSlogin 9004e86ffSlogin use crate::{ 10004e86ffSlogin arch::asm::current::current_pcb, 11004e86ffSlogin driver::disk::ahci::{self}, 12004e86ffSlogin filesystem::{ 13004e86ffSlogin devfs::DevFS, 14004e86ffSlogin fat::fs::FATFileSystem, 15004e86ffSlogin procfs::ProcFS, 16004e86ffSlogin ramfs::RamFS, 17*dd9f1fc1STingHuang sysfs::SysFS, 18004e86ffSlogin vfs::{file::File, mount::MountFS, FileSystem, FileType}, 19004e86ffSlogin }, 202b771e32SGou Ngai include::bindings::bindings::PAGE_4K_SIZE, 21004e86ffSlogin io::SeekFrom, 222b771e32SGou Ngai kerror, kinfo, 232b771e32SGou Ngai syscall::SystemError, 24004e86ffSlogin }; 25004e86ffSlogin 26004e86ffSlogin use super::{file::FileMode, utils::rsplit_path, IndexNode, InodeId}; 27004e86ffSlogin 28004e86ffSlogin /// @brief 原子地生成新的Inode号。 29004e86ffSlogin /// 请注意,所有的inode号都需要通过该函数来生成.全局的inode号,除了以下两个特殊的以外,都是唯一的 30004e86ffSlogin /// 特殊的两个inode号: 31004e86ffSlogin /// [0]: 对应'.'目录项 32004e86ffSlogin /// [1]: 对应'..'目录项 33004e86ffSlogin pub fn generate_inode_id() -> InodeId { 34004e86ffSlogin static INO: AtomicUsize = AtomicUsize::new(1); 35004e86ffSlogin return INO.fetch_add(1, Ordering::SeqCst); 36004e86ffSlogin } 37004e86ffSlogin 38004e86ffSlogin static mut __ROOT_INODE: *mut Arc<dyn IndexNode> = null_mut(); 39004e86ffSlogin 40004e86ffSlogin /// @brief 获取全局的根节点 41004e86ffSlogin #[inline(always)] 42004e86ffSlogin #[allow(non_snake_case)] 43004e86ffSlogin pub fn ROOT_INODE() -> Arc<dyn IndexNode> { 44004e86ffSlogin unsafe { 45004e86ffSlogin return __ROOT_INODE.as_ref().unwrap().clone(); 46004e86ffSlogin } 47004e86ffSlogin } 48004e86ffSlogin 49004e86ffSlogin #[no_mangle] 50004e86ffSlogin pub extern "C" fn vfs_init() -> i32 { 51004e86ffSlogin // 使用Ramfs作为默认的根文件系统 52004e86ffSlogin let ramfs = RamFS::new(); 53004e86ffSlogin let mount_fs = MountFS::new(ramfs, None); 54004e86ffSlogin let root_inode = Box::leak(Box::new(mount_fs.root_inode())); 55004e86ffSlogin 56004e86ffSlogin unsafe { 57004e86ffSlogin __ROOT_INODE = root_inode; 58004e86ffSlogin } 59004e86ffSlogin 60004e86ffSlogin // 创建文件夹 61004e86ffSlogin root_inode 62004e86ffSlogin .create("proc", FileType::Dir, 0o777) 63004e86ffSlogin .expect("Failed to create /proc"); 64004e86ffSlogin root_inode 65004e86ffSlogin .create("dev", FileType::Dir, 0o777) 66004e86ffSlogin .expect("Failed to create /dev"); 67*dd9f1fc1STingHuang root_inode 68*dd9f1fc1STingHuang .create("sys", FileType::Dir, 0o777) 69*dd9f1fc1STingHuang .expect("Failed to create /sys"); 70004e86ffSlogin 71004e86ffSlogin // // 创建procfs实例 72004e86ffSlogin let procfs: Arc<ProcFS> = ProcFS::new(); 73004e86ffSlogin 74004e86ffSlogin // procfs挂载 75004e86ffSlogin let _t = root_inode 76004e86ffSlogin .find("proc") 77004e86ffSlogin .expect("Cannot find /proc") 78004e86ffSlogin .mount(procfs) 79004e86ffSlogin .expect("Failed to mount procfs."); 80004e86ffSlogin kinfo!("ProcFS mounted."); 81004e86ffSlogin 82004e86ffSlogin // 创建 devfs 实例 83004e86ffSlogin let devfs: Arc<DevFS> = DevFS::new(); 84004e86ffSlogin // devfs 挂载 85004e86ffSlogin let _t = root_inode 86004e86ffSlogin .find("dev") 87004e86ffSlogin .expect("Cannot find /dev") 88004e86ffSlogin .mount(devfs) 89004e86ffSlogin .expect("Failed to mount devfs"); 90004e86ffSlogin kinfo!("DevFS mounted."); 91004e86ffSlogin 92*dd9f1fc1STingHuang // 创建 sysfs 实例 93*dd9f1fc1STingHuang let sysfs: Arc<SysFS> = SysFS::new(); 94*dd9f1fc1STingHuang // sysfs 挂载 95*dd9f1fc1STingHuang let _t = root_inode 96*dd9f1fc1STingHuang .find("sys") 97*dd9f1fc1STingHuang .expect("Cannot find /sys") 98*dd9f1fc1STingHuang .mount(sysfs) 99*dd9f1fc1STingHuang .expect("Failed to mount sysfs"); 100*dd9f1fc1STingHuang kinfo!("SysFS mounted."); 101*dd9f1fc1STingHuang 102004e86ffSlogin let root_inode = ROOT_INODE().list().expect("VFS init failed"); 103004e86ffSlogin if root_inode.len() > 0 { 104004e86ffSlogin kinfo!("Successfully initialized VFS!"); 105004e86ffSlogin } 106004e86ffSlogin return 0; 107004e86ffSlogin } 108004e86ffSlogin 109004e86ffSlogin /// @brief 真正执行伪文件系统迁移的过程 110004e86ffSlogin /// 111004e86ffSlogin /// @param mountpoint_name 在根目录下的挂载点的名称 112004e86ffSlogin /// @param inode 原本的挂载点的inode 113004e86ffSlogin fn do_migrate( 114004e86ffSlogin new_root_inode: Arc<dyn IndexNode>, 115004e86ffSlogin mountpoint_name: &str, 116004e86ffSlogin fs: &MountFS, 117676b8ef6SMork ) -> Result<(), SystemError> { 118004e86ffSlogin let r = new_root_inode.find(mountpoint_name); 119004e86ffSlogin let mountpoint = if r.is_err() { 120004e86ffSlogin new_root_inode 121004e86ffSlogin .create(mountpoint_name, FileType::Dir, 0o777) 122004e86ffSlogin .expect(format!("Failed to create '/{mountpoint_name}'").as_str()) 123004e86ffSlogin } else { 124004e86ffSlogin r.unwrap() 125004e86ffSlogin }; 126004e86ffSlogin // 迁移挂载点 127004e86ffSlogin mountpoint 128004e86ffSlogin .mount(fs.inner_filesystem()) 129004e86ffSlogin .expect(format!("Failed to migrate {mountpoint_name}").as_str()); 130004e86ffSlogin return Ok(()); 131004e86ffSlogin } 132004e86ffSlogin 133004e86ffSlogin /// @brief 迁移伪文件系统的inode 134004e86ffSlogin /// 请注意,为了避免删掉了伪文件系统内的信息,因此没有在原root inode那里调用unlink. 135676b8ef6SMork fn migrate_virtual_filesystem(new_fs: Arc<dyn FileSystem>) -> Result<(), SystemError> { 136004e86ffSlogin kinfo!("VFS: Migrating filesystems..."); 137004e86ffSlogin 138004e86ffSlogin // ==== 在这里获取要被迁移的文件系统的inode === 139004e86ffSlogin let binding = ROOT_INODE().find("proc").expect("ProcFS not mounted!").fs(); 140004e86ffSlogin let proc: &MountFS = binding.as_any_ref().downcast_ref::<MountFS>().unwrap(); 141004e86ffSlogin let binding = ROOT_INODE().find("dev").expect("DevFS not mounted!").fs(); 142004e86ffSlogin let dev: &MountFS = binding.as_any_ref().downcast_ref::<MountFS>().unwrap(); 143*dd9f1fc1STingHuang let binding = ROOT_INODE().find("sys").expect("SysFs not mounted!").fs(); 144*dd9f1fc1STingHuang let sys: &MountFS = binding.as_any_ref().downcast_ref::<MountFS>().unwrap(); 145004e86ffSlogin 146004e86ffSlogin let new_fs = MountFS::new(new_fs, None); 147004e86ffSlogin // 获取新的根文件系统的根节点的引用 148004e86ffSlogin let new_root_inode = Box::leak(Box::new(new_fs.root_inode())); 149004e86ffSlogin 150004e86ffSlogin // 把上述文件系统,迁移到新的文件系统下 151004e86ffSlogin do_migrate(new_root_inode.clone(), "proc", proc)?; 152004e86ffSlogin do_migrate(new_root_inode.clone(), "dev", dev)?; 153*dd9f1fc1STingHuang do_migrate(new_root_inode.clone(), "sys", sys)?; 154004e86ffSlogin 155004e86ffSlogin unsafe { 156004e86ffSlogin // drop旧的Root inode 157004e86ffSlogin let old_root_inode: Box<Arc<dyn IndexNode>> = Box::from_raw(__ROOT_INODE); 158004e86ffSlogin __ROOT_INODE = null_mut(); 159004e86ffSlogin drop(old_root_inode); 160004e86ffSlogin 161004e86ffSlogin // 设置全局的新的ROOT Inode 162004e86ffSlogin __ROOT_INODE = new_root_inode; 163004e86ffSlogin } 164004e86ffSlogin 165004e86ffSlogin kinfo!("VFS: Migrate filesystems done!"); 166004e86ffSlogin 167004e86ffSlogin return Ok(()); 168004e86ffSlogin } 169004e86ffSlogin 170004e86ffSlogin #[no_mangle] 171004e86ffSlogin pub extern "C" fn mount_root_fs() -> i32 { 172004e86ffSlogin kinfo!("Try to mount FAT32 as root fs..."); 173004e86ffSlogin let partiton: Arc<crate::io::disk_info::Partition> = 174004e86ffSlogin ahci::get_disks_by_name("ahci_disk_0".to_string()) 175004e86ffSlogin .unwrap() 176004e86ffSlogin .0 177004e86ffSlogin .lock() 178004e86ffSlogin .partitions[0] 179004e86ffSlogin .clone(); 180004e86ffSlogin 181676b8ef6SMork let fatfs: Result<Arc<FATFileSystem>, SystemError> = FATFileSystem::new(partiton); 182004e86ffSlogin if fatfs.is_err() { 183004e86ffSlogin kerror!( 184004e86ffSlogin "Failed to initialize fatfs, code={:?}", 185004e86ffSlogin fatfs.as_ref().err() 186004e86ffSlogin ); 187004e86ffSlogin loop { 188004e86ffSlogin spin_loop(); 189004e86ffSlogin } 190004e86ffSlogin } 191004e86ffSlogin let fatfs: Arc<FATFileSystem> = fatfs.unwrap(); 192004e86ffSlogin let r = migrate_virtual_filesystem(fatfs); 193004e86ffSlogin if r.is_err() { 194004e86ffSlogin kerror!("Failed to migrate virtual filesystem to FAT32!"); 195004e86ffSlogin loop { 196004e86ffSlogin spin_loop(); 197004e86ffSlogin } 198004e86ffSlogin } 199004e86ffSlogin kinfo!("Successfully migrate rootfs to FAT32!"); 200004e86ffSlogin 201004e86ffSlogin return 0; 202004e86ffSlogin } 203004e86ffSlogin 204004e86ffSlogin /// @brief 为当前进程打开一个文件 205676b8ef6SMork pub fn do_open(path: &str, mode: FileMode) -> Result<i32, SystemError> { 206004e86ffSlogin // 文件名过长 207004e86ffSlogin if path.len() > PAGE_4K_SIZE as usize { 208676b8ef6SMork return Err(SystemError::ENAMETOOLONG); 209004e86ffSlogin } 210004e86ffSlogin 211676b8ef6SMork let inode: Result<Arc<dyn IndexNode>, SystemError> = ROOT_INODE().lookup(path); 212004e86ffSlogin 213004e86ffSlogin let inode: Arc<dyn IndexNode> = if inode.is_err() { 214004e86ffSlogin let errno = inode.unwrap_err(); 215004e86ffSlogin // 文件不存在,且需要创建 216004e86ffSlogin if mode.contains(FileMode::O_CREAT) 217004e86ffSlogin && !mode.contains(FileMode::O_DIRECTORY) 218676b8ef6SMork && errno == SystemError::ENOENT 219004e86ffSlogin { 220004e86ffSlogin let (filename, parent_path) = rsplit_path(path); 221004e86ffSlogin // 查找父目录 222004e86ffSlogin let parent_inode: Arc<dyn IndexNode> = 223004e86ffSlogin ROOT_INODE().lookup(parent_path.unwrap_or("/"))?; 224004e86ffSlogin // 创建文件 225004e86ffSlogin let inode: Arc<dyn IndexNode> = parent_inode.create(filename, FileType::File, 0o777)?; 226004e86ffSlogin inode 227004e86ffSlogin } else { 228004e86ffSlogin // 不需要创建文件,因此返回错误码 229004e86ffSlogin return Err(errno); 230004e86ffSlogin } 231004e86ffSlogin } else { 232004e86ffSlogin inode.unwrap() 233004e86ffSlogin }; 234004e86ffSlogin 235004e86ffSlogin let file_type: FileType = inode.metadata()?.file_type; 236004e86ffSlogin // 如果要打开的是文件夹,而目标不是文件夹 237004e86ffSlogin if mode.contains(FileMode::O_DIRECTORY) && file_type != FileType::Dir { 238676b8ef6SMork return Err(SystemError::ENOTDIR); 239004e86ffSlogin } 240004e86ffSlogin 241004e86ffSlogin // 如果O_TRUNC,并且,打开模式包含O_RDWR或O_WRONLY,清空文件 242004e86ffSlogin if mode.contains(FileMode::O_TRUNC) 243004e86ffSlogin && (mode.contains(FileMode::O_RDWR) || mode.contains(FileMode::O_WRONLY)) 244004e86ffSlogin && file_type == FileType::File 245004e86ffSlogin { 246004e86ffSlogin inode.truncate(0)?; 247004e86ffSlogin } 248004e86ffSlogin 249004e86ffSlogin // 创建文件对象 250004e86ffSlogin let mut file: File = File::new(inode, mode)?; 251004e86ffSlogin 252004e86ffSlogin // 打开模式为“追加” 253004e86ffSlogin if mode.contains(FileMode::O_APPEND) { 254004e86ffSlogin file.lseek(SeekFrom::SeekEnd(0))?; 255004e86ffSlogin } 256004e86ffSlogin 257004e86ffSlogin // 把文件对象存入pcb 2582b771e32SGou Ngai return current_pcb().alloc_fd(file, None); 259004e86ffSlogin } 260004e86ffSlogin 261004e86ffSlogin /// @brief 根据文件描述符,读取文件数据。尝试读取的数据长度与buf的长度相同。 262004e86ffSlogin /// 263004e86ffSlogin /// @param fd 文件描述符编号 264004e86ffSlogin /// @param buf 输出缓冲区。 265004e86ffSlogin /// 266004e86ffSlogin /// @return Ok(usize) 成功读取的数据的字节数 267676b8ef6SMork /// @return Err(SystemError) 读取失败,返回posix错误码 268676b8ef6SMork pub fn do_read(fd: i32, buf: &mut [u8]) -> Result<usize, SystemError> { 269004e86ffSlogin let file: Option<&mut File> = current_pcb().get_file_mut_by_fd(fd); 270004e86ffSlogin if file.is_none() { 271676b8ef6SMork return Err(SystemError::EBADF); 272004e86ffSlogin } 273004e86ffSlogin let file: &mut File = file.unwrap(); 274004e86ffSlogin 275004e86ffSlogin return file.read(buf.len(), buf); 276004e86ffSlogin } 277004e86ffSlogin 278004e86ffSlogin /// @brief 根据文件描述符,向文件写入数据。尝试写入的数据长度与buf的长度相同。 279004e86ffSlogin /// 280004e86ffSlogin /// @param fd 文件描述符编号 281004e86ffSlogin /// @param buf 输入缓冲区。 282004e86ffSlogin /// 283004e86ffSlogin /// @return Ok(usize) 成功写入的数据的字节数 284676b8ef6SMork /// @return Err(SystemError) 写入失败,返回posix错误码 285676b8ef6SMork pub fn do_write(fd: i32, buf: &[u8]) -> Result<usize, SystemError> { 286004e86ffSlogin let file: Option<&mut File> = current_pcb().get_file_mut_by_fd(fd); 287004e86ffSlogin if file.is_none() { 288676b8ef6SMork return Err(SystemError::EBADF); 289004e86ffSlogin } 290004e86ffSlogin let file: &mut File = file.unwrap(); 291004e86ffSlogin 292004e86ffSlogin return file.write(buf.len(), buf); 293004e86ffSlogin } 294004e86ffSlogin 295004e86ffSlogin /// @brief 调整文件操作指针的位置 296004e86ffSlogin /// 297004e86ffSlogin /// @param fd 文件描述符编号 298004e86ffSlogin /// @param seek 调整的方式 299004e86ffSlogin /// 300004e86ffSlogin /// @return Ok(usize) 调整后,文件访问指针相对于文件头部的偏移量 301676b8ef6SMork /// @return Err(SystemError) 调整失败,返回posix错误码 302676b8ef6SMork pub fn do_lseek(fd: i32, seek: SeekFrom) -> Result<usize, SystemError> { 303004e86ffSlogin let file: Option<&mut File> = current_pcb().get_file_mut_by_fd(fd); 304004e86ffSlogin if file.is_none() { 305676b8ef6SMork return Err(SystemError::EBADF); 306004e86ffSlogin } 307004e86ffSlogin let file: &mut File = file.unwrap(); 308004e86ffSlogin return file.lseek(seek); 309004e86ffSlogin } 310004e86ffSlogin 311004e86ffSlogin /// @brief 创建文件/文件夹 312676b8ef6SMork pub fn do_mkdir(path: &str, _mode: FileMode) -> Result<u64, SystemError> { 313004e86ffSlogin // 文件名过长 314004e86ffSlogin if path.len() > PAGE_4K_SIZE as usize { 315676b8ef6SMork return Err(SystemError::ENAMETOOLONG); 316004e86ffSlogin } 317004e86ffSlogin 318676b8ef6SMork let inode: Result<Arc<dyn IndexNode>, SystemError> = ROOT_INODE().lookup(path); 319004e86ffSlogin 320004e86ffSlogin if inode.is_err() { 321004e86ffSlogin let errno = inode.unwrap_err(); 322004e86ffSlogin // 文件不存在,且需要创建 323676b8ef6SMork if errno == SystemError::ENOENT { 324004e86ffSlogin let (filename, parent_path) = rsplit_path(path); 325004e86ffSlogin // 查找父目录 326004e86ffSlogin let parent_inode: Arc<dyn IndexNode> = 327004e86ffSlogin ROOT_INODE().lookup(parent_path.unwrap_or("/"))?; 328004e86ffSlogin // 创建文件夹 329004e86ffSlogin let _create_inode: Arc<dyn IndexNode> = 330004e86ffSlogin parent_inode.create(filename, FileType::Dir, 0o777)?; 331004e86ffSlogin } else { 332004e86ffSlogin // 不需要创建文件,因此返回错误码 333004e86ffSlogin return Err(errno); 334004e86ffSlogin } 335004e86ffSlogin } 336004e86ffSlogin 337004e86ffSlogin return Ok(0); 338004e86ffSlogin } 339004e86ffSlogin 340004e86ffSlogin /// @breif 删除文件夹 341676b8ef6SMork pub fn do_remove_dir(path: &str) -> Result<u64, SystemError> { 342004e86ffSlogin // 文件名过长 343004e86ffSlogin if path.len() > PAGE_4K_SIZE as usize { 344676b8ef6SMork return Err(SystemError::ENAMETOOLONG); 345004e86ffSlogin } 346004e86ffSlogin 347676b8ef6SMork let inode: Result<Arc<dyn IndexNode>, SystemError> = ROOT_INODE().lookup(path); 348004e86ffSlogin 349004e86ffSlogin if inode.is_err() { 350004e86ffSlogin let errno = inode.unwrap_err(); 351004e86ffSlogin // 文件不存在 352676b8ef6SMork if errno == SystemError::ENOENT { 353676b8ef6SMork return Err(SystemError::ENOENT); 354004e86ffSlogin } 355004e86ffSlogin } 356004e86ffSlogin 357004e86ffSlogin let (filename, parent_path) = rsplit_path(path); 358004e86ffSlogin // 查找父目录 359004e86ffSlogin let parent_inode: Arc<dyn IndexNode> = ROOT_INODE().lookup(parent_path.unwrap_or("/"))?; 360004e86ffSlogin 361004e86ffSlogin if parent_inode.metadata()?.file_type != FileType::Dir { 362676b8ef6SMork return Err(SystemError::ENOTDIR); 363004e86ffSlogin } 364004e86ffSlogin 365004e86ffSlogin let target_inode: Arc<dyn IndexNode> = parent_inode.find(filename)?; 366004e86ffSlogin if target_inode.metadata()?.file_type != FileType::Dir { 367676b8ef6SMork return Err(SystemError::ENOTDIR); 368004e86ffSlogin } 369004e86ffSlogin 370004e86ffSlogin // 删除文件夹 371004e86ffSlogin parent_inode.rmdir(filename)?; 372004e86ffSlogin 373004e86ffSlogin return Ok(0); 374004e86ffSlogin } 375004e86ffSlogin 376004e86ffSlogin /// @brief 删除文件 377676b8ef6SMork pub fn do_unlink_at(path: &str, _mode: FileMode) -> Result<u64, SystemError> { 378004e86ffSlogin // 文件名过长 379004e86ffSlogin if path.len() > PAGE_4K_SIZE as usize { 380676b8ef6SMork return Err(SystemError::ENAMETOOLONG); 381004e86ffSlogin } 382004e86ffSlogin 383676b8ef6SMork let inode: Result<Arc<dyn IndexNode>, SystemError> = ROOT_INODE().lookup(path); 384004e86ffSlogin 385004e86ffSlogin if inode.is_err() { 386004e86ffSlogin let errno = inode.clone().unwrap_err(); 387004e86ffSlogin // 文件不存在,且需要创建 388676b8ef6SMork if errno == SystemError::ENOENT { 389676b8ef6SMork return Err(SystemError::ENOENT); 390004e86ffSlogin } 391004e86ffSlogin } 392004e86ffSlogin // 禁止在目录上unlink 393004e86ffSlogin if inode.unwrap().metadata()?.file_type == FileType::Dir { 394676b8ef6SMork return Err(SystemError::EPERM); 395004e86ffSlogin } 396004e86ffSlogin 397004e86ffSlogin let (filename, parent_path) = rsplit_path(path); 398004e86ffSlogin // 查找父目录 399004e86ffSlogin let parent_inode: Arc<dyn IndexNode> = ROOT_INODE().lookup(parent_path.unwrap_or("/"))?; 400004e86ffSlogin 401004e86ffSlogin if parent_inode.metadata()?.file_type != FileType::Dir { 402676b8ef6SMork return Err(SystemError::ENOTDIR); 403004e86ffSlogin } 404004e86ffSlogin 405004e86ffSlogin // 删除文件 406004e86ffSlogin parent_inode.unlink(filename)?; 407004e86ffSlogin 408004e86ffSlogin return Ok(0); 409004e86ffSlogin } 410