fuse_backend_rs/overlayfs/
mod.rs

1// Copyright (C) 2023 Ant Group. All rights reserved.
2// SPDX-License-Identifier: Apache-2.0
3
4#![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
40//type BoxedFileSystem = Box<dyn FileSystem<Inode = Inode, Handle = Handle> + Send + Sync>;
41pub type BoxedLayer = Box<dyn Layer<Inode = Inode, Handle = Handle> + Send + Sync>;
42
43// RealInode represents one inode object in specific layer.
44// Also, each RealInode maps to one Entry, which should be 'forgotten' after drop.
45// Important note: do not impl Clone trait for it or refcount will be messed up.
46pub(crate) struct RealInode {
47    pub layer: Arc<BoxedLayer>,
48    pub in_upper_layer: bool,
49    pub inode: u64,
50    // File is whiteouted, we need to hide it.
51    pub whiteout: bool,
52    // Directory is opaque, we need to hide all entries inside it.
53    pub opaque: bool,
54    pub stat: Option<stat64>,
55}
56
57// OverlayInode must be protected by lock, it can be operated by multiple threads.
58#[derive(Default)]
59pub(crate) struct OverlayInode {
60    // Inode hash table, map from 'name' to 'OverlayInode'.
61    pub childrens: Mutex<HashMap<String, Arc<OverlayInode>>>,
62    pub parent: Mutex<Weak<OverlayInode>>,
63    // Backend inodes from all layers.
64    pub real_inodes: Mutex<Vec<RealInode>>,
65    // Inode number.
66    pub inode: u64,
67    pub path: String,
68    pub name: String,
69    pub lookups: AtomicU64,
70    // Node is whiteout-ed.
71    pub whiteout: AtomicBool,
72    // Directory is loaded.
73    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    // All inodes in FS.
88    inodes: RwLock<InodeStore>,
89    // Open file handles.
90    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    //offset: libc::off_t,
109    real_handle: Option<RealHandle>,
110}
111
112// RealInode is a wrapper of one inode in specific layer.
113// All layer operations returning Entry should be wrapped in RealInode implementation
114// so that we can increase the refcount(lookup count) of each inode and decrease it after Drop.
115// Important: do not impl 'Copy' trait for it or refcount will be messed up.
116impl 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    // Do real lookup action in specific layer, this call will increase Entry refcount which must be released later.
171    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        // Real inode must have a layer.
174        let layer = self.layer.as_ref();
175        match layer.lookup(ctx, self.inode, cname.as_c_str()) {
176            Ok(v) => {
177                // Negative entry also indicates missing entry.
178                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    // Find child inode in same layer under this directory(Self).
196    // Return None if not found.
197    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        // Find child Entry with <name> under directory with inode <self.inode>.
205        match self.lookup_child_ignore_enoent(ctx, name)? {
206            Some(v) => {
207                // The Entry must be forgotten in each layer, which will be done automatically by Drop operation.
208                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    // Read directory entries from specific RealInode, error out if it's not directory.
228    fn readdir(&self, ctx: &Context) -> Result<HashMap<String, RealInode>> {
229        // Deleted inode should not be read.
230        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        // Must be directory.
240        if !utils::is_dir(stat) {
241            return Err(Error::from_raw_os_error(libc::ENOTDIR));
242        }
243
244        // Open the directory and load each entry.
245        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            // opendir may not be supported if no_opendir is set, so we can ignore this error.
249            Err(e) => {
250                match e.raw_os_error() {
251                    Some(raw_error) => {
252                        if raw_error == libc::ENOSYS {
253                            // We can still call readdir with inode if opendir is not supported in this layer.
254                            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        // Non-zero handle indicates successful 'open', we should 'release' it.
297        if handle > 0 {
298            if let Err(e) = self
299                .layer
300                .releasedir(ctx, self.inode, libc::O_RDONLY as u32, handle)
301            {
302                // ignore ENOSYS
303                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        // Lookup all child and construct "RealInode"s.
317        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        // Wrap whiteout to RealInode.
338        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        // update node's first_layer
359        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    // Create a symlink in self directory.
451    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        // Release refcount of inode in layer.
477        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    // Allocate new OverlayInode based on one RealInode,
491    // inode number is always 0 since only OverlayFs has global unique inode allocator.
492    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                // This is whiteout, no need to check lower layers.
529                if whiteout {
530                    break;
531                }
532
533                // A non-directory file shadows all lower layers as default.
534                if !utils::is_dir(stat) {
535                    break;
536                }
537
538                // Opaque directory shadows all lower layers.
539                if opaque {
540                    break;
541                }
542            } else {
543                // This is whiteout, no need to record this, break directly.
544                if ri.whiteout {
545                    break;
546                }
547
548                // Only directory have multiple real inodes, so if this is non-first real-inode
549                // and it's not directory, it should indicates some invalid layout. @weizhang555
550                if !utils::is_dir(stat) {
551                    error!("invalid layout: non-directory has multiple real inodes");
552                    break;
553                }
554
555                // Valid directory.
556                new.real_inodes.lock().unwrap().push(ri);
557                // Opaque directory shadows all lower layers.
558                if opaque {
559                    break;
560                }
561            }
562        }
563        Ok(new)
564    }
565
566    pub fn stat64(&self, ctx: &Context) -> Result<stat64> {
567        // try layers in order or just take stat from first layer?
568        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        // not in any layer
575        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        // must be directory
585        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    // Self is directory, fill all childrens.
612    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        // read out directories from each layer
620        let mut counter = 1;
621        let layers_count = self.real_inodes.lock().unwrap().len();
622        // Scan from upper layer to lower layer.
623        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                // Node is deleted from some upper layer, skip it.
634                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                // not directory
646                break;
647            }
648
649            // Read all entries from one layer.
650            let entries = ri.readdir(ctx)?;
651
652            // Merge entries from one layer to all_layer_inodes.
653            for (name, inode) in entries {
654                match all_layer_inodes.get_mut(&name) {
655                    Some(v) => {
656                        // Append additional RealInode to the end of vector.
657                        v.push(inode)
658                    }
659                    None => {
660                        all_layer_inodes.insert(name, vec![inode]);
661                    }
662                };
663            }
664
665            // if opaque, stop here
666            if ri.opaque {
667                debug!("directory {} is opaque", self.path.as_str());
668                break;
669            }
670        }
671
672        // Construct OverlayInode for each entry.
673        let mut childrens = vec![];
674        for (name, real_inodes) in all_layer_inodes {
675            // Inode numbers are not allocated yet.
676            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    // Create a new directory in upper layer for node, node must be directory.
685    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 node already has upper layer, we can just return here.
696        if self.in_upper_layer() {
697            return Ok(());
698        }
699
700        // not in upper layer, check parent.
701        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)?; // recursive call
709        }
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                    // create directory here
721                    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            // Push the new real inode to the front of vector.
736            self.add_upper_inode(ri, false);
737        }
738
739        Ok(())
740    }
741
742    // Add new upper RealInode to OverlayInode, clear all lower RealInodes if 'clear_lowers' is true.
743    fn add_upper_inode(self: &Arc<Self>, ri: RealInode, clear_lowers: bool) {
744        let mut inodes = self.real_inodes.lock().unwrap();
745        // Update self according to upper attribute.
746        self.whiteout.store(ri.whiteout, Ordering::Relaxed);
747
748        // Push the new real inode to the front of vector.
749        let mut new = vec![ri];
750        // Drain lower RealInodes.
751        let lowers = inodes.drain(..).collect::<Vec<RealInode>>();
752        if !clear_lowers {
753            // If not clear lowers, append them to the end of vector.
754            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        // load root inode
849        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        // Update upper inode
882        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        // Update lower inodes.
889        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        // insert root inode into hash
903        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        // Root node must exist.
913        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    // Get inode which is active or deleted.
925    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    // Return the inode only if it's permanently deleted from both self.inodes and self.deleted_inodes.
934    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    // Lookup child OverlayInode with <name> under <parent> directory.
942    // If name is empty, return parent itself.
943    // Parent dir will be loaded, but returned OverlayInode won't.
944    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        // Parent inode is expected to be loaded before this function is called.
950        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        // Parent is whiteout-ed, return ENOENT.
956        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            // Parent is expected to be directory, load it first.
963            self.load_directory(ctx, &pnode)?;
964        }
965
966        // Current file or dir.
967        if name.eq(".")
968            // Root directory has no parent.
969            || (parent == FUSE_ROOT_ID && name.eq(".."))
970            // Special convention: empty name indicates current dir.
971            || name.is_empty()
972        {
973            return Ok(Arc::clone(&pnode));
974        }
975
976        match pnode.child(name) {
977            // Child is found.
978            Some(v) => Ok(v),
979            None => Err(Error::from_raw_os_error(libc::ENOENT)),
980        }
981    }
982
983    // As a debug function, print all inode numbers in hash table.
984    #[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    // Load entries of the directory from all layers, if node is not directory, return directly.
1009    fn load_directory(&self, ctx: &Context, node: &Arc<OverlayInode>) -> Result<()> {
1010        if node.loaded.load(Ordering::Relaxed) {
1011            return Ok(());
1012        }
1013
1014        // We got all childrens without inode.
1015        let childrens = node.scan_childrens(ctx)?;
1016
1017        // =============== Start Lock Area ===================
1018        // Lock OverlayFs inodes.
1019        let mut inode_store = self.inodes.write().unwrap();
1020        // Lock the OverlayInode and its childrens.
1021        let mut node_children = node.childrens.lock().unwrap();
1022
1023        // Check again in case another 'load_directory' function call gets locks and want to do duplicated work.
1024        if node.loaded.load(Ordering::Relaxed) {
1025            return Ok(());
1026        }
1027
1028        // Now we have two locks' protection, Fs inodes lock and OverlayInode's childrens lock.
1029        for mut child in childrens.into_iter() {
1030            // Allocate inode for each child.
1031            let ino = inode_store.alloc_inode(&child.path)?;
1032
1033            let name = child.name.clone();
1034            child.inode = ino;
1035            // Create bi-directional link between parent and child.
1036            child.parent = Mutex::new(Arc::downgrade(node));
1037
1038            let arc_child = Arc::new(child);
1039            node_children.insert(name, arc_child.clone());
1040            // Record overlay inode in whole OverlayFs.
1041            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        // FIXME: need atomic protection around lookups' load & store. @weizhang555
1063        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        // TODO: use compare_exchange.
1073        //v.lookups.compare_exchange(old, new, Ordering::Acquire, Ordering::Relaxed);
1074
1075        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                // remove it from hashmap
1082                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        // FIXME: can forget happen between found and increase reference counter?
1101        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        // lookup the directory
1148        let ovl_inode = match self.handles.lock().unwrap().get(&handle) {
1149            Some(dir) => dir.node.clone(),
1150            None => {
1151                // Try to get data with inode.
1152                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        //add myself as "."
1165        childrens.push((".".to_string(), ovl_inode.clone()));
1166
1167        //add parent
1168        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            // skip whiteout node
1176            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                // make struct DireEntry and Entry
1190                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                            // no more space, stop here
1217                            return Ok(());
1218                        }
1219                    }
1220
1221                    Err(e) => {
1222                        // when the buffer is still empty, return error, otherwise return the entry already added
1223                        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        // Parent node was deleted.
1249        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            // Node with same name exists, let's check if it's whiteout.
1257            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            // Set opaque if child dir has lower layers.
1266            if !n.upper_layer_only() {
1267                set_opaque = true;
1268            }
1269        }
1270
1271        // Copy parent node up if necessary.
1272        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            // Allocate inode number.
1293            let ino = self.alloc_inode(&path)?;
1294            let child_dir = parent_real_inode.mkdir(ctx, name, mode, umask)?;
1295            // Set opaque if child dir has lower layers.
1296            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        // new_node is always 'Some'
1306        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        // Parent node was deleted.
1326        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                // Node with same name exists, let's check if it's whiteout.
1333                if !n.whiteout.load(Ordering::Relaxed) {
1334                    return Err(Error::from_raw_os_error(libc::EEXIST));
1335                }
1336
1337                // Copy parent node up if necessary.
1338                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                    // Replace existing real inodes with new one.
1359                    n.add_upper_inode(child_ri, true);
1360                    Ok(false)
1361                })?;
1362            }
1363            None => {
1364                // Copy parent node up if necessary.
1365                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                    // Allocate inode number.
1378                    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                // new_node is always 'Some'
1387                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        // Parent node was deleted.
1410        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                // Node with same name exists, let's check if it's whiteout.
1419                if !n.whiteout.load(Ordering::Relaxed) {
1420                    return Err(Error::from_raw_os_error(libc::EEXIST));
1421                }
1422
1423                // Copy parent node up if necessary.
1424                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                    // Replace existing real inodes with new one.
1447                    n.add_upper_inode(child_ri, true);
1448                    Ok(false)
1449                })?;
1450                n.clone()
1451            }
1452            None => {
1453                // Copy parent node up if necessary.
1454                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                    // Allocate inode number.
1470                    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                // new_node is always 'Some'
1478                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        // Node is whiteout.
1524        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            // Directory can't be hardlinked.
1532            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                // Node with same name exists, let's check if it's whiteout.
1542                if !n.whiteout.load(Ordering::Relaxed) {
1543                    return Err(Error::from_raw_os_error(libc::EEXIST));
1544                }
1545
1546                // Node is definitely a whiteout now.
1547                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                    // Whiteout file exists in upper level, let's delete it.
1557                    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                    // Replace existing real inodes with new one.
1568                    n.add_upper_inode(child_ri, true);
1569                    Ok(false)
1570                })?;
1571            }
1572            None => {
1573                // Copy parent node up if necessary.
1574                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                    // Allocate inode number.
1585                    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                // new_node is always 'Some'
1595                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        // parent was deleted.
1616        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                // Node with same name exists, let's check if it's whiteout.
1623                if !n.whiteout.load(Ordering::Relaxed) {
1624                    return Err(Error::from_raw_os_error(libc::EEXIST));
1625                }
1626
1627                // Copy parent node up if necessary.
1628                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                    // Replace existing real inodes with new one.
1649                    n.add_upper_inode(child_ri, true);
1650                    Ok(false)
1651                })?;
1652            }
1653            None => {
1654                // Copy parent node up if necessary.
1655                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                    // Allocate inode number.
1668                    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                // new_node is always 'Some'
1677                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        // Read the linkname from lower layer.
1704        let path = self_layer.readlink(ctx, self_inode)?;
1705        // Convert path to &str.
1706        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            // We already create upper dir for parent_node above.
1712            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            // update upper_inode and first_inode()
1720            node.add_upper_inode(real_inode, true);
1721        }
1722
1723        Ok(Arc::clone(&node))
1724    }
1725
1726    // Copy regular file from lower layer to upper layer.
1727    // Caller must ensure node doesn't have upper layer.
1728    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        // create the file in upper layer using information from lower layer
1747        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            // We already create upper dir for parent_node.
1758            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        // need to use work directory and then rename file to
1773        // final destination for atomic reasons.. not deal with it for now,
1774        // use stupid copy at present.
1775        // FIXME: this need a lot of work here, ntimes, xattr, etc.
1776
1777        // Copy from lower real inode to upper real inode.
1778        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        // close handles
1799        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 will remove file automatically.
1825        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                // Ignore ENOSYS.
1833                if e.raw_os_error() != Some(libc::ENOSYS) {
1834                    return Err(e);
1835                }
1836            }
1837
1838            // update upper_inode and first_inode()
1839            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        // directory
1852        if utils::is_dir(st) {
1853            node.create_upper_dir(ctx, None)?;
1854            return Ok(Arc::clone(&node));
1855        }
1856
1857        // For symlink.
1858        if st.st_mode & libc::S_IFMT == libc::S_IFLNK {
1859            return self.copy_symlink_up(ctx, Arc::clone(&node));
1860        }
1861
1862        // For regular file.
1863        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        // Find parent Overlay Inode.
1872        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        // Find the Overlay Inode for child with <name>.
1878        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            // already deleted.
1882            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            // Delete all whiteouts.
1894            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                // Parent is opaque, it shadows everything in lower layers so no need to create extra whiteouts.
1920                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        // lookups decrease by 1.
1945        node.lookups.fetch_sub(1, Ordering::Relaxed);
1946
1947        // remove it from hashmap
1948        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 is copied up, so it has upper layer.
1954            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        // Use O_RDONLY flags which indicates no copy up.
1991        let data = self.get_data(ctx, Some(handle), inode, libc::O_RDONLY as u32)?;
1992
1993        match data.real_handle {
1994            // FIXME: need to test if inode matches corresponding handle?
1995            None => Err(Error::from_raw_os_error(libc::ENOENT)),
1996            Some(ref rh) => {
1997                let real_handle = rh.handle.load(Ordering::Relaxed);
1998                // TODO: check if it's in upper layer? @weizhang555
1999                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    // Delete everything in the directory only on upper layer, ignore lower layers.
2009    fn empty_node_directory(&self, ctx: &Context, node: Arc<OverlayInode>) -> Result<()> {
2010        let st = node.stat64(ctx)?;
2011        if !utils::is_dir(st) {
2012            // This function can only be called on directories.
2013            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        // Copy node.childrens Hashmap to Vector, the Vector is also used as temp storage,
2022        // Without this, Rust won't allow us to remove them from node.childrens.
2023        let iter = node
2024            .childrens
2025            .lock()
2026            .unwrap()
2027            .values()
2028            .cloned()
2029            .collect::<Vec<_>>();
2030
2031        for child in iter {
2032            // We only care about upper layer, ignore lower layers.
2033            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                // delete the child
2056                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            // lookup node
2114            let node = self.lookup_node(ctx, inode, "")?;
2115
2116            // whiteout node
2117            if node.whiteout.load(Ordering::Relaxed) {
2118                return Err(Error::from_raw_os_error(libc::ENOENT));
2119            }
2120
2121            if !readonly {
2122                // Check if upper layer exists, return EROFS is not exists.
2123                self.upper_layer
2124                    .as_ref()
2125                    .cloned()
2126                    .ok_or_else(|| Error::from_raw_os_error(libc::EROFS))?;
2127                // copy up to upper layer
2128                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    // Copies at most count bytes from self directly into f at offset off
2150    // without storing it in any intermediate buffers.
2151    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        // Read from self to slice.
2161        let ret = self.read_volatile(slice)?;
2162        if ret > 0 {
2163            let slice = unsafe { FileVolatileSlice::from_raw_ptr(buf.as_mut_ptr(), ret) };
2164            // Write from slice to f at offset off.
2165            f.write_at_volatile(slice, off)
2166        } else {
2167            Ok(0)
2168        }
2169    }
2170}
2171
2172impl ZeroCopyWriter for File {
2173    // Copies at most count bytes from f at offset off directly into self
2174    // without storing it in any intermediate buffers.
2175    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        // Read from f at offset off to slice.
2184        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            // Write from slice to self.
2189            self.write_volatile(slice)
2190        } else {
2191            Ok(0)
2192        }
2193    }
2194
2195    fn available_bytes(&self) -> usize {
2196        // Max usize
2197        usize::MAX
2198    }
2199}
2200
2201#[cfg(not(feature = "async-io"))]
2202impl BackendFileSystem for OverlayFs {
2203    /// mount returns the backend file system root inode entry and
2204    /// the largest inode number it has.
2205    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    /// Provides a reference to the Any trait. This is useful to let
2212    /// the caller have access to the underlying type behind the
2213    /// trait.
2214    fn as_any(&self) -> &dyn std::any::Any {
2215        self
2216    }
2217}