1 #![allow(dead_code, unused_variables, unused_imports)] 2 pub mod copy_up; 3 pub mod entry; 4 5 use super::ramfs::{LockedRamFSInode, RamFSInode}; 6 use super::vfs::{self, FileSystem, FileType, FsInfo, IndexNode, Metadata, SuperBlock}; 7 use super::vfs::{FSMAKER, ROOT_INODE}; 8 use crate::driver::base::device::device_number::DeviceNumber; 9 use crate::driver::base::device::device_number::Major; 10 use crate::filesystem::vfs::{FileSystemMaker, FileSystemMakerData}; 11 use crate::libs::spinlock::SpinLock; 12 use alloc::string::String; 13 use alloc::sync::Arc; 14 use alloc::sync::Weak; 15 use alloc::vec::Vec; 16 use entry::{OvlEntry, OvlLayer}; 17 use linkme::distributed_slice; 18 use system_error::SystemError; 19 20 const WHITEOUT_MODE: u64 = 0o020000 | 0o600; // whiteout字符设备文件模式与权限 21 const WHITEOUT_DEV: DeviceNumber = DeviceNumber::new(Major::UNNAMED_MAJOR, 0); // Whiteout 文件设备号 22 const WHITEOUT_FLAG: u64 = 0x1; 23 24 #[distributed_slice(FSMAKER)] 25 static OVERLAYFSMAKER: FileSystemMaker = FileSystemMaker::new( 26 "overlay", 27 &(OverlayFS::make_overlayfs 28 as fn( 29 Option<&dyn FileSystemMakerData>, 30 ) -> Result<Arc<dyn FileSystem + 'static>, SystemError>), 31 ); 32 #[derive(Debug)] 33 pub struct OverlayMountData { 34 upper_dir: String, 35 lower_dirs: Vec<String>, 36 work_dir: String, 37 } 38 39 impl OverlayMountData { from_row(raw_data: *const u8) -> Result<Self, SystemError>40 pub fn from_row(raw_data: *const u8) -> Result<Self, SystemError> { 41 if raw_data.is_null() { 42 return Err(SystemError::EINVAL); 43 } 44 let len = (0..) 45 .find(|&i| unsafe { raw_data.add(i).read() } == 0) 46 .ok_or(SystemError::EINVAL)?; 47 let slice = unsafe { core::slice::from_raw_parts(raw_data, len) }; 48 let raw_str = core::str::from_utf8(slice).map_err(|_| SystemError::EINVAL)?; 49 let mut data = OverlayMountData { 50 upper_dir: String::new(), 51 lower_dirs: Vec::new(), 52 work_dir: String::new(), 53 }; 54 55 for pair in raw_str.split(',') { 56 let mut parts = pair.split('='); 57 let key = parts.next().ok_or(SystemError::EINVAL)?; 58 let value = parts.next().ok_or(SystemError::EINVAL)?; 59 60 match key { 61 "upperdir" => data.upper_dir = value.into(), 62 "lowerdir" => data.lower_dirs = value.split(':').map(|s| s.into()).collect(), 63 "workdir" => data.work_dir = value.into(), 64 _ => return Err(SystemError::EINVAL), 65 } 66 } 67 Ok(data) 68 } 69 } 70 impl FileSystemMakerData for OverlayMountData { as_any(&self) -> &dyn core::any::Any71 fn as_any(&self) -> &dyn core::any::Any { 72 self 73 } 74 } 75 #[derive(Debug)] 76 pub struct OvlSuperBlock { 77 super_block: SuperBlock, 78 pseudo_dev: DeviceNumber, // 虚拟设备号 79 is_lower: bool, 80 } 81 82 #[derive(Debug)] 83 struct OverlayFS { 84 numlayer: usize, 85 numfs: u32, 86 numdatalayer: usize, 87 layers: Vec<OvlLayer>, // 第0层为读写层,后面是只读层 88 workdir: Arc<OvlInode>, 89 root_inode: Arc<OvlInode>, 90 } 91 92 #[derive(Debug)] 93 pub struct OvlInode { 94 redirect: String, // 重定向路径 95 file_type: FileType, 96 flags: SpinLock<u64>, 97 upper_inode: SpinLock<Option<Arc<dyn IndexNode>>>, // 读写层 98 lower_inode: Option<Arc<dyn IndexNode>>, // 只读层 99 oe: Arc<OvlEntry>, 100 fs: Weak<OverlayFS>, 101 } 102 impl OvlInode { new( redirect: String, upper: Option<Arc<dyn IndexNode>>, lower_inode: Option<Arc<dyn IndexNode>>, ) -> Self103 pub fn new( 104 redirect: String, 105 upper: Option<Arc<dyn IndexNode>>, 106 lower_inode: Option<Arc<dyn IndexNode>>, 107 ) -> Self { 108 Self { 109 redirect, 110 file_type: FileType::Dir, 111 flags: SpinLock::new(0), 112 upper_inode: SpinLock::new(upper), 113 lower_inode, 114 oe: Arc::new(OvlEntry::new()), 115 fs: Weak::default(), 116 } 117 } 118 } 119 120 impl FileSystem for OverlayFS { root_inode(&self) -> Arc<dyn IndexNode>121 fn root_inode(&self) -> Arc<dyn IndexNode> { 122 self.root_inode.clone() 123 } 124 info(&self) -> vfs::FsInfo125 fn info(&self) -> vfs::FsInfo { 126 FsInfo { 127 blk_dev_id: 0, 128 max_name_len: 255, 129 } 130 } 131 as_any_ref(&self) -> &dyn core::any::Any132 fn as_any_ref(&self) -> &dyn core::any::Any { 133 self 134 } 135 name(&self) -> &str136 fn name(&self) -> &str { 137 "overlayfs" 138 } 139 super_block(&self) -> SuperBlock140 fn super_block(&self) -> SuperBlock { 141 todo!() 142 } 143 } 144 145 impl OverlayFS { ovl_upper_mnt(&self) -> Arc<dyn IndexNode>146 pub fn ovl_upper_mnt(&self) -> Arc<dyn IndexNode> { 147 self.layers[0].mnt.clone() 148 } make_overlayfs( data: Option<&dyn FileSystemMakerData>, ) -> Result<Arc<dyn FileSystem + 'static>, SystemError>149 pub fn make_overlayfs( 150 data: Option<&dyn FileSystemMakerData>, 151 ) -> Result<Arc<dyn FileSystem + 'static>, SystemError> { 152 let mount_data = data 153 .and_then(|d| d.as_any().downcast_ref::<OverlayMountData>()) 154 .ok_or(SystemError::EINVAL)?; 155 156 let upper_inode = ROOT_INODE() 157 .lookup(&mount_data.upper_dir) 158 .map_err(|_| SystemError::EINVAL)?; 159 let upper_layer = OvlLayer { 160 mnt: Arc::new(OvlInode::new( 161 mount_data.upper_dir.clone(), 162 Some(upper_inode), 163 None, 164 )), 165 index: 0, 166 fsid: 0, 167 }; 168 169 let lower_layers: Result<Vec<OvlLayer>, SystemError> = mount_data 170 .lower_dirs 171 .iter() 172 .enumerate() 173 .map(|(i, dir)| { 174 let lower_inode = ROOT_INODE().lookup(dir).map_err(|_| SystemError::EINVAL)?; // 处理错误 175 Ok(OvlLayer { 176 mnt: Arc::new(OvlInode::new(dir.clone(), None, Some(lower_inode))), 177 index: (i + 1) as u32, 178 fsid: (i + 1) as u32, 179 }) 180 }) 181 .collect(); 182 183 let lower_layers = lower_layers?; 184 185 let workdir = Arc::new(OvlInode::new(mount_data.work_dir.clone(), None, None)); 186 187 if lower_layers.is_empty() { 188 return Err(SystemError::EINVAL); 189 } 190 191 let mut layers = Vec::new(); 192 layers.push(upper_layer); 193 layers.extend(lower_layers); 194 195 let root_inode = layers[0].mnt.clone(); 196 197 let fs = OverlayFS { 198 numlayer: layers.len(), 199 numfs: 1, 200 numdatalayer: layers.len() - 1, 201 layers, 202 workdir, 203 root_inode, 204 }; 205 Ok(Arc::new(fs)) 206 } 207 } 208 209 impl OvlInode { ovl_lower_redirect(&self) -> Option<&str>210 pub fn ovl_lower_redirect(&self) -> Option<&str> { 211 if self.file_type == FileType::File || self.file_type == FileType::Dir { 212 Some(&self.redirect) 213 } else { 214 None 215 } 216 } 217 create_whiteout(&self, name: &str) -> Result<(), SystemError>218 pub fn create_whiteout(&self, name: &str) -> Result<(), SystemError> { 219 let whiteout_mode = vfs::syscall::ModeType::S_IFCHR; 220 let mut upper_inode = self.upper_inode.lock(); 221 if let Some(ref upper_inode) = *upper_inode { 222 upper_inode.mknod(name, whiteout_mode, WHITEOUT_DEV)?; 223 } else { 224 let new_inode = self 225 .fs 226 .upgrade() 227 .ok_or(SystemError::EROFS)? 228 .root_inode() 229 .create(name, FileType::CharDevice, whiteout_mode)?; 230 *upper_inode = Some(new_inode); 231 } 232 let mut flags = self.flags.lock(); 233 *flags |= WHITEOUT_FLAG; // 标记为 whiteout 234 Ok(()) 235 } 236 is_whiteout(&self) -> bool237 fn is_whiteout(&self) -> bool { 238 let flags = self.flags.lock(); 239 self.file_type == FileType::CharDevice && (*flags & WHITEOUT_FLAG) != 0 240 } 241 has_whiteout(&self, name: &str) -> bool242 fn has_whiteout(&self, name: &str) -> bool { 243 let upper_inode = self.upper_inode.lock(); 244 if let Some(ref upper_inode) = *upper_inode { 245 if let Ok(inode) = upper_inode.find(name) { 246 if let Some(ovl_inode) = inode.as_any_ref().downcast_ref::<OvlInode>() { 247 return ovl_inode.is_whiteout(); 248 } 249 } 250 } 251 false 252 } 253 } 254 255 impl IndexNode for OvlInode { read_at( &self, offset: usize, len: usize, buf: &mut [u8], data: crate::libs::spinlock::SpinLockGuard<vfs::FilePrivateData>, ) -> Result<usize, system_error::SystemError>256 fn read_at( 257 &self, 258 offset: usize, 259 len: usize, 260 buf: &mut [u8], 261 data: crate::libs::spinlock::SpinLockGuard<vfs::FilePrivateData>, 262 ) -> Result<usize, system_error::SystemError> { 263 if let Some(ref upper_inode) = *self.upper_inode.lock() { 264 return upper_inode.read_at(offset, len, buf, data); 265 } 266 267 if let Some(lower_inode) = &self.lower_inode { 268 return lower_inode.read_at(offset, len, buf, data); 269 } 270 271 Err(SystemError::ENOENT) 272 } 273 write_at( &self, offset: usize, len: usize, buf: &[u8], data: crate::libs::spinlock::SpinLockGuard<vfs::FilePrivateData>, ) -> Result<usize, SystemError>274 fn write_at( 275 &self, 276 offset: usize, 277 len: usize, 278 buf: &[u8], 279 data: crate::libs::spinlock::SpinLockGuard<vfs::FilePrivateData>, 280 ) -> Result<usize, SystemError> { 281 if (*self.upper_inode.lock()).is_none() { 282 self.copy_up()?; 283 } 284 if let Some(ref upper_inode) = *self.upper_inode.lock() { 285 return upper_inode.write_at(offset, len, buf, data); 286 } 287 288 Err(SystemError::EROFS) 289 } 290 fs(&self) -> Arc<dyn FileSystem>291 fn fs(&self) -> Arc<dyn FileSystem> { 292 self.fs.upgrade().unwrap() 293 } 294 metadata(&self) -> Result<Metadata, SystemError>295 fn metadata(&self) -> Result<Metadata, SystemError> { 296 if let Some(ref upper_inode) = *self.upper_inode.lock() { 297 return upper_inode.metadata(); 298 } 299 300 if let Some(ref lower_inode) = self.lower_inode { 301 return lower_inode.metadata(); 302 } 303 Ok(Metadata::default()) 304 } 305 as_any_ref(&self) -> &dyn core::any::Any306 fn as_any_ref(&self) -> &dyn core::any::Any { 307 self 308 } 309 list(&self) -> Result<Vec<String>, system_error::SystemError>310 fn list(&self) -> Result<Vec<String>, system_error::SystemError> { 311 let mut entries: Vec<String> = Vec::new(); 312 let upper_inode = self.upper_inode.lock(); 313 if let Some(ref upper_inode) = *upper_inode { 314 let upper_entries = upper_inode.list()?; 315 entries.extend(upper_entries); 316 } 317 if let Some(lower_inode) = &self.lower_inode { 318 let lower_entries = lower_inode.list()?; 319 for entry in lower_entries { 320 if !entries.contains(&entry) && !self.has_whiteout(&entry) { 321 entries.push(entry); 322 } 323 } 324 } 325 326 Ok(entries) 327 } 328 mkdir( &self, name: &str, mode: vfs::syscall::ModeType, ) -> Result<Arc<dyn IndexNode>, system_error::SystemError>329 fn mkdir( 330 &self, 331 name: &str, 332 mode: vfs::syscall::ModeType, 333 ) -> Result<Arc<dyn IndexNode>, system_error::SystemError> { 334 if let Some(ref upper_inode) = *self.upper_inode.lock() { 335 upper_inode.mkdir(name, mode) 336 } else { 337 Err(SystemError::EROFS) 338 } 339 } 340 rmdir(&self, name: &str) -> Result<(), SystemError>341 fn rmdir(&self, name: &str) -> Result<(), SystemError> { 342 let upper_inode = self.upper_inode.lock(); 343 if let Some(ref upper_inode) = *upper_inode { 344 upper_inode.rmdir(name)?; 345 } else if let Some(lower_inode) = &self.lower_inode { 346 if lower_inode.find(name).is_ok() { 347 self.create_whiteout(name)?; 348 } else { 349 return Err(SystemError::ENOENT); 350 } 351 } else { 352 return Err(SystemError::ENOENT); 353 } 354 355 Ok(()) 356 } 357 unlink(&self, name: &str) -> Result<(), SystemError>358 fn unlink(&self, name: &str) -> Result<(), SystemError> { 359 let upper_inode = self.upper_inode.lock(); 360 if let Some(ref upper_inode) = *upper_inode { 361 upper_inode.unlink(name)?; 362 } else if let Some(lower_inode) = &self.lower_inode { 363 if lower_inode.find(name).is_ok() { 364 self.create_whiteout(name)?; 365 } else { 366 return Err(SystemError::ENOENT); 367 } 368 } else { 369 return Err(SystemError::ENOENT); 370 } 371 372 Ok(()) 373 } 374 link( &self, name: &str, other: &Arc<dyn IndexNode>, ) -> Result<(), system_error::SystemError>375 fn link( 376 &self, 377 name: &str, 378 other: &Arc<dyn IndexNode>, 379 ) -> Result<(), system_error::SystemError> { 380 if let Some(ref upper_inode) = *self.upper_inode.lock() { 381 upper_inode.link(name, other) 382 } else { 383 Err(SystemError::EROFS) 384 } 385 } 386 create( &self, name: &str, file_type: vfs::FileType, mode: vfs::syscall::ModeType, ) -> Result<Arc<dyn IndexNode>, system_error::SystemError>387 fn create( 388 &self, 389 name: &str, 390 file_type: vfs::FileType, 391 mode: vfs::syscall::ModeType, 392 ) -> Result<Arc<dyn IndexNode>, system_error::SystemError> { 393 if let Some(ref upper_inode) = *self.upper_inode.lock() { 394 upper_inode.create(name, file_type, mode) 395 } else { 396 Err(SystemError::EROFS) 397 } 398 } 399 find(&self, name: &str) -> Result<Arc<dyn IndexNode>, system_error::SystemError>400 fn find(&self, name: &str) -> Result<Arc<dyn IndexNode>, system_error::SystemError> { 401 let upper_inode = self.upper_inode.lock(); 402 if let Some(ref upper) = *upper_inode { 403 if let Ok(inode) = upper.find(name) { 404 return Ok(inode); 405 } 406 } 407 if self.has_whiteout(name) { 408 return Err(SystemError::ENOENT); 409 } 410 411 if let Some(lower) = &self.lower_inode { 412 if let Ok(inode) = lower.find(name) { 413 return Ok(inode); 414 } 415 } 416 417 Err(SystemError::ENOENT) 418 } 419 mknod( &self, filename: &str, mode: vfs::syscall::ModeType, dev_t: crate::driver::base::device::device_number::DeviceNumber, ) -> Result<Arc<dyn IndexNode>, system_error::SystemError>420 fn mknod( 421 &self, 422 filename: &str, 423 mode: vfs::syscall::ModeType, 424 dev_t: crate::driver::base::device::device_number::DeviceNumber, 425 ) -> Result<Arc<dyn IndexNode>, system_error::SystemError> { 426 let upper_inode = self.upper_inode.lock(); 427 if let Some(ref inode) = *upper_inode { 428 inode.mknod(filename, mode, dev_t) 429 } else { 430 Err(SystemError::EROFS) 431 } 432 } 433 } 434