Skip to content

VFS Layer

opencode-agent[bot] edited this page May 10, 2026 · 3 revisions

VFS-Layer

The in-memory Virtual File System that unifies all mounted filesystems into a single namespace, exposing standard Java File operations.

Overview

JNode implements a Virtual File System (VFS) as an in-memory tree that aggregates all mounted filesystems. The VFS lives entirely in Java and is integrated with the standard Java I/O APIs via a custom FileSystem implementation. When an application calls new FileInputStream("/hd0a/data/file.txt"), the path is resolved through the VFS to find the appropriate filesystem driver.

Key Components

Class/File Location Purpose
FileSystemPlugin fs/src/fs/org/jnode/fs/service/def/ Plugin entry point; registers VFS as a service via InitialNaming
FileSystemService fs/src/fs/org/jnode/fs/service/ Interface for filesystem registration, mount points, and lookup
FileSystemManager fs/src/fs/org/jnode/fs/service/def/ Tracks registered FileSystem instances by device
FileSystemTypeManager fs/src/fs/org/jnode/fs/service/def/ Manages registered FileSystemType plugins (via extension point)
FileSystemMounter fs/src/fs/org/jnode/fs/service/def/ Auto-mounts filesystems from plugin extensions at startup
VirtualFS fs/src/fs/org/jnode/fs/service/def/ The VFS itself; implements FileSystem<VirtualDirEntry>
VirtualDirEntry fs/src/fs/org/jnode/fs/service/def/ A directory node in the VFS tree; contains a TreeMap of child entries
VirtualMountEntry fs/src/fs/org/jnode/fs/service/def/ A VFS entry that delegates to a mounted filesystem's root or subdirectory
FileSystemType fs/src/fs/org/jnode/fs/ Interface: factory for creating FileSystem instances from a Device
FileSystem fs/src/fs/org/jnode/fs/ Interface: represents a mounted filesystem (root entry, space info, device)
FSEntry fs/src/fs/org/jnode/fs/ Interface: a file or directory entry in a filesystem
FSDirectory fs/src/fs/org/jnode/fs/ Interface: directory node (iterator, getEntry, addDirectory, flush)
FSFile fs/src/fs/org/jnode/fs/ Interface: file read/write operations

How It Works

Mount Mechanism

The VFS is built when FileSystemPlugin.startPlugin() is called:

  1. FileSystemPlugin creates a VirtualFSDevice and registers it with the DeviceManager.
  2. It creates a VirtualFS instance backed by this device.
  3. FileSystemMounter scans plugin extensions for the types extension point.
  4. For each FileSystemType extension, the mounter probes the corresponding block device.
  5. If a valid filesystem signature is detected, a FileSystem instance is created and mounted.
  6. VirtualDirEntry.addMount(name, fs, path) creates a VirtualMountEntry in the VFS tree.

The VFS namespace is exposed to the VM via VMIOUtils.setAPI(getApi(), this), wiring JNode's FileSystemService into the standard Java I/O layer.

FSDriver Interface (FileSystemType)

FileSystemType is the factory interface that every filesystem driver implements:

public interface FileSystemType<T extends FileSystem<?>> {
    String getName();
    T create(Device device, boolean readOnly) throws FileSystemException;
}

Each concrete filesystem (e.g., FatFileSystemType) extends FileSystemType<FSDirectory> and:

  • Declares a plugin extension in its descriptor XML via the types extension point.
  • Implements create() to probe the device for a filesystem signature, then instantiate the driver.

FileSystemTypeManager loads these extensions at plugin startup and provides getSystemType(Class<T>) for lookup by type.

Path Resolution

When a Java application opens a file:

  1. The standard Java File API delegates to JNode's VMFileSystemAPI.
  2. FileSystemService receives the absolute path (e.g., /hd0a/data/file.txt).
  3. The path is tokenized: ["hd0a", "data", "file.txt"].
  4. VirtualFS.getRootEntry() returns the VFS root (VirtualDirEntry at /).
  5. getEntry("hd0a") returns a VirtualMountEntry pointing to the physical filesystem's root.
  6. getEntry("data") delegates into the mounted filesystem's FSDirectory, returning the actual directory entry.
  7. getEntry("file.txt") resolves to the file FSEntry.
flowchart TD
    Java["new FileInputStream('/hd0a/data/file.txt')"]
    VMIO["VMIOUtils → FileSystemService"]
    VFS["VirtualFS root /"]
    VME["VirtualMountEntry 'hd0a'"]
    FS["FatFileSystem on /dev/hd0a"]
    Sub["FSDirectory 'data'"]
    File["FSFile 'file.txt'"]
    Java --> VMIO --> VFS
    VFS -->|getEntry("hd0a")| VME
    VME -->|delegates| FS
    FS -->|getEntry("data")| Sub
    Sub -->|getEntry("file.txt")| File
Loading

Filesystem Driver Anatomy

A typical filesystem driver follows this pattern:

  1. SPI package (org.jnode.fs.spi.*): Provides AbstractFSObject, AbstractFSDirectory, AbstractFSFile, AbstractFSEntry base classes that implement the JNode FS interfaces.
  2. Concrete package (e.g., org.jnode.fs.fat): Contains the FatFileSystemType, FatFileSystem, FatDirectory, FatFile classes.
public class FatFileSystemType extends FileSystemType<FSDirectory> {
    public String getName() { return "fat"; }

    public FatFileSystem create(Device device, boolean readOnly) throws FileSystemException {
        return new FatFileSystem(device, readOnly);
    }
}

Gotchas

  • The VFS tree is completely in-memory. Rebooting clears all mounted state. Filesystems are re-mounted automatically at each boot via FileSystemMounter scanning plugin extensions.
  • VirtualMountEntry optionally supports mounting a subdirectory of the target filesystem (the fsPath parameter in mount()). This allows mounting /dev/hd0a/boot at /boot in the VFS namespace.
  • VirtualDirEntry uses a TreeMap<String, FSEntry> for child entries, enforcing alphabetical ordering. This provides deterministic iteration but limits scalability for very large directories.
  • Path resolution is string-based; there is no symbolic link support in the VFS layer itself (symbolic links are handled by individual filesystem drivers if supported).
  • FileSystemPlugin binds itself to InitialNaming as FileSystemService.class. Services that need filesystem access look it up via InitialNaming.get(NAME, FileSystemService.class).

Related Pages

Clone this wiki locally