Understanding Linux File Systems and the Virtual File System (VFS) Architecture
This article explains the design of Linux file systems, the role of inodes, data blocks, superblocks, and the Virtual File System layer that provides a unified interface for diverse storage back‑ends, detailing core structures, registration, mounting, and file operation workflows.
Linux File System Basics
Linux organizes storage using a hierarchical directory tree where each directory has a specific purpose, and files are represented by inodes that store metadata while data blocks hold the actual content. The superblock acts as the global controller, keeping essential filesystem information.
What Is a Filesystem?
A filesystem manages how data is stored on devices such as HDDs or SSDs, providing naming, permission, and access mechanisms. When a file is created, the system allocates space, records attributes (name, size, timestamps), and links the file to its inode.
Linux‑Specific Features
Linux treats everything as a file, including devices, processes, and sockets, allowing uniform operations via standard system calls (open, read, write, etc.). Common Linux filesystems include the EXT family (ext2/3/4), XFS, and Btrfs, each with distinct characteristics.
EXT series : ext2 (simple, no journaling), ext3 (adds journaling), ext4 (larger files, better performance).
XFS : high‑performance journaling filesystem suited for large files and heavy I/O.
Btrfs : modern filesystem offering checksums, snapshots, compression, deduplication, and online resizing.
Core Principles of Linux Filesystems
The root directory "/" branches into many sub‑directories such as /bin , /sbin , /etc , /home , /dev , /tmp , /var , etc., each serving specific system or user functions.
Inode and Data Block Interaction
An inode stores metadata (type, permissions, owner, size, timestamps, link count, and block pointers). Data blocks contain the file’s actual bytes. The inode’s block pointers map to the physical blocks where the file data resides.
struct inode {
unsigned long i_ino; // inode number
umode_t i_mode; // file type and permissions
uid_t i_uid; // owner UID
gid_t i_gid; // group GID
loff_t i_size; // file size
struct super_block *i_sb; // pointer to superblock
struct inode_operations *i_op; // inode operation callbacks
...
};Superblock – The Filesystem "Brain"
The superblock holds global filesystem metadata such as total size, block size, inode table size, layout, name, creation/modification times, and mount/status flags. It is read into memory during mount and guides all subsequent operations.
struct super_block {
dev_t s_dev;
unsigned long s_blocksize;
unsigned char s_blocksize_bits;
struct list_head s_list;
struct file_system_type *s_type;
struct super_operations *s_op;
...
};Virtual File System (VFS)
VFS provides a uniform abstraction layer above concrete filesystems and below user space. It defines four core objects: superblock, inode, dentry (directory entry), and file. These objects cooperate to register, mount, and operate on files regardless of the underlying filesystem type.
VFS Core Objects
Superblock : global filesystem descriptor.
Inode : per‑file metadata.
Dentry : links a filename to an inode and forms the directory tree.
File : per‑process open file instance containing position, flags, and operation pointers.
struct dentry {
struct inode *d_inode;
struct dentry *d_parent;
const char *d_name;
struct super_block *d_sb;
...
};
struct file {
struct dentry *f_dentry;
struct vfsmount *f_mount;
loff_t f_pos;
unsigned short f_flags;
struct file_operations *f_op;
...
};When a process calls open() , VFS resolves the pathname to a dentry, loads the corresponding inode, creates a file object, and links it to the appropriate file‑operation callbacks. Subsequent read() or write() calls use these callbacks to interact with the underlying filesystem.
Filesystem Registration and Mounting
Each filesystem registers a file_system_type structure with the kernel via register_filesystem() . During a mount operation, the kernel invokes the filesystem’s mount function, creates a superblock, initializes the root inode, and attaches the filesystem to a mount point in the VFS namespace.
File Operation Flow
Opening a file allocates a kernel buffer (dynamic file) and loads the static file from disk. Reads and writes operate on the dynamic copy; the kernel later synchronizes changes back to the storage device. The process control block (PCB) holds a file‑descriptor table that maps user‑level descriptors to kernel file structures.
Advantages and Applications
VFS enables seamless use of multiple filesystems (e.g., EXT4, XFS, Btrfs, NFS, FAT32) and storage media (local disks, USB drives, network shares) without application changes. It also simplifies adding new filesystems—developers implement the required VFS callbacks and register the filesystem, after which it becomes available system‑wide.
Examples include copying files between EXT4 and XFS partitions with a single cp command, or using Python’s open() to read from one filesystem and write to another, all mediated by VFS.
Deepin Linux
Research areas: Windows & Linux platforms, C/C++ backend development, embedded systems and Linux kernel, etc.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.