1 use super::OvlInode; 2 use crate::{ 3 filesystem::vfs::{IndexNode, Metadata}, 4 libs::spinlock::SpinLock, 5 }; 6 use alloc::sync::Arc; 7 use system_error::SystemError; 8 9 impl OvlInode { 10 pub fn copy_up(&self) -> Result<(), SystemError> { 11 let mut upper_inode = self.upper_inode.lock(); 12 if upper_inode.is_some() { 13 return Ok(()); 14 } 15 16 let lower_inode = self.lower_inode.as_ref().ok_or(SystemError::ENOENT)?; 17 18 let metadata = lower_inode.metadata()?; 19 let new_upper_inode = self.create_upper_inode(metadata.clone())?; 20 21 let mut buffer = vec![0u8; metadata.size as usize]; 22 let lock = SpinLock::new(crate::filesystem::vfs::FilePrivateData::Unused); 23 lower_inode.read_at(0, metadata.size as usize, &mut buffer, lock.lock())?; 24 25 new_upper_inode.write_at(0, metadata.size as usize, &buffer, lock.lock())?; 26 27 *upper_inode = Some(new_upper_inode); 28 29 Ok(()) 30 } 31 32 fn create_upper_inode(&self, metadata: Metadata) -> Result<Arc<dyn IndexNode>, SystemError> { 33 let upper_inode = self.upper_inode.lock(); 34 let upper_root_inode = upper_inode 35 .as_ref() 36 .ok_or(SystemError::ENOSYS)? 37 .fs() 38 .root_inode(); 39 upper_root_inode.create_with_data(&self.dname()?.0, metadata.file_type, metadata.mode, 0) 40 } 41 } 42