xref: /DragonOS/kernel/src/filesystem/overlayfs/mod.rs (revision 7c28051e8c601312d3d0fd7bcb71bc71450d10c0)
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