xref: /DragonOS/kernel/src/filesystem/overlayfs/copy_up.rs (revision f5b2038871d3441e1c7f32439ff422957e7ab828)
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 {
copy_up(&self) -> Result<(), SystemError>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 
create_upper_inode(&self, metadata: Metadata) -> Result<Arc<dyn IndexNode>, SystemError>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