How Linux VFS Mounts ext4: Deep Dive into Superblocks, Inodes, and Dentries
This article explains the object‑oriented design of the Linux VFS, details the four core VFS structures, shows how ext4 is registered and mounted via register_filesystem and ext4_mount, and walks through the six‑step ext4_fill_super process for initializing superblocks and related metadata.
Mounting to Linux VFS
VFS Objects
VFS follows an object‑oriented design, abstracting key concepts into C structures that contain both data and the operations on that data. The four primary VFS objects are:
Superblock (struct super_block) : Represents a mounted filesystem and stores information such as type, size, and status. For disk‑based filesystems it resides on a specific disk sector; for memory‑based filesystems (e.g., sysfs) it is created in memory.
Inode (struct inode) : Represents a physical file on a storage device and holds metadata like permissions, size, and timestamps.
Dentry (struct dentry) : Describes a component of the filesystem hierarchy. Every path component—whether a directory (treated as a file) or a regular file—has a dentry object.
File (struct file) : Represents an opened file instance for a process, created by open() and destroyed by close(). Multiple file objects can refer to the same inode.
Additional VFS structures include struct file_system_type (describing filesystem types) and struct vfsmount (describing mount points).
Filesystem Mounting
Before the kernel can use a filesystem type, it must be registered. For ext4 this is done with register_filesystem(&ext4_fs_type), where the most important member is ext4_mount.
register_filesystem(&ext4_fs_type);
static struct file_system_type ext4_fs_type = {
.owner = THIS_MODULE,
.name = "ext4",
.mount = ext4_mount,
.kill_sb = kill_block_super,
.fs_flags = FS_REQUIRES_DEV,
};The actual mount operation is performed by ext4_mount, which delegates to mount_bdev to handle block devices.
static struct dentry *ext4_mount(struct file_system_type *fs_type, int flags,
const char *dev_name, void *data)
{
return mount_bdev(fs_type, flags, dev_name, data, ext4_fill_super);
}
struct dentry *mount_bdev(struct file_system_type *fs_type,
int flags, const char *dev_name, void *data,
int (*fill_super)(struct super_block *, void *, int))
{
struct block_device *bdev;
struct super_block *s;
fmode_t mode = FMODE_READ | FMODE_EXCL;
int error = 0;
if (!(flags & MS_RDONLY))
mode |= FMODE_WRITE;
/* get the device */
bdev = blkdev_get_by_path(dev_name, mode, fs_type);
if (IS_ERR(bdev))
return ERR_CAST(bdev);
/* ... omitted error handling and superblock initialization ... */
return dget(s->s_root);
error_s:
error = PTR_ERR(s);
error_bdev:
blkdev_put(bdev, mode);
error:
return ERR_PTR(error);
}After mount_bdev returns, ext4_fill_super reads the on‑disk ext4_super_block, creates and initializes an ext4_sb_info structure, and links it to the generic super_block.
The ext4_sb_info definition and the core of ext4_fill_super are shown below.
struct ext4_sb_info {
struct buffer_head *s_sbh; /* Buffer containing the super block */
struct ext4_super_block *s_es; /* Pointer to the super block in the buffer */
struct buffer_head **s_group_desc;
};
static int ext4_fill_super(struct super_block *sb, void *data, int silent)
{
struct ext4_sb_info *sbi;
struct buffer_head *bh;
struct ext4_super_block *es = NULL;
/* ... read super block, set up sbi fields, calculate groups, allocate descriptors ... */
return 0;
} ext4_fill_superproceeds in six steps:
Read the ext4_super_block (initially assuming a 1024‑byte block size).
Re‑calculate the logical superblock location and offset based on the actual block size (e.g., 4096 bytes).
Assign the retrieved super block to the ext4_sb_info fields.
Validate all group descriptor data and initialise flex‑bg information.
Obtain the filesystem root inode with ext4_iget and create the root dentry.
Call ext4_setup_super for final checks, write back changes, and update mount counters.
Each mounted filesystem has a unique struct file_system_type (e.g., ext4_fs_type) and one or more struct vfsmount instances representing mount points. The diagram below shows the relationship between superblocks, mount points, and specific filesystem instances.
Recovering Deleted Files Is Not Mysterious
On most disk‑based filesystems, data consists of metadata (information about files and directories) and the file contents themselves. Deleting a file typically removes only the metadata, leaving the actual content untouched until it is overwritten. This makes recovery possible if the blocks have not been reused, but also poses a security risk.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Ops Development Stories
Maintained by a like‑minded team, covering both operations and development. Topics span Linux ops, DevOps toolchain, Kubernetes containerization, monitoring, log collection, network security, and Python or Go development. Team members: Qiao Ke, wanger, Dong Ge, Su Xin, Hua Zai, Zheng Ge, Teacher Xia.
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.
