1#![allow(missing_docs)]
5pub mod config;
6mod inode_store;
7pub mod sync_io;
8mod utils;
9
10use core::panic;
11use std::collections::HashMap;
12use std::ffi::{CStr, CString};
13use std::fs::File;
14use std::io::{Error, ErrorKind, Result, Seek, SeekFrom};
15use std::sync::atomic::{AtomicBool, AtomicU64, Ordering};
16use std::sync::{Arc, Mutex, RwLock, Weak};
17
18use crate::abi::fuse_abi::{stat64, statvfs64, CreateIn, ROOT_ID as FUSE_ROOT_ID};
19use crate::api::filesystem::{
20 Context, DirEntry, Entry, Layer, OpenOptions, ZeroCopyReader, ZeroCopyWriter,
21};
22#[cfg(not(feature = "async-io"))]
23use crate::api::BackendFileSystem;
24use crate::api::{SLASH_ASCII, VFS_MAX_INO};
25
26use crate::common::file_buf::FileVolatileSlice;
27use crate::common::file_traits::FileReadWriteVolatile;
28use vmm_sys_util::tempfile::TempFile;
29
30use self::config::Config;
31use self::inode_store::InodeStore;
32
33pub type Inode = u64;
34pub type Handle = u64;
35pub const MAXNAMELEN: usize = 256;
36pub const CURRENT_DIR: &str = ".";
37pub const PARENT_DIR: &str = "..";
38pub const MAXBUFSIZE: usize = 1 << 20;
39
40pub type BoxedLayer = Box<dyn Layer<Inode = Inode, Handle = Handle> + Send + Sync>;
42
43pub(crate) struct RealInode {
47 pub layer: Arc<BoxedLayer>,
48 pub in_upper_layer: bool,
49 pub inode: u64,
50 pub whiteout: bool,
52 pub opaque: bool,
54 pub stat: Option<stat64>,
55}
56
57#[derive(Default)]
59pub(crate) struct OverlayInode {
60 pub childrens: Mutex<HashMap<String, Arc<OverlayInode>>>,
62 pub parent: Mutex<Weak<OverlayInode>>,
63 pub real_inodes: Mutex<Vec<RealInode>>,
65 pub inode: u64,
67 pub path: String,
68 pub name: String,
69 pub lookups: AtomicU64,
70 pub whiteout: AtomicBool,
72 pub loaded: AtomicBool,
74}
75
76#[derive(Default)]
77pub enum CachePolicy {
78 Never,
79 #[default]
80 Auto,
81 Always,
82}
83pub struct OverlayFs {
84 config: Config,
85 lower_layers: Vec<Arc<BoxedLayer>>,
86 upper_layer: Option<Arc<BoxedLayer>>,
87 inodes: RwLock<InodeStore>,
89 handles: Mutex<HashMap<u64, Arc<HandleData>>>,
91 next_handle: AtomicU64,
92 writeback: AtomicBool,
93 no_open: AtomicBool,
94 no_opendir: AtomicBool,
95 killpriv_v2: AtomicBool,
96 perfile_dax: AtomicBool,
97}
98
99struct RealHandle {
100 layer: Arc<BoxedLayer>,
101 in_upper_layer: bool,
102 inode: u64,
103 handle: AtomicU64,
104}
105
106struct HandleData {
107 node: Arc<OverlayInode>,
108 real_handle: Option<RealHandle>,
110}
111
112impl RealInode {
117 fn new(
118 layer: Arc<BoxedLayer>,
119 in_upper_layer: bool,
120 inode: u64,
121 whiteout: bool,
122 opaque: bool,
123 ) -> Self {
124 let mut ri = RealInode {
125 layer,
126 in_upper_layer,
127 inode,
128 whiteout,
129 opaque,
130 stat: None,
131 };
132 match ri.stat64_ignore_enoent(&Context::default()) {
133 Ok(v) => {
134 ri.stat = v;
135 }
136 Err(e) => {
137 error!("stat64 failed during RealInode creation: {}", e);
138 }
139 }
140 ri
141 }
142
143 fn stat64(&self, ctx: &Context) -> Result<stat64> {
144 let layer = self.layer.as_ref();
145 if self.inode == 0 {
146 return Err(Error::from_raw_os_error(libc::ENOENT));
147 }
148
149 match layer.getattr(ctx, self.inode, None) {
150 Ok((v1, _v2)) => Ok(v1),
151 Err(e) => Err(e),
152 }
153 }
154
155 fn stat64_ignore_enoent(&self, ctx: &Context) -> Result<Option<stat64>> {
156 match self.stat64(ctx) {
157 Ok(v1) => Ok(Some(v1)),
158 Err(e) => match e.raw_os_error() {
159 Some(raw_error) => {
160 if raw_error != libc::ENOENT || raw_error != libc::ENAMETOOLONG {
161 return Ok(None);
162 }
163 Err(e)
164 }
165 None => Err(e),
166 },
167 }
168 }
169
170 fn lookup_child_ignore_enoent(&self, ctx: &Context, name: &str) -> Result<Option<Entry>> {
172 let cname = CString::new(name).map_err(|e| Error::new(ErrorKind::InvalidData, e))?;
173 let layer = self.layer.as_ref();
175 match layer.lookup(ctx, self.inode, cname.as_c_str()) {
176 Ok(v) => {
177 if v.inode == 0 {
179 return Ok(None);
180 }
181 Ok(Some(v))
182 }
183 Err(e) => {
184 if let Some(raw_error) = e.raw_os_error() {
185 if raw_error == libc::ENOENT || raw_error == libc::ENAMETOOLONG {
186 return Ok(None);
187 }
188 }
189
190 Err(e)
191 }
192 }
193 }
194
195 fn lookup_child(&self, ctx: &Context, name: &str) -> Result<Option<RealInode>> {
198 if self.whiteout {
199 return Ok(None);
200 }
201
202 let layer = self.layer.as_ref();
203
204 match self.lookup_child_ignore_enoent(ctx, name)? {
206 Some(v) => {
207 let (whiteout, opaque) = if utils::is_dir(v.attr) {
209 (false, layer.is_opaque(ctx, v.inode)?)
210 } else {
211 (layer.is_whiteout(ctx, v.inode)?, false)
212 };
213
214 Ok(Some(RealInode {
215 layer: self.layer.clone(),
216 in_upper_layer: self.in_upper_layer,
217 inode: v.inode,
218 whiteout,
219 opaque,
220 stat: Some(v.attr),
221 }))
222 }
223 None => Ok(None),
224 }
225 }
226
227 fn readdir(&self, ctx: &Context) -> Result<HashMap<String, RealInode>> {
229 if self.whiteout {
231 return Err(Error::from_raw_os_error(libc::ENOENT));
232 }
233
234 let stat = match self.stat {
235 Some(v) => v,
236 None => self.stat64(ctx)?,
237 };
238
239 if !utils::is_dir(stat) {
241 return Err(Error::from_raw_os_error(libc::ENOTDIR));
242 }
243
244 let opendir_res = self.layer.opendir(ctx, self.inode, libc::O_RDONLY as u32);
246 let handle = match opendir_res {
247 Ok((handle, _)) => handle.unwrap_or_default(),
248 Err(e) => {
250 match e.raw_os_error() {
251 Some(raw_error) => {
252 if raw_error == libc::ENOSYS {
253 0
255 } else {
256 return Err(e);
257 }
258 }
259 None => {
260 return Err(e);
261 }
262 }
263 }
264 };
265
266 let mut child_names = vec![];
267 let mut more = true;
268 let mut offset = 0;
269 let bufsize = 1024;
270 while more {
271 more = false;
272 self.layer.readdir(
273 ctx,
274 self.inode,
275 handle,
276 bufsize,
277 offset,
278 &mut |d| -> Result<usize> {
279 more = true;
280 offset = d.offset;
281 let child_name = String::from_utf8_lossy(d.name).into_owned();
282
283 trace!("entry: {}", child_name.as_str());
284
285 if child_name.eq(CURRENT_DIR) || child_name.eq(PARENT_DIR) {
286 return Ok(1);
287 }
288
289 child_names.push(child_name);
290
291 Ok(1)
292 },
293 )?;
294 }
295
296 if handle > 0 {
298 if let Err(e) = self
299 .layer
300 .releasedir(ctx, self.inode, libc::O_RDONLY as u32, handle)
301 {
302 match e.raw_os_error() {
304 Some(raw_error) => {
305 if raw_error != libc::ENOSYS {
306 return Err(e);
307 }
308 }
309 None => {
310 return Err(e);
311 }
312 }
313 }
314 }
315
316 let mut child_real_inodes = HashMap::new();
318 for name in child_names {
319 if let Some(child) = self.lookup_child(ctx, name.as_str())? {
320 child_real_inodes.insert(name, child);
321 }
322 }
323
324 Ok(child_real_inodes)
325 }
326
327 fn create_whiteout(&self, ctx: &Context, name: &str) -> Result<RealInode> {
328 if !self.in_upper_layer {
329 return Err(Error::from_raw_os_error(libc::EROFS));
330 }
331
332 let cname = utils::to_cstring(name)?;
333 let entry = self
334 .layer
335 .create_whiteout(ctx, self.inode, cname.as_c_str())?;
336
337 Ok(RealInode {
339 layer: self.layer.clone(),
340 in_upper_layer: true,
341 inode: entry.inode,
342 whiteout: true,
343 opaque: false,
344 stat: Some(entry.attr),
345 })
346 }
347
348 fn mkdir(&self, ctx: &Context, name: &str, mode: u32, umask: u32) -> Result<RealInode> {
349 if !self.in_upper_layer {
350 return Err(Error::from_raw_os_error(libc::EROFS));
351 }
352
353 let cname = utils::to_cstring(name)?;
354 let entry = self
355 .layer
356 .mkdir(ctx, self.inode, cname.as_c_str(), mode, umask)?;
357
358 Ok(RealInode {
360 layer: self.layer.clone(),
361 in_upper_layer: true,
362 inode: entry.inode,
363 whiteout: false,
364 opaque: false,
365 stat: Some(entry.attr),
366 })
367 }
368
369 fn create(
370 &self,
371 ctx: &Context,
372 name: &str,
373 args: CreateIn,
374 ) -> Result<(RealInode, Option<u64>)> {
375 if !self.in_upper_layer {
376 return Err(Error::from_raw_os_error(libc::EROFS));
377 }
378
379 let (entry, h, _, _) =
380 self.layer
381 .create(ctx, self.inode, utils::to_cstring(name)?.as_c_str(), args)?;
382
383 Ok((
384 RealInode {
385 layer: self.layer.clone(),
386 in_upper_layer: true,
387 inode: entry.inode,
388 whiteout: false,
389 opaque: false,
390 stat: Some(entry.attr),
391 },
392 h,
393 ))
394 }
395
396 fn mknod(
397 &self,
398 ctx: &Context,
399 name: &str,
400 mode: u32,
401 rdev: u32,
402 umask: u32,
403 ) -> Result<RealInode> {
404 if !self.in_upper_layer {
405 return Err(Error::from_raw_os_error(libc::EROFS));
406 }
407
408 let entry = self.layer.mknod(
409 ctx,
410 self.inode,
411 utils::to_cstring(name)?.as_c_str(),
412 mode,
413 rdev,
414 umask,
415 )?;
416 Ok(RealInode {
417 layer: self.layer.clone(),
418 in_upper_layer: true,
419 inode: entry.inode,
420 whiteout: false,
421 opaque: false,
422 stat: Some(entry.attr),
423 })
424 }
425
426 fn link(&self, ctx: &Context, ino: u64, name: &str) -> Result<RealInode> {
427 if !self.in_upper_layer {
428 return Err(Error::from_raw_os_error(libc::EROFS));
429 }
430
431 let entry = self
432 .layer
433 .link(ctx, ino, self.inode, utils::to_cstring(name)?.as_c_str())?;
434
435 let opaque = if utils::is_dir(entry.attr) {
436 self.layer.is_opaque(ctx, entry.inode)?
437 } else {
438 false
439 };
440 Ok(RealInode {
441 layer: self.layer.clone(),
442 in_upper_layer: true,
443 inode: entry.inode,
444 whiteout: false,
445 opaque,
446 stat: Some(entry.attr),
447 })
448 }
449
450 fn symlink(&self, ctx: &Context, link_name: &str, filename: &str) -> Result<RealInode> {
452 if !self.in_upper_layer {
453 return Err(Error::from_raw_os_error(libc::EROFS));
454 }
455
456 let entry = self.layer.symlink(
457 ctx,
458 utils::to_cstring(link_name)?.as_c_str(),
459 self.inode,
460 utils::to_cstring(filename)?.as_c_str(),
461 )?;
462
463 Ok(RealInode {
464 layer: self.layer.clone(),
465 in_upper_layer: self.in_upper_layer,
466 inode: entry.inode,
467 whiteout: false,
468 opaque: false,
469 stat: Some(entry.attr),
470 })
471 }
472}
473
474impl Drop for RealInode {
475 fn drop(&mut self) {
476 let ctx = Context::default();
478 let layer = self.layer.as_ref();
479 let inode = self.inode;
480 debug!("forget inode {} by 1 for backend inode in layer ", inode);
481 layer.forget(&ctx, inode, 1);
482 }
483}
484
485impl OverlayInode {
486 pub fn new() -> Self {
487 OverlayInode::default()
488 }
489
490 pub fn new_from_real_inode(name: &str, ino: u64, path: String, real_inode: RealInode) -> Self {
493 let mut new = OverlayInode::new();
494 new.inode = ino;
495 new.path = path.clone();
496 new.name = name.to_string();
497 new.whiteout.store(real_inode.whiteout, Ordering::Relaxed);
498 new.lookups = AtomicU64::new(1);
499 new.real_inodes = Mutex::new(vec![real_inode]);
500 new
501 }
502
503 pub fn new_from_real_inodes(
504 name: &str,
505 ino: u64,
506 path: String,
507 real_inodes: Vec<RealInode>,
508 ) -> Result<Self> {
509 if real_inodes.is_empty() {
510 error!("BUG: new_from_real_inodes() called with empty real_inodes");
511 return Err(Error::from_raw_os_error(libc::EINVAL));
512 }
513
514 let mut first = true;
515 let mut new = Self::new();
516 for ri in real_inodes {
517 let whiteout = ri.whiteout;
518 let opaque = ri.opaque;
519 let stat = match ri.stat {
520 Some(v) => v,
521 None => ri.stat64(&Context::default())?,
522 };
523
524 if first {
525 first = false;
526 new = Self::new_from_real_inode(name, ino, path.clone(), ri);
527
528 if whiteout {
530 break;
531 }
532
533 if !utils::is_dir(stat) {
535 break;
536 }
537
538 if opaque {
540 break;
541 }
542 } else {
543 if ri.whiteout {
545 break;
546 }
547
548 if !utils::is_dir(stat) {
551 error!("invalid layout: non-directory has multiple real inodes");
552 break;
553 }
554
555 new.real_inodes.lock().unwrap().push(ri);
557 if opaque {
559 break;
560 }
561 }
562 }
563 Ok(new)
564 }
565
566 pub fn stat64(&self, ctx: &Context) -> Result<stat64> {
567 for l in self.real_inodes.lock().unwrap().iter() {
569 if let Some(v) = l.stat64_ignore_enoent(ctx)? {
570 return Ok(v);
571 }
572 }
573
574 Err(Error::from_raw_os_error(libc::ENOENT))
576 }
577
578 pub fn count_entries_and_whiteout(&self, ctx: &Context) -> Result<(u64, u64)> {
579 let mut count = 0;
580 let mut whiteouts = 0;
581
582 let st = self.stat64(ctx)?;
583
584 if !utils::is_dir(st) {
586 return Err(Error::from_raw_os_error(libc::ENOTDIR));
587 }
588
589 for (_, child) in self.childrens.lock().unwrap().iter() {
590 if child.whiteout.load(Ordering::Relaxed) {
591 whiteouts += 1;
592 } else {
593 count += 1;
594 }
595 }
596
597 Ok((count, whiteouts))
598 }
599
600 pub fn open(
601 &self,
602 ctx: &Context,
603 flags: u32,
604 fuse_flags: u32,
605 ) -> Result<(Arc<BoxedLayer>, Option<Handle>, OpenOptions)> {
606 let (layer, _, inode) = self.first_layer_inode();
607 let (h, o, _) = layer.as_ref().open(ctx, inode, flags, fuse_flags)?;
608 Ok((layer, h, o))
609 }
610
611 pub fn scan_childrens(self: &Arc<Self>, ctx: &Context) -> Result<Vec<OverlayInode>> {
613 let st = self.stat64(ctx)?;
614 if !utils::is_dir(st) {
615 return Err(Error::from_raw_os_error(libc::ENOTDIR));
616 }
617
618 let mut all_layer_inodes: HashMap<String, Vec<RealInode>> = HashMap::new();
619 let mut counter = 1;
621 let layers_count = self.real_inodes.lock().unwrap().len();
622 for ri in self.real_inodes.lock().unwrap().iter() {
624 debug!(
625 "loading Layer {}/{} for dir '{}', is_upper_layer: {}",
626 counter,
627 layers_count,
628 self.path.as_str(),
629 ri.in_upper_layer
630 );
631 counter += 1;
632 if ri.whiteout {
633 debug!("directory is whiteout");
635 break;
636 }
637
638 let stat = match ri.stat {
639 Some(v) => v,
640 None => ri.stat64(ctx)?,
641 };
642
643 if !utils::is_dir(stat) {
644 debug!("{} is not a directory", self.path.as_str());
645 break;
647 }
648
649 let entries = ri.readdir(ctx)?;
651
652 for (name, inode) in entries {
654 match all_layer_inodes.get_mut(&name) {
655 Some(v) => {
656 v.push(inode)
658 }
659 None => {
660 all_layer_inodes.insert(name, vec![inode]);
661 }
662 };
663 }
664
665 if ri.opaque {
667 debug!("directory {} is opaque", self.path.as_str());
668 break;
669 }
670 }
671
672 let mut childrens = vec![];
674 for (name, real_inodes) in all_layer_inodes {
675 let path = format!("{}/{}", self.path, name);
677 let new = Self::new_from_real_inodes(name.as_str(), 0, path, real_inodes)?;
678 childrens.push(new);
679 }
680
681 Ok(childrens)
682 }
683
684 pub fn create_upper_dir(
686 self: &Arc<Self>,
687 ctx: &Context,
688 mode_umask: Option<(u32, u32)>,
689 ) -> Result<()> {
690 let st = self.stat64(ctx)?;
691 if !utils::is_dir(st) {
692 return Err(Error::from_raw_os_error(libc::ENOTDIR));
693 }
694
695 if self.in_upper_layer() {
697 return Ok(());
698 }
699
700 let pnode = if let Some(n) = self.parent.lock().unwrap().upgrade() {
702 Arc::clone(&n)
703 } else {
704 return Err(Error::other("no parent?"));
705 };
706
707 if !pnode.in_upper_layer() {
708 pnode.create_upper_dir(ctx, None)?; }
710 let mut child = None;
711 pnode.handle_upper_inode_locked(&mut |parent_upper_inode| -> Result<bool> {
712 match parent_upper_inode {
713 Some(parent_ri) => {
714 let ri = match mode_umask {
715 Some((mode, umask)) => {
716 parent_ri.mkdir(ctx, self.name.as_str(), mode, umask)?
717 }
718 None => parent_ri.mkdir(ctx, self.name.as_str(), st.st_mode, 0)?,
719 };
720 child.replace(ri);
722 }
723 None => {
724 error!(
725 "BUG: parent {} has no upper inode after create_upper_dir",
726 pnode.inode
727 );
728 return Err(Error::from_raw_os_error(libc::EINVAL));
729 }
730 }
731 Ok(false)
732 })?;
733
734 if let Some(ri) = child {
735 self.add_upper_inode(ri, false);
737 }
738
739 Ok(())
740 }
741
742 fn add_upper_inode(self: &Arc<Self>, ri: RealInode, clear_lowers: bool) {
744 let mut inodes = self.real_inodes.lock().unwrap();
745 self.whiteout.store(ri.whiteout, Ordering::Relaxed);
747
748 let mut new = vec![ri];
750 let lowers = inodes.drain(..).collect::<Vec<RealInode>>();
752 if !clear_lowers {
753 new.extend(lowers);
755 }
756 inodes.extend(new);
757 }
758
759 pub fn in_upper_layer(&self) -> bool {
760 let all_inodes = self.real_inodes.lock().unwrap();
761 let first = all_inodes.first();
762 match first {
763 Some(v) => v.in_upper_layer,
764 None => false,
765 }
766 }
767
768 pub fn upper_layer_only(&self) -> bool {
769 let real_inodes = self.real_inodes.lock().unwrap();
770 let first = real_inodes.first();
771 match first {
772 Some(v) => {
773 if !v.in_upper_layer {
774 false
775 } else {
776 real_inodes.len() == 1
777 }
778 }
779 None => false,
780 }
781 }
782
783 pub fn first_layer_inode(&self) -> (Arc<BoxedLayer>, bool, u64) {
784 let all_inodes = self.real_inodes.lock().unwrap();
785 let first = all_inodes.first();
786 match first {
787 Some(v) => (v.layer.clone(), v.in_upper_layer, v.inode),
788 None => panic!("BUG: dangling OverlayInode"),
789 }
790 }
791
792 pub fn child(&self, name: &str) -> Option<Arc<OverlayInode>> {
793 self.childrens.lock().unwrap().get(name).cloned()
794 }
795
796 pub fn remove_child(&self, name: &str) {
797 self.childrens.lock().unwrap().remove(name);
798 }
799
800 pub fn insert_child(&self, name: &str, node: Arc<OverlayInode>) {
801 self.childrens
802 .lock()
803 .unwrap()
804 .insert(name.to_string(), node);
805 }
806
807 pub fn handle_upper_inode_locked(
808 &self,
809 f: &mut dyn FnMut(Option<&RealInode>) -> Result<bool>,
810 ) -> Result<bool> {
811 let all_inodes = self.real_inodes.lock().unwrap();
812 let first = all_inodes.first();
813 match first {
814 Some(v) => {
815 if v.in_upper_layer {
816 f(Some(v))
817 } else {
818 f(None)
819 }
820 }
821 None => Err(Error::other(format!(
822 "BUG: dangling OverlayInode {} without any backend inode",
823 self.inode
824 ))),
825 }
826 }
827}
828
829fn entry_type_from_mode(mode: libc::mode_t) -> u8 {
830 match mode & libc::S_IFMT {
831 libc::S_IFBLK => libc::DT_BLK,
832 libc::S_IFCHR => libc::DT_CHR,
833 libc::S_IFDIR => libc::DT_DIR,
834 libc::S_IFIFO => libc::DT_FIFO,
835 libc::S_IFLNK => libc::DT_LNK,
836 libc::S_IFREG => libc::DT_REG,
837 libc::S_IFSOCK => libc::DT_SOCK,
838 _ => libc::DT_UNKNOWN,
839 }
840}
841
842impl OverlayFs {
843 pub fn new(
844 upper: Option<Arc<BoxedLayer>>,
845 lowers: Vec<Arc<BoxedLayer>>,
846 params: Config,
847 ) -> Result<Self> {
848 Ok(OverlayFs {
850 config: params,
851 lower_layers: lowers,
852 upper_layer: upper,
853 inodes: RwLock::new(InodeStore::new()),
854 handles: Mutex::new(HashMap::new()),
855 next_handle: AtomicU64::new(1),
856 writeback: AtomicBool::new(false),
857 no_open: AtomicBool::new(false),
858 no_opendir: AtomicBool::new(false),
859 killpriv_v2: AtomicBool::new(false),
860 perfile_dax: AtomicBool::new(false),
861 })
862 }
863
864 pub fn root_inode(&self) -> Inode {
865 FUSE_ROOT_ID
866 }
867
868 fn alloc_inode(&self, path: &String) -> Result<u64> {
869 self.inodes.write().unwrap().alloc_inode(path)
870 }
871
872 pub fn import(&self) -> Result<()> {
873 let mut root = OverlayInode::new();
874 root.inode = FUSE_ROOT_ID;
875 root.path = String::from("");
876 root.name = String::from("");
877 root.lookups = AtomicU64::new(2);
878 root.real_inodes = Mutex::new(vec![]);
879 let ctx = Context::default();
880
881 if let Some(layer) = self.upper_layer.as_ref() {
883 let ino = layer.root_inode();
884 let real = RealInode::new(layer.clone(), true, ino, false, layer.is_opaque(&ctx, ino)?);
885 root.real_inodes.lock().unwrap().push(real);
886 }
887
888 for layer in self.lower_layers.iter() {
890 let ino = layer.root_inode();
891 let real = RealInode::new(
892 layer.clone(),
893 false,
894 ino,
895 false,
896 layer.is_opaque(&ctx, ino)?,
897 );
898 root.real_inodes.lock().unwrap().push(real);
899 }
900 let root_node = Arc::new(root);
901
902 self.insert_inode(FUSE_ROOT_ID, Arc::clone(&root_node));
904
905 info!("loading root directory\n");
906 self.load_directory(&ctx, &root_node)?;
907
908 Ok(())
909 }
910
911 fn root_node(&self) -> Arc<OverlayInode> {
912 self.get_active_inode(FUSE_ROOT_ID).unwrap()
914 }
915
916 fn insert_inode(&self, inode: u64, node: Arc<OverlayInode>) {
917 self.inodes.write().unwrap().insert_inode(inode, node);
918 }
919
920 fn get_active_inode(&self, inode: u64) -> Option<Arc<OverlayInode>> {
921 self.inodes.read().unwrap().get_inode(inode)
922 }
923
924 fn get_all_inode(&self, inode: u64) -> Option<Arc<OverlayInode>> {
926 let inode_store = self.inodes.read().unwrap();
927 match inode_store.get_inode(inode) {
928 Some(n) => Some(n),
929 None => inode_store.get_deleted_inode(inode),
930 }
931 }
932
933 fn remove_inode(&self, inode: u64, path_removed: Option<String>) -> Option<Arc<OverlayInode>> {
935 self.inodes
936 .write()
937 .unwrap()
938 .remove_inode(inode, path_removed)
939 }
940
941 fn lookup_node(&self, ctx: &Context, parent: Inode, name: &str) -> Result<Arc<OverlayInode>> {
945 if name.contains([SLASH_ASCII as char]) {
946 return Err(Error::from_raw_os_error(libc::EINVAL));
947 }
948
949 let pnode = match self.get_active_inode(parent) {
951 Some(v) => v,
952 None => return Err(Error::from_raw_os_error(libc::ENOENT)),
953 };
954
955 if pnode.whiteout.load(Ordering::Relaxed) {
957 return Err(Error::from_raw_os_error(libc::ENOENT));
958 }
959
960 let st = pnode.stat64(ctx)?;
961 if utils::is_dir(st) && !pnode.loaded.load(Ordering::Relaxed) {
962 self.load_directory(ctx, &pnode)?;
964 }
965
966 if name.eq(".")
968 || (parent == FUSE_ROOT_ID && name.eq(".."))
970 || name.is_empty()
972 {
973 return Ok(Arc::clone(&pnode));
974 }
975
976 match pnode.child(name) {
977 Some(v) => Ok(v),
979 None => Err(Error::from_raw_os_error(libc::ENOENT)),
980 }
981 }
982
983 #[allow(dead_code)]
985 fn debug_print_all_inodes(&self) {
986 self.inodes.read().unwrap().debug_print_all_inodes();
987 }
988
989 fn lookup_node_ignore_enoent(
990 &self,
991 ctx: &Context,
992 parent: u64,
993 name: &str,
994 ) -> Result<Option<Arc<OverlayInode>>> {
995 match self.lookup_node(ctx, parent, name) {
996 Ok(n) => Ok(Some(Arc::clone(&n))),
997 Err(e) => {
998 if let Some(raw_error) = e.raw_os_error() {
999 if raw_error == libc::ENOENT {
1000 return Ok(None);
1001 }
1002 }
1003 Err(e)
1004 }
1005 }
1006 }
1007
1008 fn load_directory(&self, ctx: &Context, node: &Arc<OverlayInode>) -> Result<()> {
1010 if node.loaded.load(Ordering::Relaxed) {
1011 return Ok(());
1012 }
1013
1014 let childrens = node.scan_childrens(ctx)?;
1016
1017 let mut inode_store = self.inodes.write().unwrap();
1020 let mut node_children = node.childrens.lock().unwrap();
1022
1023 if node.loaded.load(Ordering::Relaxed) {
1025 return Ok(());
1026 }
1027
1028 for mut child in childrens.into_iter() {
1030 let ino = inode_store.alloc_inode(&child.path)?;
1032
1033 let name = child.name.clone();
1034 child.inode = ino;
1035 child.parent = Mutex::new(Arc::downgrade(node));
1037
1038 let arc_child = Arc::new(child);
1039 node_children.insert(name, arc_child.clone());
1040 inode_store.insert_inode(ino, arc_child.clone());
1042 }
1043
1044 node.loaded.store(true, Ordering::Relaxed);
1045
1046 Ok(())
1047 }
1048
1049 fn forget_one(&self, inode: Inode, count: u64) {
1050 if inode == self.root_inode() || inode == 0 {
1051 return;
1052 }
1053
1054 let v = match self.get_all_inode(inode) {
1055 Some(n) => n,
1056 None => {
1057 trace!("forget unknown inode: {}", inode);
1058 return;
1059 }
1060 };
1061
1062 let mut lookups = v.lookups.load(Ordering::Relaxed);
1064
1065 if lookups < count {
1066 lookups = 0;
1067 } else {
1068 lookups -= count;
1069 }
1070 v.lookups.store(lookups, Ordering::Relaxed);
1071
1072 if lookups == 0 {
1076 debug!("inode is forgotten: {}, name {}", inode, v.name);
1077 let _ = self.remove_inode(inode, None);
1078 let parent = v.parent.lock().unwrap();
1079
1080 if let Some(p) = parent.upgrade() {
1081 p.remove_child(v.name.as_str());
1083 }
1084 }
1085 }
1086
1087 fn do_lookup(&self, ctx: &Context, parent: Inode, name: &str) -> Result<Entry> {
1088 let node = self.lookup_node(ctx, parent, name)?;
1089
1090 if node.whiteout.load(Ordering::Relaxed) {
1091 return Err(Error::from_raw_os_error(libc::ENOENT));
1092 }
1093
1094 let st = node.stat64(ctx)?;
1095
1096 if utils::is_dir(st) && !node.loaded.load(Ordering::Relaxed) {
1097 self.load_directory(ctx, &node)?;
1098 }
1099
1100 let tmp = node.lookups.fetch_add(1, Ordering::Relaxed);
1102 trace!("lookup count: {}", tmp + 1);
1103 Ok(Entry {
1104 inode: node.inode,
1105 generation: 0,
1106 attr: st,
1107 attr_flags: 0,
1108 attr_timeout: self.config.attr_timeout,
1109 entry_timeout: self.config.entry_timeout,
1110 })
1111 }
1112
1113 fn do_statvfs(&self, ctx: &Context, inode: Inode) -> Result<statvfs64> {
1114 match self.get_active_inode(inode) {
1115 Some(ovi) => {
1116 let all_inodes = ovi.real_inodes.lock().unwrap();
1117 let real_inode = all_inodes
1118 .first()
1119 .ok_or(Error::other("backend inode not found"))?;
1120 real_inode.layer.statfs(ctx, real_inode.inode)
1121 }
1122 None => Err(Error::from_raw_os_error(libc::ENOENT)),
1123 }
1124 }
1125
1126 #[allow(clippy::too_many_arguments)]
1127 fn do_readdir(
1128 &self,
1129 ctx: &Context,
1130 inode: Inode,
1131 handle: u64,
1132 size: u32,
1133 offset: u64,
1134 is_readdirplus: bool,
1135 add_entry: &mut dyn FnMut(DirEntry, Option<Entry>) -> Result<usize>,
1136 ) -> Result<()> {
1137 trace!(
1138 "do_readir: handle: {}, size: {}, offset: {}",
1139 handle,
1140 size,
1141 offset
1142 );
1143 if size == 0 {
1144 return Ok(());
1145 }
1146
1147 let ovl_inode = match self.handles.lock().unwrap().get(&handle) {
1149 Some(dir) => dir.node.clone(),
1150 None => {
1151 let node = self.lookup_node(ctx, inode, ".")?;
1153
1154 let st = node.stat64(ctx)?;
1155 if !utils::is_dir(st) {
1156 return Err(Error::from_raw_os_error(libc::ENOTDIR));
1157 }
1158
1159 node.clone()
1160 }
1161 };
1162
1163 let mut childrens = Vec::new();
1164 childrens.push((".".to_string(), ovl_inode.clone()));
1166
1167 let parent_node = match ovl_inode.parent.lock().unwrap().upgrade() {
1169 Some(p) => p.clone(),
1170 None => self.root_node(),
1171 };
1172 childrens.push(("..".to_string(), parent_node));
1173
1174 for (_, child) in ovl_inode.childrens.lock().unwrap().iter() {
1175 if child.whiteout.load(Ordering::Relaxed) {
1177 continue;
1178 }
1179 childrens.push((child.name.clone(), child.clone()));
1180 }
1181
1182 let mut len: usize = 0;
1183 if offset >= childrens.len() as u64 {
1184 return Ok(());
1185 }
1186
1187 for (index, (name, child)) in (0_u64..).zip(childrens.into_iter()) {
1188 if index >= offset {
1189 let st = child.stat64(ctx)?;
1191 let dir_entry = DirEntry {
1192 ino: st.st_ino,
1193 offset: index + 1,
1194 type_: entry_type_from_mode(st.st_mode) as u32,
1195 name: name.as_bytes(),
1196 };
1197
1198 let entry = if is_readdirplus {
1199 child.lookups.fetch_add(1, Ordering::Relaxed);
1200 Some(Entry {
1201 inode: child.inode,
1202 generation: 0,
1203 attr: st,
1204 attr_flags: 0,
1205 attr_timeout: self.config.attr_timeout,
1206 entry_timeout: self.config.entry_timeout,
1207 })
1208 } else {
1209 None
1210 };
1211 match add_entry(dir_entry, entry) {
1212 Ok(0) => break,
1213 Ok(l) => {
1214 len += l;
1215 if len as u32 >= size {
1216 return Ok(());
1218 }
1219 }
1220
1221 Err(e) => {
1222 if len == 0 {
1224 return Err(e);
1225 } else {
1226 return Ok(());
1227 }
1228 }
1229 }
1230 }
1231 }
1232
1233 Ok(())
1234 }
1235
1236 fn do_mkdir(
1237 &self,
1238 ctx: &Context,
1239 parent_node: &Arc<OverlayInode>,
1240 name: &str,
1241 mode: u32,
1242 umask: u32,
1243 ) -> Result<()> {
1244 if self.upper_layer.is_none() {
1245 return Err(Error::from_raw_os_error(libc::EROFS));
1246 }
1247
1248 if parent_node.whiteout.load(Ordering::Relaxed) {
1250 return Err(Error::from_raw_os_error(libc::ENOENT));
1251 }
1252
1253 let mut delete_whiteout = false;
1254 let mut set_opaque = false;
1255 if let Some(n) = self.lookup_node_ignore_enoent(ctx, parent_node.inode, name)? {
1256 if !n.whiteout.load(Ordering::Relaxed) {
1258 return Err(Error::from_raw_os_error(libc::EEXIST));
1259 }
1260
1261 if n.in_upper_layer() {
1262 delete_whiteout = true;
1263 }
1264
1265 if !n.upper_layer_only() {
1267 set_opaque = true;
1268 }
1269 }
1270
1271 let pnode = self.copy_node_up(ctx, Arc::clone(parent_node))?;
1273
1274 let mut new_node = None;
1275 let path = format!("{}/{}", pnode.path, name);
1276 pnode.handle_upper_inode_locked(&mut |parent_real_inode| -> Result<bool> {
1277 let parent_real_inode = match parent_real_inode {
1278 Some(inode) => inode,
1279 None => {
1280 error!("BUG: parent doesn't have upper inode after copied up");
1281 return Err(Error::from_raw_os_error(libc::EINVAL));
1282 }
1283 };
1284
1285 if delete_whiteout {
1286 let _ = parent_real_inode.layer.delete_whiteout(
1287 ctx,
1288 parent_real_inode.inode,
1289 utils::to_cstring(name)?.as_c_str(),
1290 );
1291 }
1292 let ino = self.alloc_inode(&path)?;
1294 let child_dir = parent_real_inode.mkdir(ctx, name, mode, umask)?;
1295 if set_opaque {
1297 parent_real_inode.layer.set_opaque(ctx, child_dir.inode)?;
1298 }
1299 let ovi = OverlayInode::new_from_real_inode(name, ino, path.clone(), child_dir);
1300
1301 new_node.replace(ovi);
1302 Ok(false)
1303 })?;
1304
1305 let arc_node = Arc::new(new_node.unwrap());
1307 self.insert_inode(arc_node.inode, arc_node.clone());
1308 pnode.insert_child(name, arc_node);
1309 Ok(())
1310 }
1311
1312 fn do_mknod(
1313 &self,
1314 ctx: &Context,
1315 parent_node: &Arc<OverlayInode>,
1316 name: &str,
1317 mode: u32,
1318 rdev: u32,
1319 umask: u32,
1320 ) -> Result<()> {
1321 if self.upper_layer.is_none() {
1322 return Err(Error::from_raw_os_error(libc::EROFS));
1323 }
1324
1325 if parent_node.whiteout.load(Ordering::Relaxed) {
1327 return Err(Error::from_raw_os_error(libc::ENOENT));
1328 }
1329
1330 match self.lookup_node_ignore_enoent(ctx, parent_node.inode, name)? {
1331 Some(n) => {
1332 if !n.whiteout.load(Ordering::Relaxed) {
1334 return Err(Error::from_raw_os_error(libc::EEXIST));
1335 }
1336
1337 let pnode = self.copy_node_up(ctx, Arc::clone(parent_node))?;
1339 pnode.handle_upper_inode_locked(&mut |parent_real_inode| -> Result<bool> {
1340 let parent_real_inode = match parent_real_inode {
1341 Some(inode) => inode,
1342 None => {
1343 error!("BUG: parent doesn't have upper inode after copied up");
1344 return Err(Error::from_raw_os_error(libc::EINVAL));
1345 }
1346 };
1347
1348 if n.in_upper_layer() {
1349 let _ = parent_real_inode.layer.delete_whiteout(
1350 ctx,
1351 parent_real_inode.inode,
1352 utils::to_cstring(name)?.as_c_str(),
1353 );
1354 }
1355
1356 let child_ri = parent_real_inode.mknod(ctx, name, mode, rdev, umask)?;
1357
1358 n.add_upper_inode(child_ri, true);
1360 Ok(false)
1361 })?;
1362 }
1363 None => {
1364 let pnode = self.copy_node_up(ctx, Arc::clone(parent_node))?;
1366 let mut new_node = None;
1367 let path = format!("{}/{}", pnode.path, name);
1368 pnode.handle_upper_inode_locked(&mut |parent_real_inode| -> Result<bool> {
1369 let parent_real_inode = match parent_real_inode {
1370 Some(inode) => inode,
1371 None => {
1372 error!("BUG: parent doesn't have upper inode after copied up");
1373 return Err(Error::from_raw_os_error(libc::EINVAL));
1374 }
1375 };
1376
1377 let ino = self.alloc_inode(&path)?;
1379 let child_ri = parent_real_inode.mknod(ctx, name, mode, rdev, umask)?;
1380 let ovi = OverlayInode::new_from_real_inode(name, ino, path.clone(), child_ri);
1381
1382 new_node.replace(ovi);
1383 Ok(false)
1384 })?;
1385
1386 let arc_node = Arc::new(new_node.unwrap());
1388 self.insert_inode(arc_node.inode, arc_node.clone());
1389 pnode.insert_child(name, arc_node);
1390 }
1391 }
1392
1393 Ok(())
1394 }
1395
1396 fn do_create(
1397 &self,
1398 ctx: &Context,
1399 parent_node: &Arc<OverlayInode>,
1400 name: &str,
1401 args: CreateIn,
1402 ) -> Result<Option<u64>> {
1403 let upper = self
1404 .upper_layer
1405 .as_ref()
1406 .cloned()
1407 .ok_or_else(|| Error::from_raw_os_error(libc::EROFS))?;
1408
1409 if parent_node.whiteout.load(Ordering::Relaxed) {
1411 return Err(Error::from_raw_os_error(libc::ENOENT));
1412 }
1413
1414 let mut handle = None;
1415 let mut real_ino = 0u64;
1416 let new_ovi = match self.lookup_node_ignore_enoent(ctx, parent_node.inode, name)? {
1417 Some(n) => {
1418 if !n.whiteout.load(Ordering::Relaxed) {
1420 return Err(Error::from_raw_os_error(libc::EEXIST));
1421 }
1422
1423 let pnode = self.copy_node_up(ctx, Arc::clone(parent_node))?;
1425 pnode.handle_upper_inode_locked(&mut |parent_real_inode| -> Result<bool> {
1426 let parent_real_inode = match parent_real_inode {
1427 Some(inode) => inode,
1428 None => {
1429 error!("BUG: parent doesn't have upper inode after copied up");
1430 return Err(Error::from_raw_os_error(libc::EINVAL));
1431 }
1432 };
1433
1434 if n.in_upper_layer() {
1435 let _ = parent_real_inode.layer.delete_whiteout(
1436 ctx,
1437 parent_real_inode.inode,
1438 utils::to_cstring(name)?.as_c_str(),
1439 );
1440 }
1441
1442 let (child_ri, hd) = parent_real_inode.create(ctx, name, args)?;
1443 real_ino = child_ri.inode;
1444 handle = hd;
1445
1446 n.add_upper_inode(child_ri, true);
1448 Ok(false)
1449 })?;
1450 n.clone()
1451 }
1452 None => {
1453 let pnode = self.copy_node_up(ctx, Arc::clone(parent_node))?;
1455 let mut new_node = None;
1456 let path = format!("{}/{}", pnode.path, name);
1457 pnode.handle_upper_inode_locked(&mut |parent_real_inode| -> Result<bool> {
1458 let parent_real_inode = match parent_real_inode {
1459 Some(inode) => inode,
1460 None => {
1461 error!("BUG: parent doesn't have upper inode after copied up");
1462 return Err(Error::from_raw_os_error(libc::EINVAL));
1463 }
1464 };
1465
1466 let (child_ri, hd) = parent_real_inode.create(ctx, name, args)?;
1467 real_ino = child_ri.inode;
1468 handle = hd;
1469 let ino = self.alloc_inode(&path)?;
1471 let ovi = OverlayInode::new_from_real_inode(name, ino, path.clone(), child_ri);
1472
1473 new_node.replace(ovi);
1474 Ok(false)
1475 })?;
1476
1477 let arc_node = Arc::new(new_node.unwrap());
1479 self.insert_inode(arc_node.inode, arc_node.clone());
1480 pnode.insert_child(name, arc_node.clone());
1481 arc_node
1482 }
1483 };
1484
1485 let final_handle = match handle {
1486 Some(hd) => {
1487 if self.no_open.load(Ordering::Relaxed) {
1488 None
1489 } else {
1490 let handle = self.next_handle.fetch_add(1, Ordering::Relaxed);
1491 let handle_data = HandleData {
1492 node: new_ovi,
1493 real_handle: Some(RealHandle {
1494 layer: upper.clone(),
1495 in_upper_layer: true,
1496 inode: real_ino,
1497 handle: AtomicU64::new(hd),
1498 }),
1499 };
1500 self.handles
1501 .lock()
1502 .unwrap()
1503 .insert(handle, Arc::new(handle_data));
1504 Some(handle)
1505 }
1506 }
1507 None => None,
1508 };
1509 Ok(final_handle)
1510 }
1511
1512 fn do_link(
1513 &self,
1514 ctx: &Context,
1515 src_node: &Arc<OverlayInode>,
1516 new_parent: &Arc<OverlayInode>,
1517 name: &str,
1518 ) -> Result<()> {
1519 if self.upper_layer.is_none() {
1520 return Err(Error::from_raw_os_error(libc::EROFS));
1521 }
1522
1523 if src_node.whiteout.load(Ordering::Relaxed) || new_parent.whiteout.load(Ordering::Relaxed)
1525 {
1526 return Err(Error::from_raw_os_error(libc::ENOENT));
1527 }
1528
1529 let st = src_node.stat64(ctx)?;
1530 if utils::is_dir(st) {
1531 return Err(Error::from_raw_os_error(libc::EPERM));
1533 }
1534
1535 let src_node = self.copy_node_up(ctx, Arc::clone(src_node))?;
1536 let new_parent = self.copy_node_up(ctx, Arc::clone(new_parent))?;
1537 let src_ino = src_node.first_layer_inode().2;
1538
1539 match self.lookup_node_ignore_enoent(ctx, new_parent.inode, name)? {
1540 Some(n) => {
1541 if !n.whiteout.load(Ordering::Relaxed) {
1543 return Err(Error::from_raw_os_error(libc::EEXIST));
1544 }
1545
1546 new_parent.handle_upper_inode_locked(&mut |parent_real_inode| -> Result<bool> {
1548 let parent_real_inode = match parent_real_inode {
1549 Some(inode) => inode,
1550 None => {
1551 error!("BUG: parent doesn't have upper inode after copied up");
1552 return Err(Error::from_raw_os_error(libc::EINVAL));
1553 }
1554 };
1555
1556 if n.in_upper_layer() {
1558 let _ = parent_real_inode.layer.delete_whiteout(
1559 ctx,
1560 parent_real_inode.inode,
1561 utils::to_cstring(name)?.as_c_str(),
1562 );
1563 }
1564
1565 let child_ri = parent_real_inode.link(ctx, src_ino, name)?;
1566
1567 n.add_upper_inode(child_ri, true);
1569 Ok(false)
1570 })?;
1571 }
1572 None => {
1573 let mut new_node = None;
1575 new_parent.handle_upper_inode_locked(&mut |parent_real_inode| -> Result<bool> {
1576 let parent_real_inode = match parent_real_inode {
1577 Some(inode) => inode,
1578 None => {
1579 error!("BUG: parent doesn't have upper inode after copied up");
1580 return Err(Error::from_raw_os_error(libc::EINVAL));
1581 }
1582 };
1583
1584 let path = format!("{}/{}", new_parent.path, name);
1586 let ino = self.alloc_inode(&path)?;
1587 let child_ri = parent_real_inode.link(ctx, src_ino, name)?;
1588 let ovi = OverlayInode::new_from_real_inode(name, ino, path, child_ri);
1589
1590 new_node.replace(ovi);
1591 Ok(false)
1592 })?;
1593
1594 let arc_node = Arc::new(new_node.unwrap());
1596 self.insert_inode(arc_node.inode, arc_node.clone());
1597 new_parent.insert_child(name, arc_node);
1598 }
1599 }
1600
1601 Ok(())
1602 }
1603
1604 fn do_symlink(
1605 &self,
1606 ctx: &Context,
1607 linkname: &str,
1608 parent_node: &Arc<OverlayInode>,
1609 name: &str,
1610 ) -> Result<()> {
1611 if self.upper_layer.is_none() {
1612 return Err(Error::from_raw_os_error(libc::EROFS));
1613 }
1614
1615 if parent_node.whiteout.load(Ordering::Relaxed) {
1617 return Err(Error::from_raw_os_error(libc::ENOENT));
1618 }
1619
1620 match self.lookup_node_ignore_enoent(ctx, parent_node.inode, name)? {
1621 Some(n) => {
1622 if !n.whiteout.load(Ordering::Relaxed) {
1624 return Err(Error::from_raw_os_error(libc::EEXIST));
1625 }
1626
1627 let pnode = self.copy_node_up(ctx, Arc::clone(parent_node))?;
1629 pnode.handle_upper_inode_locked(&mut |parent_real_inode| -> Result<bool> {
1630 let parent_real_inode = match parent_real_inode {
1631 Some(inode) => inode,
1632 None => {
1633 error!("BUG: parent doesn't have upper inode after copied up");
1634 return Err(Error::from_raw_os_error(libc::EINVAL));
1635 }
1636 };
1637
1638 if n.in_upper_layer() {
1639 let _ = parent_real_inode.layer.delete_whiteout(
1640 ctx,
1641 parent_real_inode.inode,
1642 utils::to_cstring(name)?.as_c_str(),
1643 );
1644 }
1645
1646 let child_ri = parent_real_inode.symlink(ctx, linkname, name)?;
1647
1648 n.add_upper_inode(child_ri, true);
1650 Ok(false)
1651 })?;
1652 }
1653 None => {
1654 let pnode = self.copy_node_up(ctx, Arc::clone(parent_node))?;
1656 let mut new_node = None;
1657 let path = format!("{}/{}", pnode.path, name);
1658 pnode.handle_upper_inode_locked(&mut |parent_real_inode| -> Result<bool> {
1659 let parent_real_inode = match parent_real_inode {
1660 Some(inode) => inode,
1661 None => {
1662 error!("BUG: parent doesn't have upper inode after copied up");
1663 return Err(Error::from_raw_os_error(libc::EINVAL));
1664 }
1665 };
1666
1667 let ino = self.alloc_inode(&path)?;
1669 let child_ri = parent_real_inode.symlink(ctx, linkname, name)?;
1670 let ovi = OverlayInode::new_from_real_inode(name, ino, path.clone(), child_ri);
1671
1672 new_node.replace(ovi);
1673 Ok(false)
1674 })?;
1675
1676 let arc_node = Arc::new(new_node.unwrap());
1678 self.insert_inode(arc_node.inode, arc_node.clone());
1679 pnode.insert_child(name, arc_node);
1680 }
1681 }
1682
1683 Ok(())
1684 }
1685
1686 fn copy_symlink_up(&self, ctx: &Context, node: Arc<OverlayInode>) -> Result<Arc<OverlayInode>> {
1687 if node.in_upper_layer() {
1688 return Ok(node);
1689 }
1690
1691 let parent_node = if let Some(ref n) = node.parent.lock().unwrap().upgrade() {
1692 Arc::clone(n)
1693 } else {
1694 return Err(Error::other("no parent?"));
1695 };
1696
1697 let (self_layer, _, self_inode) = node.first_layer_inode();
1698
1699 if !parent_node.in_upper_layer() {
1700 parent_node.create_upper_dir(ctx, None)?;
1701 }
1702
1703 let path = self_layer.readlink(ctx, self_inode)?;
1705 let path =
1707 std::str::from_utf8(&path).map_err(|_| Error::from_raw_os_error(libc::EINVAL))?;
1708
1709 let mut new_upper_real = None;
1710 parent_node.handle_upper_inode_locked(&mut |parent_upper_inode| -> Result<bool> {
1711 let parent_real_inode =
1713 parent_upper_inode.ok_or_else(|| Error::from_raw_os_error(libc::EROFS))?;
1714 new_upper_real.replace(parent_real_inode.symlink(ctx, path, node.name.as_str())?);
1715 Ok(false)
1716 })?;
1717
1718 if let Some(real_inode) = new_upper_real {
1719 node.add_upper_inode(real_inode, true);
1721 }
1722
1723 Ok(Arc::clone(&node))
1724 }
1725
1726 fn copy_regfile_up(&self, ctx: &Context, node: Arc<OverlayInode>) -> Result<Arc<OverlayInode>> {
1729 if node.in_upper_layer() {
1730 return Ok(node);
1731 }
1732
1733 let parent_node = if let Some(ref n) = node.parent.lock().unwrap().upgrade() {
1734 Arc::clone(n)
1735 } else {
1736 return Err(Error::other("no parent?"));
1737 };
1738
1739 let st = node.stat64(ctx)?;
1740 let (lower_layer, _, lower_inode) = node.first_layer_inode();
1741
1742 if !parent_node.in_upper_layer() {
1743 parent_node.create_upper_dir(ctx, None)?;
1744 }
1745
1746 let args = CreateIn {
1748 flags: libc::O_WRONLY as u32,
1749 mode: st.st_mode,
1750 umask: 0,
1751 fuse_flags: 0,
1752 };
1753
1754 let mut upper_handle = 0u64;
1755 let mut upper_real_inode = None;
1756 parent_node.handle_upper_inode_locked(&mut |parent_upper_inode| -> Result<bool> {
1757 let parent_real_inode = parent_upper_inode.ok_or_else(|| {
1759 error!("parent {} has no upper inode", parent_node.inode);
1760 Error::from_raw_os_error(libc::EINVAL)
1761 })?;
1762 let (inode, h) = parent_real_inode.create(ctx, node.name.as_str(), args)?;
1763 upper_handle = h.unwrap_or(0);
1764 upper_real_inode.replace(inode);
1765 Ok(false)
1766 })?;
1767
1768 let (h, _, _) = lower_layer.open(ctx, lower_inode, libc::O_RDONLY as u32, 0)?;
1769
1770 let lower_handle = h.unwrap_or(0);
1771
1772 let mut file = TempFile::new().unwrap().into_file();
1779 let mut offset: usize = 0;
1780 let size = 4 * 1024 * 1024;
1781 loop {
1782 let ret = lower_layer.read(
1783 ctx,
1784 lower_inode,
1785 lower_handle,
1786 &mut file,
1787 size,
1788 offset as u64,
1789 None,
1790 0,
1791 )?;
1792 if ret == 0 {
1793 break;
1794 }
1795
1796 offset += ret;
1797 }
1798 lower_layer.release(ctx, lower_inode, 0, lower_handle, true, true, None)?;
1800
1801 file.seek(SeekFrom::Start(0))?;
1802 offset = 0;
1803
1804 while let Some(ref ri) = upper_real_inode {
1805 let ret = ri.layer.write(
1806 ctx,
1807 ri.inode,
1808 upper_handle,
1809 &mut file,
1810 size,
1811 offset as u64,
1812 None,
1813 false,
1814 0,
1815 0,
1816 )?;
1817 if ret == 0 {
1818 break;
1819 }
1820
1821 offset += ret;
1822 }
1823
1824 drop(file);
1826
1827 if let Some(ri) = upper_real_inode {
1828 if let Err(e) = ri
1829 .layer
1830 .release(ctx, ri.inode, 0, upper_handle, true, true, None)
1831 {
1832 if e.raw_os_error() != Some(libc::ENOSYS) {
1834 return Err(e);
1835 }
1836 }
1837
1838 node.add_upper_inode(ri, true);
1840 }
1841
1842 Ok(Arc::clone(&node))
1843 }
1844
1845 fn copy_node_up(&self, ctx: &Context, node: Arc<OverlayInode>) -> Result<Arc<OverlayInode>> {
1846 if node.in_upper_layer() {
1847 return Ok(node);
1848 }
1849
1850 let st = node.stat64(ctx)?;
1851 if utils::is_dir(st) {
1853 node.create_upper_dir(ctx, None)?;
1854 return Ok(Arc::clone(&node));
1855 }
1856
1857 if st.st_mode & libc::S_IFMT == libc::S_IFLNK {
1859 return self.copy_symlink_up(ctx, Arc::clone(&node));
1860 }
1861
1862 self.copy_regfile_up(ctx, Arc::clone(&node))
1864 }
1865
1866 fn do_rm(&self, ctx: &Context, parent: u64, name: &CStr, dir: bool) -> Result<()> {
1867 if self.upper_layer.is_none() {
1868 return Err(Error::from_raw_os_error(libc::EROFS));
1869 }
1870
1871 let pnode = self.lookup_node(ctx, parent, "")?;
1873 if pnode.whiteout.load(Ordering::Relaxed) {
1874 return Err(Error::from_raw_os_error(libc::ENOENT));
1875 }
1876
1877 let sname = name.to_string_lossy().to_string();
1879 let node = self.lookup_node(ctx, parent, sname.as_str())?;
1880 if node.whiteout.load(Ordering::Relaxed) {
1881 return Err(Error::from_raw_os_error(libc::ENOENT));
1883 }
1884
1885 if dir {
1886 self.load_directory(ctx, &node)?;
1887 let (count, whiteouts) = node.count_entries_and_whiteout(ctx)?;
1888 trace!("entries: {}, whiteouts: {}\n", count, whiteouts);
1889 if count > 0 {
1890 return Err(Error::from_raw_os_error(libc::ENOTEMPTY));
1891 }
1892
1893 if whiteouts > 0 && node.in_upper_layer() {
1895 self.empty_node_directory(ctx, Arc::clone(&node))?;
1896 }
1897
1898 trace!("whiteouts deleted!\n");
1899 }
1900
1901 let mut need_whiteout = true;
1902 let pnode = self.copy_node_up(ctx, Arc::clone(&pnode))?;
1903
1904 if node.upper_layer_only() {
1905 need_whiteout = false;
1906 }
1907
1908 let mut path_removed = None;
1909 if node.in_upper_layer() {
1910 pnode.handle_upper_inode_locked(&mut |parent_upper_inode| -> Result<bool> {
1911 let parent_real_inode = parent_upper_inode.ok_or_else(|| {
1912 error!(
1913 "BUG: parent {} has no upper inode after copy up",
1914 pnode.inode
1915 );
1916 Error::from_raw_os_error(libc::EINVAL)
1917 })?;
1918
1919 if parent_real_inode.opaque {
1921 need_whiteout = false;
1922 }
1923 if dir {
1924 parent_real_inode
1925 .layer
1926 .rmdir(ctx, parent_real_inode.inode, name)?;
1927 } else {
1928 parent_real_inode
1929 .layer
1930 .unlink(ctx, parent_real_inode.inode, name)?;
1931 }
1932
1933 Ok(false)
1934 })?;
1935
1936 path_removed.replace(node.path.clone());
1937 }
1938
1939 trace!(
1940 "Remove inode {} from global hashmap and parent's children hashmap\n",
1941 node.inode
1942 );
1943
1944 node.lookups.fetch_sub(1, Ordering::Relaxed);
1946
1947 self.remove_inode(node.inode, path_removed);
1949 pnode.remove_child(node.name.as_str());
1950
1951 if need_whiteout {
1952 trace!("do_rm: creating whiteout\n");
1953 pnode.handle_upper_inode_locked(&mut |parent_upper_inode| -> Result<bool> {
1955 let parent_real_inode = parent_upper_inode.ok_or_else(|| {
1956 error!(
1957 "BUG: parent {} has no upper inode after copy up",
1958 pnode.inode
1959 );
1960 Error::from_raw_os_error(libc::EINVAL)
1961 })?;
1962
1963 let child_ri = parent_real_inode.create_whiteout(ctx, sname.as_str())?;
1964 let path = format!("{}/{}", pnode.path, sname);
1965 let ino = self.alloc_inode(&path)?;
1966 let ovi = Arc::new(OverlayInode::new_from_real_inode(
1967 sname.as_str(),
1968 ino,
1969 path.clone(),
1970 child_ri,
1971 ));
1972
1973 self.insert_inode(ino, ovi.clone());
1974 pnode.insert_child(sname.as_str(), ovi.clone());
1975 Ok(false)
1976 })?;
1977 }
1978
1979 Ok(())
1980 }
1981
1982 fn do_fsync(
1983 &self,
1984 ctx: &Context,
1985 inode: Inode,
1986 datasync: bool,
1987 handle: Handle,
1988 syncdir: bool,
1989 ) -> Result<()> {
1990 let data = self.get_data(ctx, Some(handle), inode, libc::O_RDONLY as u32)?;
1992
1993 match data.real_handle {
1994 None => Err(Error::from_raw_os_error(libc::ENOENT)),
1996 Some(ref rh) => {
1997 let real_handle = rh.handle.load(Ordering::Relaxed);
1998 if syncdir {
2000 rh.layer.fsyncdir(ctx, rh.inode, datasync, real_handle)
2001 } else {
2002 rh.layer.fsync(ctx, rh.inode, datasync, real_handle)
2003 }
2004 }
2005 }
2006 }
2007
2008 fn empty_node_directory(&self, ctx: &Context, node: Arc<OverlayInode>) -> Result<()> {
2010 let st = node.stat64(ctx)?;
2011 if !utils::is_dir(st) {
2012 return Err(Error::from_raw_os_error(libc::ENOTDIR));
2014 }
2015
2016 let (layer, in_upper, inode) = node.first_layer_inode();
2017 if !in_upper {
2018 return Ok(());
2019 }
2020
2021 let iter = node
2024 .childrens
2025 .lock()
2026 .unwrap()
2027 .values()
2028 .cloned()
2029 .collect::<Vec<_>>();
2030
2031 for child in iter {
2032 if child.in_upper_layer() {
2034 if child.whiteout.load(Ordering::Relaxed) {
2035 layer.delete_whiteout(
2036 ctx,
2037 inode,
2038 utils::to_cstring(child.name.as_str())?.as_c_str(),
2039 )?
2040 } else {
2041 let s = child.stat64(ctx)?;
2042 let cname = utils::to_cstring(&child.name)?;
2043 if utils::is_dir(s) {
2044 let (count, whiteouts) = child.count_entries_and_whiteout(ctx)?;
2045 if count + whiteouts > 0 {
2046 self.empty_node_directory(ctx, Arc::clone(&child))?;
2047 }
2048
2049 layer.rmdir(ctx, inode, cname.as_c_str())?
2050 } else {
2051 layer.unlink(ctx, inode, cname.as_c_str())?;
2052 }
2053 }
2054
2055 self.remove_inode(child.inode, Some(child.path.clone()));
2057 node.remove_child(child.name.as_str());
2058 }
2059 }
2060
2061 Ok(())
2062 }
2063
2064 fn find_real_info_from_handle(
2065 &self,
2066 handle: Handle,
2067 ) -> Result<(Arc<BoxedLayer>, Inode, Handle)> {
2068 match self.handles.lock().unwrap().get(&handle) {
2069 Some(h) => match h.real_handle {
2070 Some(ref rhd) => Ok((
2071 rhd.layer.clone(),
2072 rhd.inode,
2073 rhd.handle.load(Ordering::Relaxed),
2074 )),
2075 None => Err(Error::from_raw_os_error(libc::ENOENT)),
2076 },
2077
2078 None => Err(Error::from_raw_os_error(libc::ENOENT)),
2079 }
2080 }
2081
2082 fn find_real_inode(&self, inode: Inode) -> Result<(Arc<BoxedLayer>, Inode)> {
2083 if let Some(n) = self.get_active_inode(inode) {
2084 let (first_layer, _, first_inode) = n.first_layer_inode();
2085 return Ok((first_layer, first_inode));
2086 }
2087
2088 Err(Error::from_raw_os_error(libc::ENOENT))
2089 }
2090
2091 fn get_data(
2092 &self,
2093 ctx: &Context,
2094 handle: Option<Handle>,
2095 inode: Inode,
2096 flags: u32,
2097 ) -> Result<Arc<HandleData>> {
2098 let no_open = self.no_open.load(Ordering::Relaxed);
2099 if !no_open {
2100 if let Some(h) = handle {
2101 if let Some(v) = self.handles.lock().unwrap().get(&h) {
2102 if v.node.inode == inode {
2103 return Ok(Arc::clone(v));
2104 }
2105 }
2106 }
2107 } else {
2108 let readonly: bool = flags
2109 & (libc::O_APPEND | libc::O_CREAT | libc::O_TRUNC | libc::O_RDWR | libc::O_WRONLY)
2110 as u32
2111 == 0;
2112
2113 let node = self.lookup_node(ctx, inode, "")?;
2115
2116 if node.whiteout.load(Ordering::Relaxed) {
2118 return Err(Error::from_raw_os_error(libc::ENOENT));
2119 }
2120
2121 if !readonly {
2122 self.upper_layer
2124 .as_ref()
2125 .cloned()
2126 .ok_or_else(|| Error::from_raw_os_error(libc::EROFS))?;
2127 self.copy_node_up(ctx, Arc::clone(&node))?;
2129 }
2130
2131 let (layer, in_upper_layer, inode) = node.first_layer_inode();
2132 let handle_data = HandleData {
2133 node: Arc::clone(&node),
2134 real_handle: Some(RealHandle {
2135 layer,
2136 in_upper_layer,
2137 inode,
2138 handle: AtomicU64::new(0),
2139 }),
2140 };
2141 return Ok(Arc::new(handle_data));
2142 }
2143
2144 Err(Error::from_raw_os_error(libc::ENOENT))
2145 }
2146}
2147
2148impl ZeroCopyReader for File {
2149 fn read_to(
2152 &mut self,
2153 f: &mut dyn FileReadWriteVolatile,
2154 count: usize,
2155 off: u64,
2156 ) -> Result<usize> {
2157 let mut buf = vec![0_u8; count];
2158 let slice = unsafe { FileVolatileSlice::from_raw_ptr(buf.as_mut_ptr(), count) };
2159
2160 let ret = self.read_volatile(slice)?;
2162 if ret > 0 {
2163 let slice = unsafe { FileVolatileSlice::from_raw_ptr(buf.as_mut_ptr(), ret) };
2164 f.write_at_volatile(slice, off)
2166 } else {
2167 Ok(0)
2168 }
2169 }
2170}
2171
2172impl ZeroCopyWriter for File {
2173 fn write_from(
2176 &mut self,
2177 f: &mut dyn FileReadWriteVolatile,
2178 count: usize,
2179 off: u64,
2180 ) -> Result<usize> {
2181 let mut buf = vec![0_u8; count];
2182 let slice = unsafe { FileVolatileSlice::from_raw_ptr(buf.as_mut_ptr(), count) };
2183 let ret = f.read_at_volatile(slice, off)?;
2185
2186 if ret > 0 {
2187 let slice = unsafe { FileVolatileSlice::from_raw_ptr(buf.as_mut_ptr(), ret) };
2188 self.write_volatile(slice)
2190 } else {
2191 Ok(0)
2192 }
2193 }
2194
2195 fn available_bytes(&self) -> usize {
2196 usize::MAX
2198 }
2199}
2200
2201#[cfg(not(feature = "async-io"))]
2202impl BackendFileSystem for OverlayFs {
2203 fn mount(&self) -> Result<(Entry, u64)> {
2206 let ctx = Context::default();
2207 let entry = self.do_lookup(&ctx, self.root_inode(), "")?;
2208 Ok((entry, VFS_MAX_INO))
2209 }
2210
2211 fn as_any(&self) -> &dyn std::any::Any {
2215 self
2216 }
2217}