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