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