What Is the Linux Virtual File System (VFS)?
The Virtual File System (VFS), sometimes referred to as the Virtual
Filesystem Switch, is a core abstraction layer within the Linux kernel
that enables applications to access different types of file systems
uniformly. Rather than requiring distinct code for every storage format,
the VFS provides a standardized system-call interface, allowing local
file systems like Ext4, Btrfs, and XFS, network file systems like NFS,
and pseudo-file systems like /proc and /sys to
coexist and function interchangeably.
The Role of the VFS
In a traditional computing environment without an abstraction layer, programs would need custom routines to read and write data depending on whether the target storage is a hard drive, a flash drive, or a remote server. The VFS solves this by decoupling user-space applications from the underlying physical storage architecture.
When an application issues a standard POSIX system call—such as
open(), read(), write(), or
close()—it interacts directly with the VFS. The VFS
translates these general requests into the specific operations required
by the underlying file system driver, which then communicates with the
storage device driver.
Core Data Structures of VFS
The VFS operates through an object-oriented paradigm implemented in C using function pointer tables. It revolves around four primary data objects:
- The Superblock Object: Represents an entire mounted file system. It stores metadata regarding the file system itself, such as file system type, size, status, and pointers to the superblock operations table.
- The Inode Object: Represents a specific file or directory on the disk. It holds metadata about the file, including ownership, permissions, timestamps, and the physical location of the file's data blocks, but it does not store the file's name.
- The Dentry (Directory Entry) Object: Represents a directory entry, linking a human-readable file name to its corresponding inode. Dentries are cached in memory (the dentry cache or "dcache") to accelerate file path lookups and path resolution.
- The File Object: Represents a file that has been opened by a process. It tracks runtime state information, such as the current read/write offset position, access modes (read-only, write-only), and reference counts. Unlike inodes, which persist as long as the file exists, file objects are created dynamically when a file is opened and destroyed when it is closed.
How VFS Processes Requests
When a user process executes a command to read a file, the request follows a structured path:
- System Call: The application calls the standard C
library function, which triggers the
sys_read()system call in the kernel. - Path Resolution: The VFS traverses the dentry cache to locate the file's path components. If a dentry is not cached, the VFS queries the underlying file system to look up the path and construct the missing dentry.
- Dispatch to File System: The VFS retrieves the file
object associated with the process's file descriptor and calls the
implementation-specific read function (e.g.,
ext4_file_read_iter()) via the file object's operations table. - Hardware Execution: The file system driver translates the request into block-level addresses and passes it to the generic block layer and device driver to fetch the data.
Key Benefits
- Uniform Interface: Developers write code using a single, standard API regardless of the storage medium.
- Extensibility: Kernel developers can implement and add new file system types without modifying existing user-space software or other kernel subsystems.
- Performance Optimization: Through centralized caching mechanisms—such as the dentry cache and the page cache—the VFS minimizes expensive disk I/O operations across all mounted file systems.