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, _)) => match handle {
248                Some(h) => h,
249                _ => 0,
250            },
251            // opendir may not be supported if no_opendir is set, so we can ignore this error.
252            Err(e) => {
253                match e.raw_os_error() {
254                    Some(raw_error) => {
255                        if raw_error == libc::ENOSYS {
256                            // We can still call readdir with inode if opendir is not supported in this layer.
257                            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        // Non-zero handle indicates successful 'open', we should 'release' it.
300        if handle > 0 {
301            if let Err(e) = self
302                .layer
303                .releasedir(ctx, self.inode, libc::O_RDONLY as u32, handle)
304            {
305                // ignore ENOSYS
306                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        // Lookup all child and construct "RealInode"s.
320        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        // Wrap whiteout to RealInode.
341        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        // update node's first_layer
362        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    // Create a symlink in self directory.
454    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        // Release refcount of inode in layer.
480        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    // Allocate new OverlayInode based on one RealInode,
494    // inode number is always 0 since only OverlayFs has global unique inode allocator.
495    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                // This is whiteout, no need to check lower layers.
532                if whiteout {
533                    break;
534                }
535
536                // A non-directory file shadows all lower layers as default.
537                if !utils::is_dir(stat) {
538                    break;
539                }
540
541                // Opaque directory shadows all lower layers.
542                if opaque {
543                    break;
544                }
545            } else {
546                // This is whiteout, no need to record this, break directly.
547                if ri.whiteout {
548                    break;
549                }
550
551                // Only directory have multiple real inodes, so if this is non-first real-inode
552                // and it's not directory, it should indicates some invalid layout. @weizhang555
553                if !utils::is_dir(stat) {
554                    error!("invalid layout: non-directory has multiple real inodes");
555                    break;
556                }
557
558                // Valid directory.
559                new.real_inodes.lock().unwrap().push(ri);
560                // Opaque directory shadows all lower layers.
561                if opaque {
562                    break;
563                }
564            }
565        }
566        Ok(new)
567    }
568
569    pub fn stat64(&self, ctx: &Context) -> Result<stat64> {
570        // try layers in order or just take stat from first layer?
571        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        // not in any layer
578        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        // must be directory
588        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    // Self is directory, fill all childrens.
615    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        // read out directories from each layer
623        let mut counter = 1;
624        let layers_count = self.real_inodes.lock().unwrap().len();
625        // Scan from upper layer to lower layer.
626        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                // Node is deleted from some upper layer, skip it.
637                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                // not directory
649                break;
650            }
651
652            // Read all entries from one layer.
653            let entries = ri.readdir(ctx)?;
654
655            // Merge entries from one layer to all_layer_inodes.
656            for (name, inode) in entries {
657                match all_layer_inodes.get_mut(&name) {
658                    Some(v) => {
659                        // Append additional RealInode to the end of vector.
660                        v.push(inode)
661                    }
662                    None => {
663                        all_layer_inodes.insert(name, vec![inode]);
664                    }
665                };
666            }
667
668            // if opaque, stop here
669            if ri.opaque {
670                debug!("directory {} is opaque", self.path.as_str());
671                break;
672            }
673        }
674
675        // Construct OverlayInode for each entry.
676        let mut childrens = vec![];
677        for (name, real_inodes) in all_layer_inodes {
678            // Inode numbers are not allocated yet.
679            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    // Create a new directory in upper layer for node, node must be directory.
688    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 node already has upper layer, we can just return here.
699        if self.in_upper_layer() {
700            return Ok(());
701        }
702
703        // not in upper layer, check parent.
704        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)?; // recursive call
712        }
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                    // create directory here
724                    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            // Push the new real inode to the front of vector.
739            self.add_upper_inode(ri, false);
740        }
741
742        Ok(())
743    }
744
745    // Add new upper RealInode to OverlayInode, clear all lower RealInodes if 'clear_lowers' is true.
746    fn add_upper_inode(self: &Arc<Self>, ri: RealInode, clear_lowers: bool) {
747        let mut inodes = self.real_inodes.lock().unwrap();
748        // Update self according to upper attribute.
749        self.whiteout.store(ri.whiteout, Ordering::Relaxed);
750
751        // Push the new real inode to the front of vector.
752        let mut new = vec![ri];
753        // Drain lower RealInodes.
754        let lowers = inodes.drain(..).collect::<Vec<RealInode>>();
755        if !clear_lowers {
756            // If not clear lowers, append them to the end of vector.
757            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        // load root inode
855        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        // Update upper inode
888        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        // Update lower inodes.
895        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        // insert root inode into hash
909        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        // Root node must exist.
919        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    // Get inode which is active or deleted.
931    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    // Return the inode only if it's permanently deleted from both self.inodes and self.deleted_inodes.
940    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    // Lookup child OverlayInode with <name> under <parent> directory.
948    // If name is empty, return parent itself.
949    // Parent dir will be loaded, but returned OverlayInode won't.
950    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        // Parent inode is expected to be loaded before this function is called.
956        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        // Parent is whiteout-ed, return ENOENT.
962        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            // Parent is expected to be directory, load it first.
969            self.load_directory(ctx, &pnode)?;
970        }
971
972        // Current file or dir.
973        if name.eq(".")  
974            // Root directory has no parent.
975            || (parent == FUSE_ROOT_ID && name.eq("..")) 
976            // Special convention: empty name indicates current dir.
977            || name.is_empty()
978        {
979            return Ok(Arc::clone(&pnode));
980        }
981
982        match pnode.child(name) {
983            // Child is found.
984            Some(v) => Ok(v),
985            None => Err(Error::from_raw_os_error(libc::ENOENT)),
986        }
987    }
988
989    // As a debug function, print all inode numbers in hash table.
990    #[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    // Load entries of the directory from all layers, if node is not directory, return directly.
1015    fn load_directory(&self, ctx: &Context, node: &Arc<OverlayInode>) -> Result<()> {
1016        if node.loaded.load(Ordering::Relaxed) {
1017            return Ok(());
1018        }
1019
1020        // We got all childrens without inode.
1021        let childrens = node.scan_childrens(ctx)?;
1022
1023        // =============== Start Lock Area ===================
1024        // Lock OverlayFs inodes.
1025        let mut inode_store = self.inodes.write().unwrap();
1026        // Lock the OverlayInode and its childrens.
1027        let mut node_children = node.childrens.lock().unwrap();
1028
1029        // Check again in case another 'load_directory' function call gets locks and want to do duplicated work.
1030        if node.loaded.load(Ordering::Relaxed) {
1031            return Ok(());
1032        }
1033
1034        // Now we have two locks' protection, Fs inodes lock and OverlayInode's childrens lock.
1035        for mut child in childrens.into_iter() {
1036            // Allocate inode for each child.
1037            let ino = inode_store.alloc_inode(&child.path)?;
1038
1039            let name = child.name.clone();
1040            child.inode = ino;
1041            // Create bi-directional link between parent and child.
1042            child.parent = Mutex::new(Arc::downgrade(node));
1043
1044            let arc_child = Arc::new(child);
1045            node_children.insert(name, arc_child.clone());
1046            // Record overlay inode in whole OverlayFs.
1047            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        // FIXME: need atomic protection around lookups' load & store. @weizhang555
1069        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        // TODO: use compare_exchange.
1079        //v.lookups.compare_exchange(old, new, Ordering::Acquire, Ordering::Relaxed);
1080
1081        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                // remove it from hashmap
1088                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        // FIXME: can forget happen between found and increase reference counter?
1107        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        // lookup the directory
1154        let ovl_inode = match self.handles.lock().unwrap().get(&handle) {
1155            Some(dir) => dir.node.clone(),
1156            None => {
1157                // Try to get data with inode.
1158                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        //add myself as "."
1171        childrens.push((".".to_string(), ovl_inode.clone()));
1172
1173        //add parent
1174        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            // skip whiteout node
1182            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                // make struct DireEntry and Entry
1196                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                            // no more space, stop here
1223                            return Ok(());
1224                        }
1225                    }
1226
1227                    Err(e) => {
1228                        // when the buffer is still empty, return error, otherwise return the entry already added
1229                        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        // Parent node was deleted.
1255        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            // Node with same name exists, let's check if it's whiteout.
1263            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            // Set opaque if child dir has lower layers.
1272            if !n.upper_layer_only() {
1273                set_opaque = true;
1274            }
1275        }
1276
1277        // Copy parent node up if necessary.
1278        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            // Allocate inode number.
1299            let ino = self.alloc_inode(&path)?;
1300            let child_dir = parent_real_inode.mkdir(ctx, name, mode, umask)?;
1301            // Set opaque if child dir has lower layers.
1302            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        // new_node is always 'Some'
1312        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        // Parent node was deleted.
1332        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                // Node with same name exists, let's check if it's whiteout.
1339                if !n.whiteout.load(Ordering::Relaxed) {
1340                    return Err(Error::from_raw_os_error(libc::EEXIST));
1341                }
1342
1343                // Copy parent node up if necessary.
1344                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                    // Replace existing real inodes with new one.
1365                    n.add_upper_inode(child_ri, true);
1366                    Ok(false)
1367                })?;
1368            }
1369            None => {
1370                // Copy parent node up if necessary.
1371                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                    // Allocate inode number.
1384                    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                // new_node is always 'Some'
1393                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        // Parent node was deleted.
1416        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                // Node with same name exists, let's check if it's whiteout.
1425                if !n.whiteout.load(Ordering::Relaxed) {
1426                    return Err(Error::from_raw_os_error(libc::EEXIST));
1427                }
1428
1429                // Copy parent node up if necessary.
1430                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                    // Replace existing real inodes with new one.
1453                    n.add_upper_inode(child_ri, true);
1454                    Ok(false)
1455                })?;
1456                n.clone()
1457            }
1458            None => {
1459                // Copy parent node up if necessary.
1460                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                    // Allocate inode number.
1476                    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                // new_node is always 'Some'
1484                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        // Node is whiteout.
1530        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            // Directory can't be hardlinked.
1538            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                // Node with same name exists, let's check if it's whiteout.
1548                if !n.whiteout.load(Ordering::Relaxed) {
1549                    return Err(Error::from_raw_os_error(libc::EEXIST));
1550                }
1551
1552                // Node is definitely a whiteout now.
1553                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                    // Whiteout file exists in upper level, let's delete it.
1563                    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                    // Replace existing real inodes with new one.
1574                    n.add_upper_inode(child_ri, true);
1575                    Ok(false)
1576                })?;
1577            }
1578            None => {
1579                // Copy parent node up if necessary.
1580                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                    // Allocate inode number.
1591                    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                // new_node is always 'Some'
1601                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        // parent was deleted.
1622        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                // Node with same name exists, let's check if it's whiteout.
1629                if !n.whiteout.load(Ordering::Relaxed) {
1630                    return Err(Error::from_raw_os_error(libc::EEXIST));
1631                }
1632
1633                // Copy parent node up if necessary.
1634                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                    // Replace existing real inodes with new one.
1655                    n.add_upper_inode(child_ri, true);
1656                    Ok(false)
1657                })?;
1658            }
1659            None => {
1660                // Copy parent node up if necessary.
1661                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                    // Allocate inode number.
1674                    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                // new_node is always 'Some'
1683                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        // Read the linkname from lower layer.
1710        let path = self_layer.readlink(ctx, self_inode)?;
1711        // Convert path to &str.
1712        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            // We already create upper dir for parent_node above.
1718            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            // update upper_inode and first_inode()
1726            node.add_upper_inode(real_inode, true);
1727        }
1728
1729        Ok(Arc::clone(&node))
1730    }
1731
1732    // Copy regular file from lower layer to upper layer.
1733    // Caller must ensure node doesn't have upper layer.
1734    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        // create the file in upper layer using information from lower layer
1753        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            // We already create upper dir for parent_node.
1764            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        // need to use work directory and then rename file to
1779        // final destination for atomic reasons.. not deal with it for now,
1780        // use stupid copy at present.
1781        // FIXME: this need a lot of work here, ntimes, xattr, etc.
1782
1783        // Copy from lower real inode to upper real inode.
1784        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        // close handles
1805        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 will remove file automatically.
1831        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                // Ignore ENOSYS.
1839                if e.raw_os_error() != Some(libc::ENOSYS) {
1840                    return Err(e);
1841                }
1842            }
1843
1844            // update upper_inode and first_inode()
1845            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        // directory
1858        if utils::is_dir(st) {
1859            node.create_upper_dir(ctx, None)?;
1860            return Ok(Arc::clone(&node));
1861        }
1862
1863        // For symlink.
1864        if st.st_mode & libc::S_IFMT == libc::S_IFLNK {
1865            return self.copy_symlink_up(ctx, Arc::clone(&node));
1866        }
1867
1868        // For regular file.
1869        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        // Find parent Overlay Inode.
1878        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        // Find the Overlay Inode for child with <name>.
1884        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            // already deleted.
1888            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            // Delete all whiteouts.
1900            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                // Parent is opaque, it shadows everything in lower layers so no need to create extra whiteouts.
1926                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        // lookups decrease by 1.
1951        node.lookups.fetch_sub(1, Ordering::Relaxed);
1952
1953        // remove it from hashmap
1954        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 is copied up, so it has upper layer.
1960            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        // Use O_RDONLY flags which indicates no copy up.
1997        let data = self.get_data(ctx, Some(handle), inode, libc::O_RDONLY as u32)?;
1998
1999        match data.real_handle {
2000            // FIXME: need to test if inode matches corresponding handle?
2001            None => Err(Error::from_raw_os_error(libc::ENOENT)),
2002            Some(ref rh) => {
2003                let real_handle = rh.handle.load(Ordering::Relaxed);
2004                // TODO: check if it's in upper layer? @weizhang555
2005                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    // Delete everything in the directory only on upper layer, ignore lower layers.
2015    fn empty_node_directory(&self, ctx: &Context, node: Arc<OverlayInode>) -> Result<()> {
2016        let st = node.stat64(ctx)?;
2017        if !utils::is_dir(st) {
2018            // This function can only be called on directories.
2019            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        // Copy node.childrens Hashmap to Vector, the Vector is also used as temp storage,
2028        // Without this, Rust won't allow us to remove them from node.childrens.
2029        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            // We only care about upper layer, ignore lower layers.
2039            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                // delete the child
2062                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            // lookup node
2120            let node = self.lookup_node(ctx, inode, "")?;
2121
2122            // whiteout node
2123            if node.whiteout.load(Ordering::Relaxed) {
2124                return Err(Error::from_raw_os_error(libc::ENOENT));
2125            }
2126
2127            if !readonly {
2128                // Check if upper layer exists, return EROFS is not exists.
2129                self.upper_layer
2130                    .as_ref()
2131                    .cloned()
2132                    .ok_or_else(|| Error::from_raw_os_error(libc::EROFS))?;
2133                // copy up to upper layer
2134                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    // Copies at most count bytes from self directly into f at offset off
2156    // without storing it in any intermediate buffers.
2157    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        // Read from self to slice.
2167        let ret = self.read_volatile(slice)?;
2168        if ret > 0 {
2169            let slice = unsafe { FileVolatileSlice::from_raw_ptr(buf.as_mut_ptr(), ret) };
2170            // Write from slice to f at offset off.
2171            f.write_at_volatile(slice, off)
2172        } else {
2173            Ok(0)
2174        }
2175    }
2176}
2177
2178impl ZeroCopyWriter for File {
2179    // Copies at most count bytes from f at offset off directly into self
2180    // without storing it in any intermediate buffers.
2181    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        // Read from f at offset off to slice.
2190        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            // Write from slice to self.
2195            self.write_volatile(slice)
2196        } else {
2197            Ok(0)
2198        }
2199    }
2200
2201    fn available_bytes(&self) -> usize {
2202        // Max usize
2203        usize::MAX
2204    }
2205}
2206
2207#[cfg(not(feature = "async-io"))]
2208impl BackendFileSystem for OverlayFs {
2209    /// mount returns the backend file system root inode entry and
2210    /// the largest inode number it has.
2211    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    /// Provides a reference to the Any trait. This is useful to let
2218    /// the caller have access to the underlying type behind the
2219    /// trait.
2220    fn as_any(&self) -> &dyn std::any::Any {
2221        self
2222    }
2223}