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 driver::disk::ahci::{self}, 11 filesystem::{ 12 devfs::DevFS, 13 fat::fs::FATFileSystem, 14 procfs::ProcFS, 15 ramfs::RamFS, 16 sysfs::SysFS, 17 vfs::{mount::MountFS, FileSystem, FileType}, 18 }, 19 include::bindings::bindings::PAGE_4K_SIZE, 20 kerror, kinfo, 21 syscall::SystemError, 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 root_inode 66 .create("sys", FileType::Dir, 0o777) 67 .expect("Failed to create /sys"); 68 69 // // 创建procfs实例 70 let procfs: Arc<ProcFS> = ProcFS::new(); 71 72 // procfs挂载 73 let _t = root_inode 74 .find("proc") 75 .expect("Cannot find /proc") 76 .mount(procfs) 77 .expect("Failed to mount procfs."); 78 kinfo!("ProcFS mounted."); 79 80 // 创建 devfs 实例 81 let devfs: Arc<DevFS> = DevFS::new(); 82 // devfs 挂载 83 let _t = root_inode 84 .find("dev") 85 .expect("Cannot find /dev") 86 .mount(devfs) 87 .expect("Failed to mount devfs"); 88 kinfo!("DevFS mounted."); 89 90 // 创建 sysfs 实例 91 let sysfs: Arc<SysFS> = SysFS::new(); 92 // sysfs 挂载 93 let _t = root_inode 94 .find("sys") 95 .expect("Cannot find /sys") 96 .mount(sysfs) 97 .expect("Failed to mount sysfs"); 98 kinfo!("SysFS mounted."); 99 100 let root_inode = ROOT_INODE().list().expect("VFS init failed"); 101 if root_inode.len() > 0 { 102 kinfo!("Successfully initialized VFS!"); 103 } 104 return 0; 105 } 106 107 /// @brief 真正执行伪文件系统迁移的过程 108 /// 109 /// @param mountpoint_name 在根目录下的挂载点的名称 110 /// @param inode 原本的挂载点的inode 111 fn do_migrate( 112 new_root_inode: Arc<dyn IndexNode>, 113 mountpoint_name: &str, 114 fs: &MountFS, 115 ) -> Result<(), SystemError> { 116 let r = new_root_inode.find(mountpoint_name); 117 let mountpoint = if r.is_err() { 118 new_root_inode 119 .create(mountpoint_name, FileType::Dir, 0o777) 120 .expect(format!("Failed to create '/{mountpoint_name}'").as_str()) 121 } else { 122 r.unwrap() 123 }; 124 // 迁移挂载点 125 mountpoint 126 .mount(fs.inner_filesystem()) 127 .expect(format!("Failed to migrate {mountpoint_name}").as_str()); 128 return Ok(()); 129 } 130 131 /// @brief 迁移伪文件系统的inode 132 /// 请注意,为了避免删掉了伪文件系统内的信息,因此没有在原root inode那里调用unlink. 133 fn migrate_virtual_filesystem(new_fs: Arc<dyn FileSystem>) -> Result<(), SystemError> { 134 kinfo!("VFS: Migrating filesystems..."); 135 136 // ==== 在这里获取要被迁移的文件系统的inode === 137 let binding = ROOT_INODE().find("proc").expect("ProcFS not mounted!").fs(); 138 let proc: &MountFS = binding.as_any_ref().downcast_ref::<MountFS>().unwrap(); 139 let binding = ROOT_INODE().find("dev").expect("DevFS not mounted!").fs(); 140 let dev: &MountFS = binding.as_any_ref().downcast_ref::<MountFS>().unwrap(); 141 let binding = ROOT_INODE().find("sys").expect("SysFs not mounted!").fs(); 142 let sys: &MountFS = binding.as_any_ref().downcast_ref::<MountFS>().unwrap(); 143 144 let new_fs = MountFS::new(new_fs, None); 145 // 获取新的根文件系统的根节点的引用 146 let new_root_inode = Box::leak(Box::new(new_fs.root_inode())); 147 148 // 把上述文件系统,迁移到新的文件系统下 149 do_migrate(new_root_inode.clone(), "proc", proc)?; 150 do_migrate(new_root_inode.clone(), "dev", dev)?; 151 do_migrate(new_root_inode.clone(), "sys", sys)?; 152 153 unsafe { 154 // drop旧的Root inode 155 let old_root_inode: Box<Arc<dyn IndexNode>> = Box::from_raw(__ROOT_INODE); 156 __ROOT_INODE = null_mut(); 157 drop(old_root_inode); 158 159 // 设置全局的新的ROOT Inode 160 __ROOT_INODE = new_root_inode; 161 } 162 163 kinfo!("VFS: Migrate filesystems done!"); 164 165 return Ok(()); 166 } 167 168 #[no_mangle] 169 pub extern "C" fn mount_root_fs() -> i32 { 170 kinfo!("Try to mount FAT32 as root fs..."); 171 let partiton: Arc<crate::io::disk_info::Partition> = 172 ahci::get_disks_by_name("ahci_disk_0".to_string()) 173 .unwrap() 174 .0 175 .lock() 176 .partitions[0] 177 .clone(); 178 179 let fatfs: Result<Arc<FATFileSystem>, SystemError> = FATFileSystem::new(partiton); 180 if fatfs.is_err() { 181 kerror!( 182 "Failed to initialize fatfs, code={:?}", 183 fatfs.as_ref().err() 184 ); 185 loop { 186 spin_loop(); 187 } 188 } 189 let fatfs: Arc<FATFileSystem> = fatfs.unwrap(); 190 let r = migrate_virtual_filesystem(fatfs); 191 if r.is_err() { 192 kerror!("Failed to migrate virtual filesystem to FAT32!"); 193 loop { 194 spin_loop(); 195 } 196 } 197 kinfo!("Successfully migrate rootfs to FAT32!"); 198 199 return 0; 200 } 201 202 /// @brief 创建文件/文件夹 203 pub fn do_mkdir(path: &str, _mode: FileMode) -> Result<u64, SystemError> { 204 // 文件名过长 205 if path.len() > PAGE_4K_SIZE as usize { 206 return Err(SystemError::ENAMETOOLONG); 207 } 208 209 let inode: Result<Arc<dyn IndexNode>, SystemError> = ROOT_INODE().lookup(path); 210 211 if inode.is_err() { 212 let errno = inode.unwrap_err(); 213 // 文件不存在,且需要创建 214 if errno == SystemError::ENOENT { 215 let (filename, parent_path) = rsplit_path(path); 216 // 查找父目录 217 let parent_inode: Arc<dyn IndexNode> = 218 ROOT_INODE().lookup(parent_path.unwrap_or("/"))?; 219 // 创建文件夹 220 let _create_inode: Arc<dyn IndexNode> = 221 parent_inode.create(filename, FileType::Dir, 0o777)?; 222 } else { 223 // 不需要创建文件,因此返回错误码 224 return Err(errno); 225 } 226 } 227 228 return Ok(0); 229 } 230 231 /// @breif 删除文件夹 232 pub fn do_remove_dir(path: &str) -> Result<u64, SystemError> { 233 // 文件名过长 234 if path.len() > PAGE_4K_SIZE as usize { 235 return Err(SystemError::ENAMETOOLONG); 236 } 237 238 let inode: Result<Arc<dyn IndexNode>, SystemError> = ROOT_INODE().lookup(path); 239 240 if inode.is_err() { 241 let errno = inode.unwrap_err(); 242 // 文件不存在 243 if errno == SystemError::ENOENT { 244 return Err(SystemError::ENOENT); 245 } 246 } 247 248 let (filename, parent_path) = rsplit_path(path); 249 // 查找父目录 250 let parent_inode: Arc<dyn IndexNode> = ROOT_INODE().lookup(parent_path.unwrap_or("/"))?; 251 252 if parent_inode.metadata()?.file_type != FileType::Dir { 253 return Err(SystemError::ENOTDIR); 254 } 255 256 let target_inode: Arc<dyn IndexNode> = parent_inode.find(filename)?; 257 if target_inode.metadata()?.file_type != FileType::Dir { 258 return Err(SystemError::ENOTDIR); 259 } 260 261 // 删除文件夹 262 parent_inode.rmdir(filename)?; 263 264 return Ok(0); 265 } 266 267 /// @brief 删除文件 268 pub fn do_unlink_at(path: &str, _mode: FileMode) -> Result<u64, SystemError> { 269 // 文件名过长 270 if path.len() > PAGE_4K_SIZE as usize { 271 return Err(SystemError::ENAMETOOLONG); 272 } 273 274 let inode: Result<Arc<dyn IndexNode>, SystemError> = ROOT_INODE().lookup(path); 275 276 if inode.is_err() { 277 let errno = inode.clone().unwrap_err(); 278 // 文件不存在,且需要创建 279 if errno == SystemError::ENOENT { 280 return Err(SystemError::ENOENT); 281 } 282 } 283 // 禁止在目录上unlink 284 if inode.unwrap().metadata()?.file_type == FileType::Dir { 285 return Err(SystemError::EPERM); 286 } 287 288 let (filename, parent_path) = rsplit_path(path); 289 // 查找父目录 290 let parent_inode: Arc<dyn IndexNode> = ROOT_INODE().lookup(parent_path.unwrap_or("/"))?; 291 292 if parent_inode.metadata()?.file_type != FileType::Dir { 293 return Err(SystemError::ENOTDIR); 294 } 295 296 // 删除文件 297 parent_inode.unlink(filename)?; 298 299 return Ok(0); 300 } 301