Fundamentals 12 min read

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.

Ops Development Stories
Ops Development Stories
Ops Development Stories
How Linux VFS Mounts ext4: Deep Dive into Superblocks, Inodes, and Dentries

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

.

<code>register_filesystem(&amp;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,
};</code>

The actual mount operation is performed by

ext4_mount

, which delegates to

mount_bdev

to handle block devices.

<code>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);
}
</code>

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.

<code>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;
}
</code>
ext4_fill_super

proceeds 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.

KernelLinuxVFSfilesystemext4mounting
Ops Development Stories
Written by

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.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.