pub struct OverlayFS {
upper: Option<(Arc<MountPoint>, Arc<VfsEntry>)>,
lower_layers: Vec<(Arc<MountPoint>, Arc<VfsEntry>)>,
name: String,
root_node: Arc<OverlayNode>,
}
Expand description
OverlayFS implementation for VFS v2
This filesystem provides a unified view of multiple underlying filesystems by layering them on top of each other. Files and directories from all layers are merged, with the upper layer taking precedence for writes and the lower layers providing fallback content.
§Layer Resolution
When resolving files or directories:
- Check upper layer first (if present and not whiteout)
- Check lower layers in priority order
- Return first match found
§Write Operations
All write operations are performed on the upper layer. If a file exists only in lower layers, it is first copied to the upper layer (copy-up) before modification.
Fields§
§upper: Option<(Arc<MountPoint>, Arc<VfsEntry>)>
Upper layer for write operations (may be None for read-only overlay)
lower_layers: Vec<(Arc<MountPoint>, Arc<VfsEntry>)>
Lower layers (in priority order, highest priority first)
name: String
Filesystem name
root_node: Arc<OverlayNode>
Root node (composite of all layers)
Implementations§
Source§impl OverlayFS
impl OverlayFS
Sourcepub fn new(
upper: Option<(Arc<MountPoint>, Arc<VfsEntry>)>,
lower_layers: Vec<(Arc<MountPoint>, Arc<VfsEntry>)>,
name: String,
) -> Result<Arc<Self>, FileSystemError>
pub fn new( upper: Option<(Arc<MountPoint>, Arc<VfsEntry>)>, lower_layers: Vec<(Arc<MountPoint>, Arc<VfsEntry>)>, name: String, ) -> Result<Arc<Self>, FileSystemError>
Create a new OverlayFS instance with specified layers
§Arguments
upper
- Optional upper layer for write operations (mount point and entry)lower_layers
- Vector of lower layers in priority order (highest priority first)name
- Name identifier for this overlay filesystem
§Returns
Returns an Arc
§Example
let overlay = OverlayFS::new(
Some((upper_mount, upper_entry)), // Read-write upper layer
vec![
(layer1_mount, layer1_entry), // Higher priority lower layer
(layer2_mount, layer2_entry), // Lower priority layer
],
"system_overlay".to_string()
)?;
Sourcepub fn new_from_paths(
vfs_manager: &VfsManager,
upper_path: Option<&str>,
lower_paths: Vec<&str>,
name: &str,
) -> Result<Arc<Self>, FileSystemError>
pub fn new_from_paths( vfs_manager: &VfsManager, upper_path: Option<&str>, lower_paths: Vec<&str>, name: &str, ) -> Result<Arc<Self>, FileSystemError>
Create a new OverlayFS from VFS paths
This is a convenience method that resolves VFS paths to create an overlay. This approach follows the “normal filesystem” pattern - create the overlay instance, then mount it like any other filesystem.
§Arguments
vfs_manager
- VFS manager to resolve paths inupper_path
- Optional path for the upper (writable) layerlower_paths
- Vector of paths for lower (read-only) layersname
- Name for the overlay instance
§Example
// Create overlay from paths
let overlay = OverlayFS::new_from_paths(
&vfs_manager,
Some("/tmp/overlay"), // Upper layer
vec!["/system", "/base"], // Lower layers
"container_overlay"
)?;
// Mount like any other filesystem
vfs_manager.mount(overlay, "/merged", 0)?;
Sourcepub fn new_from_paths_and_vfs(
upper_vfs_and_path: Option<(&Arc<VfsManager>, &str)>,
lower_vfs_and_paths: Vec<(&Arc<VfsManager>, &str)>,
name: &str,
) -> Result<Arc<Self>, FileSystemError>
pub fn new_from_paths_and_vfs( upper_vfs_and_path: Option<(&Arc<VfsManager>, &str)>, lower_vfs_and_paths: Vec<(&Arc<VfsManager>, &str)>, name: &str, ) -> Result<Arc<Self>, FileSystemError>
Create a new OverlayFS from paths across multiple VFS managers (Cross-VFS)
This method enables true cross-VFS overlays where upper and lower layers can come from completely different VFS manager instances. This is perfect for container scenarios where the base system is in one VFS and the container overlay is in another.
§Arguments
upper_vfs_and_path
- Optional tuple of (vfs_manager, path) for upper layerlower_vfs_and_paths
- Vector of (vfs_manager, path) tuples for lower layersname
- Name for the overlay instance
§Example
// Cross-VFS overlay: base system from global VFS, overlay in container VFS
let base_vfs = get_global_vfs_manager();
let container_vfs = VfsManager::new();
let overlay = OverlayFS::new_from_paths_and_vfs(
Some((&container_vfs, "/upper")), // Upper in container VFS
vec![
(&base_vfs, "/system"), // Base system from global VFS
(&container_vfs, "/config"), // Config from container VFS
],
"cross_vfs_overlay"
)?;
// Mount in container VFS like any other filesystem
container_vfs.mount(overlay, "/merged", 0)?;
Sourcefn fs_from_mount(
mount: &Arc<MountPoint>,
) -> Result<Arc<dyn FileSystemOperations>, FileSystemError>
fn fs_from_mount( mount: &Arc<MountPoint>, ) -> Result<Arc<dyn FileSystemOperations>, FileSystemError>
Get FileSystemOperations from MountPoint
Helper method to extract the filesystem operations from a mount point. This is used internally to access the underlying filesystem operations for each layer.
Sourcefn get_metadata_for_path(
&self,
path: &str,
) -> Result<FileMetadata, FileSystemError>
fn get_metadata_for_path( &self, path: &str, ) -> Result<FileMetadata, FileSystemError>
Get metadata for a path by checking layers in priority order
This method implements the core overlay resolution logic:
- Check if the path is hidden by a whiteout file
- Check the upper layer first (if present)
- Fall back to lower layers in priority order
§Arguments
path
- The path to resolve within the overlay
§Returns
Returns FileMetadata for the first matching file found, or NotFound error if the file doesn’t exist in any layer or is hidden by whiteout.
Sourcefn resolve_in_layer(
&self,
mount: &Arc<MountPoint>,
entry: &Arc<VfsEntry>,
path: &str,
) -> Result<Arc<dyn VfsNode>, FileSystemError>
fn resolve_in_layer( &self, mount: &Arc<MountPoint>, entry: &Arc<VfsEntry>, path: &str, ) -> Result<Arc<dyn VfsNode>, FileSystemError>
Resolve a path in a specific layer, starting from the given node
This method performs path resolution within a single overlay layer, handling mount boundary crossings correctly. It walks down the path components, following mount points as needed.
§Arguments
mount
- The mount point to start resolution fromentry
- The VFS entry to start resolution frompath
- The path to resolve (relative to the entry)
§Returns
Returns the resolved VfsNode, or an error if the path cannot be resolved in this layer.
Sourcefn is_whiteout(&self, path: &str) -> bool
fn is_whiteout(&self, path: &str) -> bool
Check if a file is hidden by a whiteout file
Whiteout files are special files in the upper layer that indicate
a file from a lower layer should be hidden. They follow the naming
convention .wh.filename
where filename
is the name of the file
to be hidden.
§Arguments
path
- The path to check for whiteout
§Returns
Returns true if the file is hidden by a whiteout, false otherwise.
Sourcefn get_upper_layer(
&self,
) -> Result<(Arc<MountPoint>, Arc<VfsEntry>), FileSystemError>
fn get_upper_layer( &self, ) -> Result<(Arc<MountPoint>, Arc<VfsEntry>), FileSystemError>
Get upper layer, error if not available
Returns the upper layer mount point and entry, or an error if the overlay filesystem is read-only (no upper layer configured). This is used by write operations that require an upper layer.
§Returns
Returns (MountPoint, VfsEntry) tuple for upper layer, or PermissionDenied error if no upper layer is available.
Sourcefn create_whiteout(&self, path: &str) -> Result<(), FileSystemError>
fn create_whiteout(&self, path: &str) -> Result<(), FileSystemError>
Create a whiteout file to hide a file from lower layers
Sourcefn copy_up(&self, path: &str) -> Result<(), FileSystemError>
fn copy_up(&self, path: &str) -> Result<(), FileSystemError>
Perform copy-up operation: copy a file from lower layer to upper layer
Sourcefn ensure_parent_dirs(&self, path: &str) -> Result<(), FileSystemError>
fn ensure_parent_dirs(&self, path: &str) -> Result<(), FileSystemError>
Ensure parent directories exist in upper layer
Sourcefn file_exists_in_lower_only(&self, path: &str) -> bool
fn file_exists_in_lower_only(&self, path: &str) -> bool
Check if file exists only in lower layers (not in upper)
Sourcepub fn create_from_option_string(
_option: Option<&str>,
upper: Option<(Arc<MountPoint>, Arc<VfsEntry>)>,
lower_layers: Vec<(Arc<MountPoint>, Arc<VfsEntry>)>,
) -> Arc<dyn FileSystemOperations>
pub fn create_from_option_string( _option: Option<&str>, upper: Option<(Arc<MountPoint>, Arc<VfsEntry>)>, lower_layers: Vec<(Arc<MountPoint>, Arc<VfsEntry>)>, ) -> Arc<dyn FileSystemOperations>
Create an OverlayFS from an option string example: option = Some(“upper=tmpfs,lower=cpiofs”)
Trait Implementations§
Source§impl FileSystemOperations for OverlayFS
impl FileSystemOperations for OverlayFS
Source§fn lookup(
&self,
parent_node: &Arc<dyn VfsNode>,
name: &String,
) -> Result<Arc<dyn VfsNode>, FileSystemError>
fn lookup( &self, parent_node: &Arc<dyn VfsNode>, name: &String, ) -> Result<Arc<dyn VfsNode>, FileSystemError>
Source§fn open(
&self,
overlay_node: &Arc<dyn VfsNode>,
flags: u32,
) -> Result<Arc<dyn FileObject>, FileSystemError>
fn open( &self, overlay_node: &Arc<dyn VfsNode>, flags: u32, ) -> Result<Arc<dyn FileObject>, FileSystemError>
Source§fn create(
&self,
parent_node: &Arc<dyn VfsNode>,
name: &String,
file_type: FileType,
mode: u32,
) -> Result<Arc<dyn VfsNode>, FileSystemError>
fn create( &self, parent_node: &Arc<dyn VfsNode>, name: &String, file_type: FileType, mode: u32, ) -> Result<Arc<dyn VfsNode>, FileSystemError>
Source§fn remove(
&self,
parent_node: &Arc<dyn VfsNode>,
name: &String,
) -> Result<(), FileSystemError>
fn remove( &self, parent_node: &Arc<dyn VfsNode>, name: &String, ) -> Result<(), FileSystemError>
Source§fn is_read_only(&self) -> bool
fn is_read_only(&self) -> bool
Source§fn readdir(
&self,
node: &Arc<dyn VfsNode>,
) -> Result<Vec<DirectoryEntryInternal>, FileSystemError>
fn readdir( &self, node: &Arc<dyn VfsNode>, ) -> Result<Vec<DirectoryEntryInternal>, FileSystemError>
Source§fn create_hardlink(
&self,
link_parent: &Arc<dyn VfsNode>,
link_name: &String,
target_node: &Arc<dyn VfsNode>,
) -> Result<Arc<dyn VfsNode>, FileSystemError>
fn create_hardlink( &self, link_parent: &Arc<dyn VfsNode>, link_name: &String, target_node: &Arc<dyn VfsNode>, ) -> Result<Arc<dyn VfsNode>, FileSystemError>
Auto Trait Implementations§
impl Freeze for OverlayFS
impl !RefUnwindSafe for OverlayFS
impl Send for OverlayFS
impl Sync for OverlayFS
impl Unpin for OverlayFS
impl !UnwindSafe for OverlayFS
Blanket Implementations§
§impl<T> Any for Twhere
T: 'static + ?Sized,
impl<T> Any for Twhere
T: 'static + ?Sized,
§impl<T> Borrow<T> for Twhere
T: ?Sized,
impl<T> Borrow<T> for Twhere
T: ?Sized,
§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§unsafe fn clone_to_uninit(&self, dest: *mut u8)
unsafe fn clone_to_uninit(&self, dest: *mut u8)
clone_to_uninit
)