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, _)) => match handle {
248 Some(h) => h,
249 _ => 0,
250 },
251 Err(e) => {
253 match e.raw_os_error() {
254 Some(raw_error) => {
255 if raw_error == libc::ENOSYS {
256 0
258 } else {
259 return Err(e);
260 }
261 }
262 None => {
263 return Err(e);
264 }
265 }
266 }
267 };
268
269 let mut child_names = vec![];
270 let mut more = true;
271 let mut offset = 0;
272 let bufsize = 1024;
273 while more {
274 more = false;
275 self.layer.readdir(
276 ctx,
277 self.inode,
278 handle,
279 bufsize,
280 offset,
281 &mut |d| -> Result<usize> {
282 more = true;
283 offset = d.offset;
284 let child_name = String::from_utf8_lossy(d.name).into_owned();
285
286 trace!("entry: {}", child_name.as_str());
287
288 if child_name.eq(CURRENT_DIR) || child_name.eq(PARENT_DIR) {
289 return Ok(1);
290 }
291
292 child_names.push(child_name);
293
294 Ok(1)
295 },
296 )?;
297 }
298
299 if handle > 0 {
301 if let Err(e) = self
302 .layer
303 .releasedir(ctx, self.inode, libc::O_RDONLY as u32, handle)
304 {
305 match e.raw_os_error() {
307 Some(raw_error) => {
308 if raw_error != libc::ENOSYS {
309 return Err(e);
310 }
311 }
312 None => {
313 return Err(e);
314 }
315 }
316 }
317 }
318
319 let mut child_real_inodes = HashMap::new();
321 for name in child_names {
322 if let Some(child) = self.lookup_child(ctx, name.as_str())? {
323 child_real_inodes.insert(name, child);
324 }
325 }
326
327 Ok(child_real_inodes)
328 }
329
330 fn create_whiteout(&self, ctx: &Context, name: &str) -> Result<RealInode> {
331 if !self.in_upper_layer {
332 return Err(Error::from_raw_os_error(libc::EROFS));
333 }
334
335 let cname = utils::to_cstring(name)?;
336 let entry = self
337 .layer
338 .create_whiteout(ctx, self.inode, cname.as_c_str())?;
339
340 Ok(RealInode {
342 layer: self.layer.clone(),
343 in_upper_layer: true,
344 inode: entry.inode,
345 whiteout: true,
346 opaque: false,
347 stat: Some(entry.attr),
348 })
349 }
350
351 fn mkdir(&self, ctx: &Context, name: &str, mode: u32, umask: u32) -> Result<RealInode> {
352 if !self.in_upper_layer {
353 return Err(Error::from_raw_os_error(libc::EROFS));
354 }
355
356 let cname = utils::to_cstring(name)?;
357 let entry = self
358 .layer
359 .mkdir(ctx, self.inode, cname.as_c_str(), mode, umask)?;
360
361 Ok(RealInode {
363 layer: self.layer.clone(),
364 in_upper_layer: true,
365 inode: entry.inode,
366 whiteout: false,
367 opaque: false,
368 stat: Some(entry.attr),
369 })
370 }
371
372 fn create(
373 &self,
374 ctx: &Context,
375 name: &str,
376 args: CreateIn,
377 ) -> Result<(RealInode, Option<u64>)> {
378 if !self.in_upper_layer {
379 return Err(Error::from_raw_os_error(libc::EROFS));
380 }
381
382 let (entry, h, _, _) =
383 self.layer
384 .create(ctx, self.inode, utils::to_cstring(name)?.as_c_str(), args)?;
385
386 Ok((
387 RealInode {
388 layer: self.layer.clone(),
389 in_upper_layer: true,
390 inode: entry.inode,
391 whiteout: false,
392 opaque: false,
393 stat: Some(entry.attr),
394 },
395 h,
396 ))
397 }
398
399 fn mknod(
400 &self,
401 ctx: &Context,
402 name: &str,
403 mode: u32,
404 rdev: u32,
405 umask: u32,
406 ) -> Result<RealInode> {
407 if !self.in_upper_layer {
408 return Err(Error::from_raw_os_error(libc::EROFS));
409 }
410
411 let entry = self.layer.mknod(
412 ctx,
413 self.inode,
414 utils::to_cstring(name)?.as_c_str(),
415 mode,
416 rdev,
417 umask,
418 )?;
419 Ok(RealInode {
420 layer: self.layer.clone(),
421 in_upper_layer: true,
422 inode: entry.inode,
423 whiteout: false,
424 opaque: false,
425 stat: Some(entry.attr),
426 })
427 }
428
429 fn link(&self, ctx: &Context, ino: u64, name: &str) -> Result<RealInode> {
430 if !self.in_upper_layer {
431 return Err(Error::from_raw_os_error(libc::EROFS));
432 }
433
434 let entry = self
435 .layer
436 .link(ctx, ino, self.inode, utils::to_cstring(name)?.as_c_str())?;
437
438 let opaque = if utils::is_dir(entry.attr) {
439 self.layer.is_opaque(ctx, entry.inode)?
440 } else {
441 false
442 };
443 Ok(RealInode {
444 layer: self.layer.clone(),
445 in_upper_layer: true,
446 inode: entry.inode,
447 whiteout: false,
448 opaque,
449 stat: Some(entry.attr),
450 })
451 }
452
453 fn symlink(&self, ctx: &Context, link_name: &str, filename: &str) -> Result<RealInode> {
455 if !self.in_upper_layer {
456 return Err(Error::from_raw_os_error(libc::EROFS));
457 }
458
459 let entry = self.layer.symlink(
460 ctx,
461 utils::to_cstring(link_name)?.as_c_str(),
462 self.inode,
463 utils::to_cstring(filename)?.as_c_str(),
464 )?;
465
466 Ok(RealInode {
467 layer: self.layer.clone(),
468 in_upper_layer: self.in_upper_layer,
469 inode: entry.inode,
470 whiteout: false,
471 opaque: false,
472 stat: Some(entry.attr),
473 })
474 }
475}
476
477impl Drop for RealInode {
478 fn drop(&mut self) {
479 let ctx = Context::default();
481 let layer = self.layer.as_ref();
482 let inode = self.inode;
483 debug!("forget inode {} by 1 for backend inode in layer ", inode);
484 layer.forget(&ctx, inode, 1);
485 }
486}
487
488impl OverlayInode {
489 pub fn new() -> Self {
490 OverlayInode::default()
491 }
492
493 pub fn new_from_real_inode(name: &str, ino: u64, path: String, real_inode: RealInode) -> Self {
496 let mut new = OverlayInode::new();
497 new.inode = ino;
498 new.path = path.clone();
499 new.name = name.to_string();
500 new.whiteout.store(real_inode.whiteout, Ordering::Relaxed);
501 new.lookups = AtomicU64::new(1);
502 new.real_inodes = Mutex::new(vec![real_inode]);
503 new
504 }
505
506 pub fn new_from_real_inodes(
507 name: &str,
508 ino: u64,
509 path: String,
510 real_inodes: Vec<RealInode>,
511 ) -> Result<Self> {
512 if real_inodes.is_empty() {
513 error!("BUG: new_from_real_inodes() called with empty real_inodes");
514 return Err(Error::from_raw_os_error(libc::EINVAL));
515 }
516
517 let mut first = true;
518 let mut new = Self::new();
519 for ri in real_inodes {
520 let whiteout = ri.whiteout;
521 let opaque = ri.opaque;
522 let stat = match ri.stat {
523 Some(v) => v,
524 None => ri.stat64(&Context::default())?,
525 };
526
527 if first {
528 first = false;
529 new = Self::new_from_real_inode(name, ino, path.clone(), ri);
530
531 if whiteout {
533 break;
534 }
535
536 if !utils::is_dir(stat) {
538 break;
539 }
540
541 if opaque {
543 break;
544 }
545 } else {
546 if ri.whiteout {
548 break;
549 }
550
551 if !utils::is_dir(stat) {
554 error!("invalid layout: non-directory has multiple real inodes");
555 break;
556 }
557
558 new.real_inodes.lock().unwrap().push(ri);
560 if opaque {
562 break;
563 }
564 }
565 }
566 Ok(new)
567 }
568
569 pub fn stat64(&self, ctx: &Context) -> Result<stat64> {
570 for l in self.real_inodes.lock().unwrap().iter() {
572 if let Some(v) = l.stat64_ignore_enoent(ctx)? {
573 return Ok(v);
574 }
575 }
576
577 Err(Error::from_raw_os_error(libc::ENOENT))
579 }
580
581 pub fn count_entries_and_whiteout(&self, ctx: &Context) -> Result<(u64, u64)> {
582 let mut count = 0;
583 let mut whiteouts = 0;
584
585 let st = self.stat64(ctx)?;
586
587 if !utils::is_dir(st) {
589 return Err(Error::from_raw_os_error(libc::ENOTDIR));
590 }
591
592 for (_, child) in self.childrens.lock().unwrap().iter() {
593 if child.whiteout.load(Ordering::Relaxed) {
594 whiteouts += 1;
595 } else {
596 count += 1;
597 }
598 }
599
600 Ok((count, whiteouts))
601 }
602
603 pub fn open(
604 &self,
605 ctx: &Context,
606 flags: u32,
607 fuse_flags: u32,
608 ) -> Result<(Arc<BoxedLayer>, Option<Handle>, OpenOptions)> {
609 let (layer, _, inode) = self.first_layer_inode();
610 let (h, o, _) = layer.as_ref().open(ctx, inode, flags, fuse_flags)?;
611 Ok((layer, h, o))
612 }
613
614 pub fn scan_childrens(self: &Arc<Self>, ctx: &Context) -> Result<Vec<OverlayInode>> {
616 let st = self.stat64(ctx)?;
617 if !utils::is_dir(st) {
618 return Err(Error::from_raw_os_error(libc::ENOTDIR));
619 }
620
621 let mut all_layer_inodes: HashMap<String, Vec<RealInode>> = HashMap::new();
622 let mut counter = 1;
624 let layers_count = self.real_inodes.lock().unwrap().len();
625 for ri in self.real_inodes.lock().unwrap().iter() {
627 debug!(
628 "loading Layer {}/{} for dir '{}', is_upper_layer: {}",
629 counter,
630 layers_count,
631 self.path.as_str(),
632 ri.in_upper_layer
633 );
634 counter += 1;
635 if ri.whiteout {
636 debug!("directory is whiteout");
638 break;
639 }
640
641 let stat = match ri.stat {
642 Some(v) => v,
643 None => ri.stat64(ctx)?,
644 };
645
646 if !utils::is_dir(stat) {
647 debug!("{} is not a directory", self.path.as_str());
648 break;
650 }
651
652 let entries = ri.readdir(ctx)?;
654
655 for (name, inode) in entries {
657 match all_layer_inodes.get_mut(&name) {
658 Some(v) => {
659 v.push(inode)
661 }
662 None => {
663 all_layer_inodes.insert(name, vec![inode]);
664 }
665 };
666 }
667
668 if ri.opaque {
670 debug!("directory {} is opaque", self.path.as_str());
671 break;
672 }
673 }
674
675 let mut childrens = vec![];
677 for (name, real_inodes) in all_layer_inodes {
678 let path = format!("{}/{}", self.path, name);
680 let new = Self::new_from_real_inodes(name.as_str(), 0, path, real_inodes)?;
681 childrens.push(new);
682 }
683
684 Ok(childrens)
685 }
686
687 pub fn create_upper_dir(
689 self: &Arc<Self>,
690 ctx: &Context,
691 mode_umask: Option<(u32, u32)>,
692 ) -> Result<()> {
693 let st = self.stat64(ctx)?;
694 if !utils::is_dir(st) {
695 return Err(Error::from_raw_os_error(libc::ENOTDIR));
696 }
697
698 if self.in_upper_layer() {
700 return Ok(());
701 }
702
703 let pnode = if let Some(n) = self.parent.lock().unwrap().upgrade() {
705 Arc::clone(&n)
706 } else {
707 return Err(Error::new(ErrorKind::Other, "no parent?"));
708 };
709
710 if !pnode.in_upper_layer() {
711 pnode.create_upper_dir(ctx, None)?; }
713 let mut child = None;
714 pnode.handle_upper_inode_locked(&mut |parent_upper_inode| -> Result<bool> {
715 match parent_upper_inode {
716 Some(parent_ri) => {
717 let ri = match mode_umask {
718 Some((mode, umask)) => {
719 parent_ri.mkdir(ctx, self.name.as_str(), mode, umask)?
720 }
721 None => parent_ri.mkdir(ctx, self.name.as_str(), st.st_mode, 0)?,
722 };
723 child.replace(ri);
725 }
726 None => {
727 error!(
728 "BUG: parent {} has no upper inode after create_upper_dir",
729 pnode.inode
730 );
731 return Err(Error::from_raw_os_error(libc::EINVAL));
732 }
733 }
734 Ok(false)
735 })?;
736
737 if let Some(ri) = child {
738 self.add_upper_inode(ri, false);
740 }
741
742 Ok(())
743 }
744
745 fn add_upper_inode(self: &Arc<Self>, ri: RealInode, clear_lowers: bool) {
747 let mut inodes = self.real_inodes.lock().unwrap();
748 self.whiteout.store(ri.whiteout, Ordering::Relaxed);
750
751 let mut new = vec![ri];
753 let lowers = inodes.drain(..).collect::<Vec<RealInode>>();
755 if !clear_lowers {
756 new.extend(lowers);
758 }
759 inodes.extend(new);
760 }
761
762 pub fn in_upper_layer(&self) -> bool {
763 let all_inodes = self.real_inodes.lock().unwrap();
764 let first = all_inodes.first();
765 match first {
766 Some(v) => v.in_upper_layer,
767 None => false,
768 }
769 }
770
771 pub fn upper_layer_only(&self) -> bool {
772 let real_inodes = self.real_inodes.lock().unwrap();
773 let first = real_inodes.first();
774 match first {
775 Some(v) => {
776 if !v.in_upper_layer {
777 false
778 } else {
779 real_inodes.len() == 1
780 }
781 }
782 None => false,
783 }
784 }
785
786 pub fn first_layer_inode(&self) -> (Arc<BoxedLayer>, bool, u64) {
787 let all_inodes = self.real_inodes.lock().unwrap();
788 let first = all_inodes.first();
789 match first {
790 Some(v) => (v.layer.clone(), v.in_upper_layer, v.inode),
791 None => panic!("BUG: dangling OverlayInode"),
792 }
793 }
794
795 pub fn child(&self, name: &str) -> Option<Arc<OverlayInode>> {
796 self.childrens.lock().unwrap().get(name).cloned()
797 }
798
799 pub fn remove_child(&self, name: &str) {
800 self.childrens.lock().unwrap().remove(name);
801 }
802
803 pub fn insert_child(&self, name: &str, node: Arc<OverlayInode>) {
804 self.childrens
805 .lock()
806 .unwrap()
807 .insert(name.to_string(), node);
808 }
809
810 pub fn handle_upper_inode_locked(
811 &self,
812 f: &mut dyn FnMut(Option<&RealInode>) -> Result<bool>,
813 ) -> Result<bool> {
814 let all_inodes = self.real_inodes.lock().unwrap();
815 let first = all_inodes.first();
816 match first {
817 Some(v) => {
818 if v.in_upper_layer {
819 f(Some(v))
820 } else {
821 f(None)
822 }
823 }
824 None => Err(Error::new(
825 ErrorKind::Other,
826 format!(
827 "BUG: dangling OverlayInode {} without any backend inode",
828 self.inode
829 ),
830 )),
831 }
832 }
833}
834
835fn entry_type_from_mode(mode: libc::mode_t) -> u8 {
836 match mode & libc::S_IFMT {
837 libc::S_IFBLK => libc::DT_BLK,
838 libc::S_IFCHR => libc::DT_CHR,
839 libc::S_IFDIR => libc::DT_DIR,
840 libc::S_IFIFO => libc::DT_FIFO,
841 libc::S_IFLNK => libc::DT_LNK,
842 libc::S_IFREG => libc::DT_REG,
843 libc::S_IFSOCK => libc::DT_SOCK,
844 _ => libc::DT_UNKNOWN,
845 }
846}
847
848impl OverlayFs {
849 pub fn new(
850 upper: Option<Arc<BoxedLayer>>,
851 lowers: Vec<Arc<BoxedLayer>>,
852 params: Config,
853 ) -> Result<Self> {
854 Ok(OverlayFs {
856 config: params,
857 lower_layers: lowers,
858 upper_layer: upper,
859 inodes: RwLock::new(InodeStore::new()),
860 handles: Mutex::new(HashMap::new()),
861 next_handle: AtomicU64::new(1),
862 writeback: AtomicBool::new(false),
863 no_open: AtomicBool::new(false),
864 no_opendir: AtomicBool::new(false),
865 killpriv_v2: AtomicBool::new(false),
866 perfile_dax: AtomicBool::new(false),
867 })
868 }
869
870 pub fn root_inode(&self) -> Inode {
871 FUSE_ROOT_ID
872 }
873
874 fn alloc_inode(&self, path: &String) -> Result<u64> {
875 self.inodes.write().unwrap().alloc_inode(path)
876 }
877
878 pub fn import(&self) -> Result<()> {
879 let mut root = OverlayInode::new();
880 root.inode = FUSE_ROOT_ID;
881 root.path = String::from("");
882 root.name = String::from("");
883 root.lookups = AtomicU64::new(2);
884 root.real_inodes = Mutex::new(vec![]);
885 let ctx = Context::default();
886
887 if let Some(layer) = self.upper_layer.as_ref() {
889 let ino = layer.root_inode();
890 let real = RealInode::new(layer.clone(), true, ino, false, layer.is_opaque(&ctx, ino)?);
891 root.real_inodes.lock().unwrap().push(real);
892 }
893
894 for layer in self.lower_layers.iter() {
896 let ino = layer.root_inode();
897 let real = RealInode::new(
898 layer.clone(),
899 false,
900 ino,
901 false,
902 layer.is_opaque(&ctx, ino)?,
903 );
904 root.real_inodes.lock().unwrap().push(real);
905 }
906 let root_node = Arc::new(root);
907
908 self.insert_inode(FUSE_ROOT_ID, Arc::clone(&root_node));
910
911 info!("loading root directory\n");
912 self.load_directory(&ctx, &root_node)?;
913
914 Ok(())
915 }
916
917 fn root_node(&self) -> Arc<OverlayInode> {
918 self.get_active_inode(FUSE_ROOT_ID).unwrap()
920 }
921
922 fn insert_inode(&self, inode: u64, node: Arc<OverlayInode>) {
923 self.inodes.write().unwrap().insert_inode(inode, node);
924 }
925
926 fn get_active_inode(&self, inode: u64) -> Option<Arc<OverlayInode>> {
927 self.inodes.read().unwrap().get_inode(inode)
928 }
929
930 fn get_all_inode(&self, inode: u64) -> Option<Arc<OverlayInode>> {
932 let inode_store = self.inodes.read().unwrap();
933 match inode_store.get_inode(inode) {
934 Some(n) => Some(n),
935 None => inode_store.get_deleted_inode(inode),
936 }
937 }
938
939 fn remove_inode(&self, inode: u64, path_removed: Option<String>) -> Option<Arc<OverlayInode>> {
941 self.inodes
942 .write()
943 .unwrap()
944 .remove_inode(inode, path_removed)
945 }
946
947 fn lookup_node(&self, ctx: &Context, parent: Inode, name: &str) -> Result<Arc<OverlayInode>> {
951 if name.contains([SLASH_ASCII as char]) {
952 return Err(Error::from_raw_os_error(libc::EINVAL));
953 }
954
955 let pnode = match self.get_active_inode(parent) {
957 Some(v) => v,
958 None => return Err(Error::from_raw_os_error(libc::ENOENT)),
959 };
960
961 if pnode.whiteout.load(Ordering::Relaxed) {
963 return Err(Error::from_raw_os_error(libc::ENOENT));
964 }
965
966 let st = pnode.stat64(ctx)?;
967 if utils::is_dir(st) && !pnode.loaded.load(Ordering::Relaxed) {
968 self.load_directory(ctx, &pnode)?;
970 }
971
972 if name.eq(".")
974 || (parent == FUSE_ROOT_ID && name.eq(".."))
976 || name.is_empty()
978 {
979 return Ok(Arc::clone(&pnode));
980 }
981
982 match pnode.child(name) {
983 Some(v) => Ok(v),
985 None => Err(Error::from_raw_os_error(libc::ENOENT)),
986 }
987 }
988
989 #[allow(dead_code)]
991 fn debug_print_all_inodes(&self) {
992 self.inodes.read().unwrap().debug_print_all_inodes();
993 }
994
995 fn lookup_node_ignore_enoent(
996 &self,
997 ctx: &Context,
998 parent: u64,
999 name: &str,
1000 ) -> Result<Option<Arc<OverlayInode>>> {
1001 match self.lookup_node(ctx, parent, name) {
1002 Ok(n) => Ok(Some(Arc::clone(&n))),
1003 Err(e) => {
1004 if let Some(raw_error) = e.raw_os_error() {
1005 if raw_error == libc::ENOENT {
1006 return Ok(None);
1007 }
1008 }
1009 Err(e)
1010 }
1011 }
1012 }
1013
1014 fn load_directory(&self, ctx: &Context, node: &Arc<OverlayInode>) -> Result<()> {
1016 if node.loaded.load(Ordering::Relaxed) {
1017 return Ok(());
1018 }
1019
1020 let childrens = node.scan_childrens(ctx)?;
1022
1023 let mut inode_store = self.inodes.write().unwrap();
1026 let mut node_children = node.childrens.lock().unwrap();
1028
1029 if node.loaded.load(Ordering::Relaxed) {
1031 return Ok(());
1032 }
1033
1034 for mut child in childrens.into_iter() {
1036 let ino = inode_store.alloc_inode(&child.path)?;
1038
1039 let name = child.name.clone();
1040 child.inode = ino;
1041 child.parent = Mutex::new(Arc::downgrade(node));
1043
1044 let arc_child = Arc::new(child);
1045 node_children.insert(name, arc_child.clone());
1046 inode_store.insert_inode(ino, arc_child.clone());
1048 }
1049
1050 node.loaded.store(true, Ordering::Relaxed);
1051
1052 Ok(())
1053 }
1054
1055 fn forget_one(&self, inode: Inode, count: u64) {
1056 if inode == self.root_inode() || inode == 0 {
1057 return;
1058 }
1059
1060 let v = match self.get_all_inode(inode) {
1061 Some(n) => n,
1062 None => {
1063 trace!("forget unknown inode: {}", inode);
1064 return;
1065 }
1066 };
1067
1068 let mut lookups = v.lookups.load(Ordering::Relaxed);
1070
1071 if lookups < count {
1072 lookups = 0;
1073 } else {
1074 lookups -= count;
1075 }
1076 v.lookups.store(lookups, Ordering::Relaxed);
1077
1078 if lookups == 0 {
1082 debug!("inode is forgotten: {}, name {}", inode, v.name);
1083 let _ = self.remove_inode(inode, None);
1084 let parent = v.parent.lock().unwrap();
1085
1086 if let Some(p) = parent.upgrade() {
1087 p.remove_child(v.name.as_str());
1089 }
1090 }
1091 }
1092
1093 fn do_lookup(&self, ctx: &Context, parent: Inode, name: &str) -> Result<Entry> {
1094 let node = self.lookup_node(ctx, parent, name)?;
1095
1096 if node.whiteout.load(Ordering::Relaxed) {
1097 return Err(Error::from_raw_os_error(libc::ENOENT));
1098 }
1099
1100 let st = node.stat64(ctx)?;
1101
1102 if utils::is_dir(st) && !node.loaded.load(Ordering::Relaxed) {
1103 self.load_directory(ctx, &node)?;
1104 }
1105
1106 let tmp = node.lookups.fetch_add(1, Ordering::Relaxed);
1108 trace!("lookup count: {}", tmp + 1);
1109 Ok(Entry {
1110 inode: node.inode,
1111 generation: 0,
1112 attr: st,
1113 attr_flags: 0,
1114 attr_timeout: self.config.attr_timeout,
1115 entry_timeout: self.config.entry_timeout,
1116 })
1117 }
1118
1119 fn do_statvfs(&self, ctx: &Context, inode: Inode) -> Result<statvfs64> {
1120 match self.get_active_inode(inode) {
1121 Some(ovi) => {
1122 let all_inodes = ovi.real_inodes.lock().unwrap();
1123 let real_inode = all_inodes
1124 .first()
1125 .ok_or(Error::new(ErrorKind::Other, "backend inode not found"))?;
1126 real_inode.layer.statfs(ctx, real_inode.inode)
1127 }
1128 None => Err(Error::from_raw_os_error(libc::ENOENT)),
1129 }
1130 }
1131
1132 #[allow(clippy::too_many_arguments)]
1133 fn do_readdir(
1134 &self,
1135 ctx: &Context,
1136 inode: Inode,
1137 handle: u64,
1138 size: u32,
1139 offset: u64,
1140 is_readdirplus: bool,
1141 add_entry: &mut dyn FnMut(DirEntry, Option<Entry>) -> Result<usize>,
1142 ) -> Result<()> {
1143 trace!(
1144 "do_readir: handle: {}, size: {}, offset: {}",
1145 handle,
1146 size,
1147 offset
1148 );
1149 if size == 0 {
1150 return Ok(());
1151 }
1152
1153 let ovl_inode = match self.handles.lock().unwrap().get(&handle) {
1155 Some(dir) => dir.node.clone(),
1156 None => {
1157 let node = self.lookup_node(ctx, inode, ".")?;
1159
1160 let st = node.stat64(ctx)?;
1161 if !utils::is_dir(st) {
1162 return Err(Error::from_raw_os_error(libc::ENOTDIR));
1163 }
1164
1165 node.clone()
1166 }
1167 };
1168
1169 let mut childrens = Vec::new();
1170 childrens.push((".".to_string(), ovl_inode.clone()));
1172
1173 let parent_node = match ovl_inode.parent.lock().unwrap().upgrade() {
1175 Some(p) => p.clone(),
1176 None => self.root_node(),
1177 };
1178 childrens.push(("..".to_string(), parent_node));
1179
1180 for (_, child) in ovl_inode.childrens.lock().unwrap().iter() {
1181 if child.whiteout.load(Ordering::Relaxed) {
1183 continue;
1184 }
1185 childrens.push((child.name.clone(), child.clone()));
1186 }
1187
1188 let mut len: usize = 0;
1189 if offset >= childrens.len() as u64 {
1190 return Ok(());
1191 }
1192
1193 for (index, (name, child)) in (0_u64..).zip(childrens.into_iter()) {
1194 if index >= offset {
1195 let st = child.stat64(ctx)?;
1197 let dir_entry = DirEntry {
1198 ino: st.st_ino,
1199 offset: index + 1,
1200 type_: entry_type_from_mode(st.st_mode) as u32,
1201 name: name.as_bytes(),
1202 };
1203
1204 let entry = if is_readdirplus {
1205 child.lookups.fetch_add(1, Ordering::Relaxed);
1206 Some(Entry {
1207 inode: child.inode,
1208 generation: 0,
1209 attr: st,
1210 attr_flags: 0,
1211 attr_timeout: self.config.attr_timeout,
1212 entry_timeout: self.config.entry_timeout,
1213 })
1214 } else {
1215 None
1216 };
1217 match add_entry(dir_entry, entry) {
1218 Ok(0) => break,
1219 Ok(l) => {
1220 len += l;
1221 if len as u32 >= size {
1222 return Ok(());
1224 }
1225 }
1226
1227 Err(e) => {
1228 if len == 0 {
1230 return Err(e);
1231 } else {
1232 return Ok(());
1233 }
1234 }
1235 }
1236 }
1237 }
1238
1239 Ok(())
1240 }
1241
1242 fn do_mkdir(
1243 &self,
1244 ctx: &Context,
1245 parent_node: &Arc<OverlayInode>,
1246 name: &str,
1247 mode: u32,
1248 umask: u32,
1249 ) -> Result<()> {
1250 if self.upper_layer.is_none() {
1251 return Err(Error::from_raw_os_error(libc::EROFS));
1252 }
1253
1254 if parent_node.whiteout.load(Ordering::Relaxed) {
1256 return Err(Error::from_raw_os_error(libc::ENOENT));
1257 }
1258
1259 let mut delete_whiteout = false;
1260 let mut set_opaque = false;
1261 if let Some(n) = self.lookup_node_ignore_enoent(ctx, parent_node.inode, name)? {
1262 if !n.whiteout.load(Ordering::Relaxed) {
1264 return Err(Error::from_raw_os_error(libc::EEXIST));
1265 }
1266
1267 if n.in_upper_layer() {
1268 delete_whiteout = true;
1269 }
1270
1271 if !n.upper_layer_only() {
1273 set_opaque = true;
1274 }
1275 }
1276
1277 let pnode = self.copy_node_up(ctx, Arc::clone(parent_node))?;
1279
1280 let mut new_node = None;
1281 let path = format!("{}/{}", pnode.path, name);
1282 pnode.handle_upper_inode_locked(&mut |parent_real_inode| -> Result<bool> {
1283 let parent_real_inode = match parent_real_inode {
1284 Some(inode) => inode,
1285 None => {
1286 error!("BUG: parent doesn't have upper inode after copied up");
1287 return Err(Error::from_raw_os_error(libc::EINVAL));
1288 }
1289 };
1290
1291 if delete_whiteout {
1292 let _ = parent_real_inode.layer.delete_whiteout(
1293 ctx,
1294 parent_real_inode.inode,
1295 utils::to_cstring(name)?.as_c_str(),
1296 );
1297 }
1298 let ino = self.alloc_inode(&path)?;
1300 let child_dir = parent_real_inode.mkdir(ctx, name, mode, umask)?;
1301 if set_opaque {
1303 parent_real_inode.layer.set_opaque(ctx, child_dir.inode)?;
1304 }
1305 let ovi = OverlayInode::new_from_real_inode(name, ino, path.clone(), child_dir);
1306
1307 new_node.replace(ovi);
1308 Ok(false)
1309 })?;
1310
1311 let arc_node = Arc::new(new_node.unwrap());
1313 self.insert_inode(arc_node.inode, arc_node.clone());
1314 pnode.insert_child(name, arc_node);
1315 Ok(())
1316 }
1317
1318 fn do_mknod(
1319 &self,
1320 ctx: &Context,
1321 parent_node: &Arc<OverlayInode>,
1322 name: &str,
1323 mode: u32,
1324 rdev: u32,
1325 umask: u32,
1326 ) -> Result<()> {
1327 if self.upper_layer.is_none() {
1328 return Err(Error::from_raw_os_error(libc::EROFS));
1329 }
1330
1331 if parent_node.whiteout.load(Ordering::Relaxed) {
1333 return Err(Error::from_raw_os_error(libc::ENOENT));
1334 }
1335
1336 match self.lookup_node_ignore_enoent(ctx, parent_node.inode, name)? {
1337 Some(n) => {
1338 if !n.whiteout.load(Ordering::Relaxed) {
1340 return Err(Error::from_raw_os_error(libc::EEXIST));
1341 }
1342
1343 let pnode = self.copy_node_up(ctx, Arc::clone(parent_node))?;
1345 pnode.handle_upper_inode_locked(&mut |parent_real_inode| -> Result<bool> {
1346 let parent_real_inode = match parent_real_inode {
1347 Some(inode) => inode,
1348 None => {
1349 error!("BUG: parent doesn't have upper inode after copied up");
1350 return Err(Error::from_raw_os_error(libc::EINVAL));
1351 }
1352 };
1353
1354 if n.in_upper_layer() {
1355 let _ = parent_real_inode.layer.delete_whiteout(
1356 ctx,
1357 parent_real_inode.inode,
1358 utils::to_cstring(name)?.as_c_str(),
1359 );
1360 }
1361
1362 let child_ri = parent_real_inode.mknod(ctx, name, mode, rdev, umask)?;
1363
1364 n.add_upper_inode(child_ri, true);
1366 Ok(false)
1367 })?;
1368 }
1369 None => {
1370 let pnode = self.copy_node_up(ctx, Arc::clone(parent_node))?;
1372 let mut new_node = None;
1373 let path = format!("{}/{}", pnode.path, name);
1374 pnode.handle_upper_inode_locked(&mut |parent_real_inode| -> Result<bool> {
1375 let parent_real_inode = match parent_real_inode {
1376 Some(inode) => inode,
1377 None => {
1378 error!("BUG: parent doesn't have upper inode after copied up");
1379 return Err(Error::from_raw_os_error(libc::EINVAL));
1380 }
1381 };
1382
1383 let ino = self.alloc_inode(&path)?;
1385 let child_ri = parent_real_inode.mknod(ctx, name, mode, rdev, umask)?;
1386 let ovi = OverlayInode::new_from_real_inode(name, ino, path.clone(), child_ri);
1387
1388 new_node.replace(ovi);
1389 Ok(false)
1390 })?;
1391
1392 let arc_node = Arc::new(new_node.unwrap());
1394 self.insert_inode(arc_node.inode, arc_node.clone());
1395 pnode.insert_child(name, arc_node);
1396 }
1397 }
1398
1399 Ok(())
1400 }
1401
1402 fn do_create(
1403 &self,
1404 ctx: &Context,
1405 parent_node: &Arc<OverlayInode>,
1406 name: &str,
1407 args: CreateIn,
1408 ) -> Result<Option<u64>> {
1409 let upper = self
1410 .upper_layer
1411 .as_ref()
1412 .cloned()
1413 .ok_or_else(|| Error::from_raw_os_error(libc::EROFS))?;
1414
1415 if parent_node.whiteout.load(Ordering::Relaxed) {
1417 return Err(Error::from_raw_os_error(libc::ENOENT));
1418 }
1419
1420 let mut handle = None;
1421 let mut real_ino = 0u64;
1422 let new_ovi = match self.lookup_node_ignore_enoent(ctx, parent_node.inode, name)? {
1423 Some(n) => {
1424 if !n.whiteout.load(Ordering::Relaxed) {
1426 return Err(Error::from_raw_os_error(libc::EEXIST));
1427 }
1428
1429 let pnode = self.copy_node_up(ctx, Arc::clone(parent_node))?;
1431 pnode.handle_upper_inode_locked(&mut |parent_real_inode| -> Result<bool> {
1432 let parent_real_inode = match parent_real_inode {
1433 Some(inode) => inode,
1434 None => {
1435 error!("BUG: parent doesn't have upper inode after copied up");
1436 return Err(Error::from_raw_os_error(libc::EINVAL));
1437 }
1438 };
1439
1440 if n.in_upper_layer() {
1441 let _ = parent_real_inode.layer.delete_whiteout(
1442 ctx,
1443 parent_real_inode.inode,
1444 utils::to_cstring(name)?.as_c_str(),
1445 );
1446 }
1447
1448 let (child_ri, hd) = parent_real_inode.create(ctx, name, args)?;
1449 real_ino = child_ri.inode;
1450 handle = hd;
1451
1452 n.add_upper_inode(child_ri, true);
1454 Ok(false)
1455 })?;
1456 n.clone()
1457 }
1458 None => {
1459 let pnode = self.copy_node_up(ctx, Arc::clone(parent_node))?;
1461 let mut new_node = None;
1462 let path = format!("{}/{}", pnode.path, name);
1463 pnode.handle_upper_inode_locked(&mut |parent_real_inode| -> Result<bool> {
1464 let parent_real_inode = match parent_real_inode {
1465 Some(inode) => inode,
1466 None => {
1467 error!("BUG: parent doesn't have upper inode after copied up");
1468 return Err(Error::from_raw_os_error(libc::EINVAL));
1469 }
1470 };
1471
1472 let (child_ri, hd) = parent_real_inode.create(ctx, name, args)?;
1473 real_ino = child_ri.inode;
1474 handle = hd;
1475 let ino = self.alloc_inode(&path)?;
1477 let ovi = OverlayInode::new_from_real_inode(name, ino, path.clone(), child_ri);
1478
1479 new_node.replace(ovi);
1480 Ok(false)
1481 })?;
1482
1483 let arc_node = Arc::new(new_node.unwrap());
1485 self.insert_inode(arc_node.inode, arc_node.clone());
1486 pnode.insert_child(name, arc_node.clone());
1487 arc_node
1488 }
1489 };
1490
1491 let final_handle = match handle {
1492 Some(hd) => {
1493 if self.no_open.load(Ordering::Relaxed) {
1494 None
1495 } else {
1496 let handle = self.next_handle.fetch_add(1, Ordering::Relaxed);
1497 let handle_data = HandleData {
1498 node: new_ovi,
1499 real_handle: Some(RealHandle {
1500 layer: upper.clone(),
1501 in_upper_layer: true,
1502 inode: real_ino,
1503 handle: AtomicU64::new(hd),
1504 }),
1505 };
1506 self.handles
1507 .lock()
1508 .unwrap()
1509 .insert(handle, Arc::new(handle_data));
1510 Some(handle)
1511 }
1512 }
1513 None => None,
1514 };
1515 Ok(final_handle)
1516 }
1517
1518 fn do_link(
1519 &self,
1520 ctx: &Context,
1521 src_node: &Arc<OverlayInode>,
1522 new_parent: &Arc<OverlayInode>,
1523 name: &str,
1524 ) -> Result<()> {
1525 if self.upper_layer.is_none() {
1526 return Err(Error::from_raw_os_error(libc::EROFS));
1527 }
1528
1529 if src_node.whiteout.load(Ordering::Relaxed) || new_parent.whiteout.load(Ordering::Relaxed)
1531 {
1532 return Err(Error::from_raw_os_error(libc::ENOENT));
1533 }
1534
1535 let st = src_node.stat64(ctx)?;
1536 if utils::is_dir(st) {
1537 return Err(Error::from_raw_os_error(libc::EPERM));
1539 }
1540
1541 let src_node = self.copy_node_up(ctx, Arc::clone(src_node))?;
1542 let new_parent = self.copy_node_up(ctx, Arc::clone(new_parent))?;
1543 let src_ino = src_node.first_layer_inode().2;
1544
1545 match self.lookup_node_ignore_enoent(ctx, new_parent.inode, name)? {
1546 Some(n) => {
1547 if !n.whiteout.load(Ordering::Relaxed) {
1549 return Err(Error::from_raw_os_error(libc::EEXIST));
1550 }
1551
1552 new_parent.handle_upper_inode_locked(&mut |parent_real_inode| -> Result<bool> {
1554 let parent_real_inode = match parent_real_inode {
1555 Some(inode) => inode,
1556 None => {
1557 error!("BUG: parent doesn't have upper inode after copied up");
1558 return Err(Error::from_raw_os_error(libc::EINVAL));
1559 }
1560 };
1561
1562 if n.in_upper_layer() {
1564 let _ = parent_real_inode.layer.delete_whiteout(
1565 ctx,
1566 parent_real_inode.inode,
1567 utils::to_cstring(name)?.as_c_str(),
1568 );
1569 }
1570
1571 let child_ri = parent_real_inode.link(ctx, src_ino, name)?;
1572
1573 n.add_upper_inode(child_ri, true);
1575 Ok(false)
1576 })?;
1577 }
1578 None => {
1579 let mut new_node = None;
1581 new_parent.handle_upper_inode_locked(&mut |parent_real_inode| -> Result<bool> {
1582 let parent_real_inode = match parent_real_inode {
1583 Some(inode) => inode,
1584 None => {
1585 error!("BUG: parent doesn't have upper inode after copied up");
1586 return Err(Error::from_raw_os_error(libc::EINVAL));
1587 }
1588 };
1589
1590 let path = format!("{}/{}", new_parent.path, name);
1592 let ino = self.alloc_inode(&path)?;
1593 let child_ri = parent_real_inode.link(ctx, src_ino, name)?;
1594 let ovi = OverlayInode::new_from_real_inode(name, ino, path, child_ri);
1595
1596 new_node.replace(ovi);
1597 Ok(false)
1598 })?;
1599
1600 let arc_node = Arc::new(new_node.unwrap());
1602 self.insert_inode(arc_node.inode, arc_node.clone());
1603 new_parent.insert_child(name, arc_node);
1604 }
1605 }
1606
1607 Ok(())
1608 }
1609
1610 fn do_symlink(
1611 &self,
1612 ctx: &Context,
1613 linkname: &str,
1614 parent_node: &Arc<OverlayInode>,
1615 name: &str,
1616 ) -> Result<()> {
1617 if self.upper_layer.is_none() {
1618 return Err(Error::from_raw_os_error(libc::EROFS));
1619 }
1620
1621 if parent_node.whiteout.load(Ordering::Relaxed) {
1623 return Err(Error::from_raw_os_error(libc::ENOENT));
1624 }
1625
1626 match self.lookup_node_ignore_enoent(ctx, parent_node.inode, name)? {
1627 Some(n) => {
1628 if !n.whiteout.load(Ordering::Relaxed) {
1630 return Err(Error::from_raw_os_error(libc::EEXIST));
1631 }
1632
1633 let pnode = self.copy_node_up(ctx, Arc::clone(parent_node))?;
1635 pnode.handle_upper_inode_locked(&mut |parent_real_inode| -> Result<bool> {
1636 let parent_real_inode = match parent_real_inode {
1637 Some(inode) => inode,
1638 None => {
1639 error!("BUG: parent doesn't have upper inode after copied up");
1640 return Err(Error::from_raw_os_error(libc::EINVAL));
1641 }
1642 };
1643
1644 if n.in_upper_layer() {
1645 let _ = parent_real_inode.layer.delete_whiteout(
1646 ctx,
1647 parent_real_inode.inode,
1648 utils::to_cstring(name)?.as_c_str(),
1649 );
1650 }
1651
1652 let child_ri = parent_real_inode.symlink(ctx, linkname, name)?;
1653
1654 n.add_upper_inode(child_ri, true);
1656 Ok(false)
1657 })?;
1658 }
1659 None => {
1660 let pnode = self.copy_node_up(ctx, Arc::clone(parent_node))?;
1662 let mut new_node = None;
1663 let path = format!("{}/{}", pnode.path, name);
1664 pnode.handle_upper_inode_locked(&mut |parent_real_inode| -> Result<bool> {
1665 let parent_real_inode = match parent_real_inode {
1666 Some(inode) => inode,
1667 None => {
1668 error!("BUG: parent doesn't have upper inode after copied up");
1669 return Err(Error::from_raw_os_error(libc::EINVAL));
1670 }
1671 };
1672
1673 let ino = self.alloc_inode(&path)?;
1675 let child_ri = parent_real_inode.symlink(ctx, linkname, name)?;
1676 let ovi = OverlayInode::new_from_real_inode(name, ino, path.clone(), child_ri);
1677
1678 new_node.replace(ovi);
1679 Ok(false)
1680 })?;
1681
1682 let arc_node = Arc::new(new_node.unwrap());
1684 self.insert_inode(arc_node.inode, arc_node.clone());
1685 pnode.insert_child(name, arc_node);
1686 }
1687 }
1688
1689 Ok(())
1690 }
1691
1692 fn copy_symlink_up(&self, ctx: &Context, node: Arc<OverlayInode>) -> Result<Arc<OverlayInode>> {
1693 if node.in_upper_layer() {
1694 return Ok(node);
1695 }
1696
1697 let parent_node = if let Some(ref n) = node.parent.lock().unwrap().upgrade() {
1698 Arc::clone(n)
1699 } else {
1700 return Err(Error::new(ErrorKind::Other, "no parent?"));
1701 };
1702
1703 let (self_layer, _, self_inode) = node.first_layer_inode();
1704
1705 if !parent_node.in_upper_layer() {
1706 parent_node.create_upper_dir(ctx, None)?;
1707 }
1708
1709 let path = self_layer.readlink(ctx, self_inode)?;
1711 let path =
1713 std::str::from_utf8(&path).map_err(|_| Error::from_raw_os_error(libc::EINVAL))?;
1714
1715 let mut new_upper_real = None;
1716 parent_node.handle_upper_inode_locked(&mut |parent_upper_inode| -> Result<bool> {
1717 let parent_real_inode =
1719 parent_upper_inode.ok_or_else(|| Error::from_raw_os_error(libc::EROFS))?;
1720 new_upper_real.replace(parent_real_inode.symlink(ctx, path, node.name.as_str())?);
1721 Ok(false)
1722 })?;
1723
1724 if let Some(real_inode) = new_upper_real {
1725 node.add_upper_inode(real_inode, true);
1727 }
1728
1729 Ok(Arc::clone(&node))
1730 }
1731
1732 fn copy_regfile_up(&self, ctx: &Context, node: Arc<OverlayInode>) -> Result<Arc<OverlayInode>> {
1735 if node.in_upper_layer() {
1736 return Ok(node);
1737 }
1738
1739 let parent_node = if let Some(ref n) = node.parent.lock().unwrap().upgrade() {
1740 Arc::clone(n)
1741 } else {
1742 return Err(Error::new(ErrorKind::Other, "no parent?"));
1743 };
1744
1745 let st = node.stat64(ctx)?;
1746 let (lower_layer, _, lower_inode) = node.first_layer_inode();
1747
1748 if !parent_node.in_upper_layer() {
1749 parent_node.create_upper_dir(ctx, None)?;
1750 }
1751
1752 let args = CreateIn {
1754 flags: libc::O_WRONLY as u32,
1755 mode: st.st_mode,
1756 umask: 0,
1757 fuse_flags: 0,
1758 };
1759
1760 let mut upper_handle = 0u64;
1761 let mut upper_real_inode = None;
1762 parent_node.handle_upper_inode_locked(&mut |parent_upper_inode| -> Result<bool> {
1763 let parent_real_inode = parent_upper_inode.ok_or_else(|| {
1765 error!("parent {} has no upper inode", parent_node.inode);
1766 Error::from_raw_os_error(libc::EINVAL)
1767 })?;
1768 let (inode, h) = parent_real_inode.create(ctx, node.name.as_str(), args)?;
1769 upper_handle = h.unwrap_or(0);
1770 upper_real_inode.replace(inode);
1771 Ok(false)
1772 })?;
1773
1774 let (h, _, _) = lower_layer.open(ctx, lower_inode, libc::O_RDONLY as u32, 0)?;
1775
1776 let lower_handle = h.unwrap_or(0);
1777
1778 let mut file = TempFile::new().unwrap().into_file();
1785 let mut offset: usize = 0;
1786 let size = 4 * 1024 * 1024;
1787 loop {
1788 let ret = lower_layer.read(
1789 ctx,
1790 lower_inode,
1791 lower_handle,
1792 &mut file,
1793 size,
1794 offset as u64,
1795 None,
1796 0,
1797 )?;
1798 if ret == 0 {
1799 break;
1800 }
1801
1802 offset += ret;
1803 }
1804 lower_layer.release(ctx, lower_inode, 0, lower_handle, true, true, None)?;
1806
1807 file.seek(SeekFrom::Start(0))?;
1808 offset = 0;
1809
1810 while let Some(ref ri) = upper_real_inode {
1811 let ret = ri.layer.write(
1812 ctx,
1813 ri.inode,
1814 upper_handle,
1815 &mut file,
1816 size,
1817 offset as u64,
1818 None,
1819 false,
1820 0,
1821 0,
1822 )?;
1823 if ret == 0 {
1824 break;
1825 }
1826
1827 offset += ret;
1828 }
1829
1830 drop(file);
1832
1833 if let Some(ri) = upper_real_inode {
1834 if let Err(e) = ri
1835 .layer
1836 .release(ctx, ri.inode, 0, upper_handle, true, true, None)
1837 {
1838 if e.raw_os_error() != Some(libc::ENOSYS) {
1840 return Err(e);
1841 }
1842 }
1843
1844 node.add_upper_inode(ri, true);
1846 }
1847
1848 Ok(Arc::clone(&node))
1849 }
1850
1851 fn copy_node_up(&self, ctx: &Context, node: Arc<OverlayInode>) -> Result<Arc<OverlayInode>> {
1852 if node.in_upper_layer() {
1853 return Ok(node);
1854 }
1855
1856 let st = node.stat64(ctx)?;
1857 if utils::is_dir(st) {
1859 node.create_upper_dir(ctx, None)?;
1860 return Ok(Arc::clone(&node));
1861 }
1862
1863 if st.st_mode & libc::S_IFMT == libc::S_IFLNK {
1865 return self.copy_symlink_up(ctx, Arc::clone(&node));
1866 }
1867
1868 self.copy_regfile_up(ctx, Arc::clone(&node))
1870 }
1871
1872 fn do_rm(&self, ctx: &Context, parent: u64, name: &CStr, dir: bool) -> Result<()> {
1873 if self.upper_layer.is_none() {
1874 return Err(Error::from_raw_os_error(libc::EROFS));
1875 }
1876
1877 let pnode = self.lookup_node(ctx, parent, "")?;
1879 if pnode.whiteout.load(Ordering::Relaxed) {
1880 return Err(Error::from_raw_os_error(libc::ENOENT));
1881 }
1882
1883 let sname = name.to_string_lossy().to_string();
1885 let node = self.lookup_node(ctx, parent, sname.as_str())?;
1886 if node.whiteout.load(Ordering::Relaxed) {
1887 return Err(Error::from_raw_os_error(libc::ENOENT));
1889 }
1890
1891 if dir {
1892 self.load_directory(ctx, &node)?;
1893 let (count, whiteouts) = node.count_entries_and_whiteout(ctx)?;
1894 trace!("entries: {}, whiteouts: {}\n", count, whiteouts);
1895 if count > 0 {
1896 return Err(Error::from_raw_os_error(libc::ENOTEMPTY));
1897 }
1898
1899 if whiteouts > 0 && node.in_upper_layer() {
1901 self.empty_node_directory(ctx, Arc::clone(&node))?;
1902 }
1903
1904 trace!("whiteouts deleted!\n");
1905 }
1906
1907 let mut need_whiteout = true;
1908 let pnode = self.copy_node_up(ctx, Arc::clone(&pnode))?;
1909
1910 if node.upper_layer_only() {
1911 need_whiteout = false;
1912 }
1913
1914 let mut path_removed = None;
1915 if node.in_upper_layer() {
1916 pnode.handle_upper_inode_locked(&mut |parent_upper_inode| -> Result<bool> {
1917 let parent_real_inode = parent_upper_inode.ok_or_else(|| {
1918 error!(
1919 "BUG: parent {} has no upper inode after copy up",
1920 pnode.inode
1921 );
1922 Error::from_raw_os_error(libc::EINVAL)
1923 })?;
1924
1925 if parent_real_inode.opaque {
1927 need_whiteout = false;
1928 }
1929 if dir {
1930 parent_real_inode
1931 .layer
1932 .rmdir(ctx, parent_real_inode.inode, name)?;
1933 } else {
1934 parent_real_inode
1935 .layer
1936 .unlink(ctx, parent_real_inode.inode, name)?;
1937 }
1938
1939 Ok(false)
1940 })?;
1941
1942 path_removed.replace(node.path.clone());
1943 }
1944
1945 trace!(
1946 "Remove inode {} from global hashmap and parent's children hashmap\n",
1947 node.inode
1948 );
1949
1950 node.lookups.fetch_sub(1, Ordering::Relaxed);
1952
1953 self.remove_inode(node.inode, path_removed);
1955 pnode.remove_child(node.name.as_str());
1956
1957 if need_whiteout {
1958 trace!("do_rm: creating whiteout\n");
1959 pnode.handle_upper_inode_locked(&mut |parent_upper_inode| -> Result<bool> {
1961 let parent_real_inode = parent_upper_inode.ok_or_else(|| {
1962 error!(
1963 "BUG: parent {} has no upper inode after copy up",
1964 pnode.inode
1965 );
1966 Error::from_raw_os_error(libc::EINVAL)
1967 })?;
1968
1969 let child_ri = parent_real_inode.create_whiteout(ctx, sname.as_str())?;
1970 let path = format!("{}/{}", pnode.path, sname);
1971 let ino = self.alloc_inode(&path)?;
1972 let ovi = Arc::new(OverlayInode::new_from_real_inode(
1973 sname.as_str(),
1974 ino,
1975 path.clone(),
1976 child_ri,
1977 ));
1978
1979 self.insert_inode(ino, ovi.clone());
1980 pnode.insert_child(sname.as_str(), ovi.clone());
1981 Ok(false)
1982 })?;
1983 }
1984
1985 Ok(())
1986 }
1987
1988 fn do_fsync(
1989 &self,
1990 ctx: &Context,
1991 inode: Inode,
1992 datasync: bool,
1993 handle: Handle,
1994 syncdir: bool,
1995 ) -> Result<()> {
1996 let data = self.get_data(ctx, Some(handle), inode, libc::O_RDONLY as u32)?;
1998
1999 match data.real_handle {
2000 None => Err(Error::from_raw_os_error(libc::ENOENT)),
2002 Some(ref rh) => {
2003 let real_handle = rh.handle.load(Ordering::Relaxed);
2004 if syncdir {
2006 rh.layer.fsyncdir(ctx, rh.inode, datasync, real_handle)
2007 } else {
2008 rh.layer.fsync(ctx, rh.inode, datasync, real_handle)
2009 }
2010 }
2011 }
2012 }
2013
2014 fn empty_node_directory(&self, ctx: &Context, node: Arc<OverlayInode>) -> Result<()> {
2016 let st = node.stat64(ctx)?;
2017 if !utils::is_dir(st) {
2018 return Err(Error::from_raw_os_error(libc::ENOTDIR));
2020 }
2021
2022 let (layer, in_upper, inode) = node.first_layer_inode();
2023 if !in_upper {
2024 return Ok(());
2025 }
2026
2027 let iter = node
2030 .childrens
2031 .lock()
2032 .unwrap()
2033 .iter()
2034 .map(|(_, v)| v.clone())
2035 .collect::<Vec<_>>();
2036
2037 for child in iter {
2038 if child.in_upper_layer() {
2040 if child.whiteout.load(Ordering::Relaxed) {
2041 layer.delete_whiteout(
2042 ctx,
2043 inode,
2044 utils::to_cstring(child.name.as_str())?.as_c_str(),
2045 )?
2046 } else {
2047 let s = child.stat64(ctx)?;
2048 let cname = utils::to_cstring(&child.name)?;
2049 if utils::is_dir(s) {
2050 let (count, whiteouts) = child.count_entries_and_whiteout(ctx)?;
2051 if count + whiteouts > 0 {
2052 self.empty_node_directory(ctx, Arc::clone(&child))?;
2053 }
2054
2055 layer.rmdir(ctx, inode, cname.as_c_str())?
2056 } else {
2057 layer.unlink(ctx, inode, cname.as_c_str())?;
2058 }
2059 }
2060
2061 self.remove_inode(child.inode, Some(child.path.clone()));
2063 node.remove_child(child.name.as_str());
2064 }
2065 }
2066
2067 Ok(())
2068 }
2069
2070 fn find_real_info_from_handle(
2071 &self,
2072 handle: Handle,
2073 ) -> Result<(Arc<BoxedLayer>, Inode, Handle)> {
2074 match self.handles.lock().unwrap().get(&handle) {
2075 Some(h) => match h.real_handle {
2076 Some(ref rhd) => Ok((
2077 rhd.layer.clone(),
2078 rhd.inode,
2079 rhd.handle.load(Ordering::Relaxed),
2080 )),
2081 None => Err(Error::from_raw_os_error(libc::ENOENT)),
2082 },
2083
2084 None => Err(Error::from_raw_os_error(libc::ENOENT)),
2085 }
2086 }
2087
2088 fn find_real_inode(&self, inode: Inode) -> Result<(Arc<BoxedLayer>, Inode)> {
2089 if let Some(n) = self.get_active_inode(inode) {
2090 let (first_layer, _, first_inode) = n.first_layer_inode();
2091 return Ok((first_layer, first_inode));
2092 }
2093
2094 Err(Error::from_raw_os_error(libc::ENOENT))
2095 }
2096
2097 fn get_data(
2098 &self,
2099 ctx: &Context,
2100 handle: Option<Handle>,
2101 inode: Inode,
2102 flags: u32,
2103 ) -> Result<Arc<HandleData>> {
2104 let no_open = self.no_open.load(Ordering::Relaxed);
2105 if !no_open {
2106 if let Some(h) = handle {
2107 if let Some(v) = self.handles.lock().unwrap().get(&h) {
2108 if v.node.inode == inode {
2109 return Ok(Arc::clone(v));
2110 }
2111 }
2112 }
2113 } else {
2114 let readonly: bool = flags
2115 & (libc::O_APPEND | libc::O_CREAT | libc::O_TRUNC | libc::O_RDWR | libc::O_WRONLY)
2116 as u32
2117 == 0;
2118
2119 let node = self.lookup_node(ctx, inode, "")?;
2121
2122 if node.whiteout.load(Ordering::Relaxed) {
2124 return Err(Error::from_raw_os_error(libc::ENOENT));
2125 }
2126
2127 if !readonly {
2128 self.upper_layer
2130 .as_ref()
2131 .cloned()
2132 .ok_or_else(|| Error::from_raw_os_error(libc::EROFS))?;
2133 self.copy_node_up(ctx, Arc::clone(&node))?;
2135 }
2136
2137 let (layer, in_upper_layer, inode) = node.first_layer_inode();
2138 let handle_data = HandleData {
2139 node: Arc::clone(&node),
2140 real_handle: Some(RealHandle {
2141 layer,
2142 in_upper_layer,
2143 inode,
2144 handle: AtomicU64::new(0),
2145 }),
2146 };
2147 return Ok(Arc::new(handle_data));
2148 }
2149
2150 Err(Error::from_raw_os_error(libc::ENOENT))
2151 }
2152}
2153
2154impl ZeroCopyReader for File {
2155 fn read_to(
2158 &mut self,
2159 f: &mut dyn FileReadWriteVolatile,
2160 count: usize,
2161 off: u64,
2162 ) -> Result<usize> {
2163 let mut buf = vec![0_u8; count];
2164 let slice = unsafe { FileVolatileSlice::from_raw_ptr(buf.as_mut_ptr(), count) };
2165
2166 let ret = self.read_volatile(slice)?;
2168 if ret > 0 {
2169 let slice = unsafe { FileVolatileSlice::from_raw_ptr(buf.as_mut_ptr(), ret) };
2170 f.write_at_volatile(slice, off)
2172 } else {
2173 Ok(0)
2174 }
2175 }
2176}
2177
2178impl ZeroCopyWriter for File {
2179 fn write_from(
2182 &mut self,
2183 f: &mut dyn FileReadWriteVolatile,
2184 count: usize,
2185 off: u64,
2186 ) -> Result<usize> {
2187 let mut buf = vec![0_u8; count];
2188 let slice = unsafe { FileVolatileSlice::from_raw_ptr(buf.as_mut_ptr(), count) };
2189 let ret = f.read_at_volatile(slice, off)?;
2191
2192 if ret > 0 {
2193 let slice = unsafe { FileVolatileSlice::from_raw_ptr(buf.as_mut_ptr(), ret) };
2194 self.write_volatile(slice)
2196 } else {
2197 Ok(0)
2198 }
2199 }
2200
2201 fn available_bytes(&self) -> usize {
2202 usize::MAX
2204 }
2205}
2206
2207#[cfg(not(feature = "async-io"))]
2208impl BackendFileSystem for OverlayFs {
2209 fn mount(&self) -> Result<(Entry, u64)> {
2212 let ctx = Context::default();
2213 let entry = self.do_lookup(&ctx, self.root_inode(), "")?;
2214 Ok((entry, VFS_MAX_INO))
2215 }
2216
2217 fn as_any(&self) -> &dyn std::any::Any {
2221 self
2222 }
2223}