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