Fundamentals 10 min read

How Linux’s Virtual File System Turns Everything Into a File

The article explains Linux’s Virtual File System (VFS) as an interface layer that treats all objects as files, illustrates the concept with Java‑style interface examples, then details the underlying C structures—file, file_operations, dentry, inode—and shows how the kernel links them to enable diverse file systems.

Liangxu Linux
Liangxu Linux
Liangxu Linux
How Linux’s Virtual File System Turns Everything Into a File

Introduction

In Unix philosophy, "everything is a file" means that any object can be accessed through the standard file‑handling interfaces. Linux implements this idea with a middle layer called the Virtual File System (VFS), which defines a uniform set of operations that higher‑level code can use regardless of the underlying file‑system implementation.

Java‑style Interface Example

To make the VFS concept easier to grasp, a Java‑style interface is used to model the VFS API.

public interface VFSFile {
    int open(String file, int mode);
    int read(int fd, byte[] buffer, int size);
    int write(int fd, byte[] buffer, int size);
    // ... other operations
}

public class Ext3File implements VFSFile {
    @Override
    public int open(String file, int mode) {
        // implementation
    }
    @Override
    public int read(int fd, byte[] buffer, int size) {
        // implementation
    }
    @Override
    public int write(int fd, byte[] buffer, int size) {
        // implementation
    }
    // ...
}

public class Main {
    public static void main(String[] args) {
        VFSFile file = new Ext3File();
        int fd = file.open("/tmp/file.txt", 0);
        // use fd with read/write
    }
}

Any object that implements VFSFile can be manipulated through open(), read(), and write() without the caller needing to know the concrete type.

Kernel Implementation in C

Linux is written in C, which lacks a native interface construct. Instead, the kernel simulates interfaces using structures of function pointers.

1. struct file

struct file {
    // ... other members ...
    const struct file_operations *f_op; // pointer to operations
    // ...
};

2. struct file_operations

struct file_operations {
    loff_t (*llseek)(struct file *, loff_t, int);
    ssize_t (*read)(struct file *, char __user *, size_t, loff_t *);
    ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *);
    // ... other callbacks ...
    int (*open)(struct inode *, struct file *);
    // ...
};

The kernel fills this structure with pointers to the concrete functions provided by a specific file‑system implementation.

3. Opening a file – __dentry_open()

static struct file *
__dentry_open(struct dentry *dentry,
              struct vfsmount *mnt,
              struct file *f,
              int (*open)(struct inode *, struct file *),
              const struct cred *cred)
{
    // ...
    inode = dentry->d_inode;
    // assign the file_operations from the inode to the file
    f->f_op = fops_get(inode->i_fop);
    // ...
    return f;
}

When a file is opened, the kernel retrieves the inode, copies its i_fop pointer into the newly created file object's f_op, and thus equips the file with the appropriate operations.

4. Example: Minix file‑system operations

const struct file_operations minix_file_operations = {
    .llseek      = generic_file_llseek,
    .read        = do_sync_read,
    .aio_read    = generic_file_aio_read,
    .write       = do_sync_write,
    .aio_write   = generic_file_aio_write,
    .mmap        = generic_file_mmap,
    .fsync       = generic_file_fsync,
    .splice_read = generic_file_splice_read,
};

If the current file‑system is Minix, calls to read() ultimately invoke do_sync_read(), and so on.

5. Directory entry – struct dentry

struct dentry {
    struct dentry *d_parent;   // parent directory
    struct qstr d_name;          // name of the entry
    struct inode *d_inode;       // pointer to inode
    const struct dentry_operations *d_op; // operations for dentry
    // ...
};

Each component of a pathname creates a dentry object, linked via d_parent to form a tree that the kernel can traverse.

6. Path – struct path

struct path {
    struct dentry *dentry; // points to the dentry of the file
    // ... other members ...
};

7. Inode – struct inode

struct inode {
    uid_t i_uid;   // owner user ID
    gid_t i_gid;   // owner group ID
    struct timespec i_atime; // last access time
    struct timespec i_mtime; // last modification time
    struct timespec i_ctime; // creation time
    unsigned short i_bytes;   // file size
    const struct file_operations *i_fop; // operations for files of this inode
    // ... other attributes ...
};

The inode represents the actual file on disk and stores metadata such as ownership, timestamps, and a pointer to the file‑operations table that will be used when a file is opened.

Conclusion

The Virtual File System provides a uniform interface that abstracts away the details of individual file‑system implementations. By defining a set of operation callbacks (the file_operations structure) and linking them through inode and file objects, Linux can support a wide variety of file systems while allowing user‑space programs to interact with them using the familiar open(), read(), and write() system calls.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

KernelC++LinuxinodeVFSDentry
Liangxu Linux
Written by

Liangxu Linux

Liangxu, a self‑taught IT professional now working as a Linux development engineer at a Fortune 500 multinational, shares extensive Linux knowledge—fundamentals, applications, tools, plus Git, databases, Raspberry Pi, etc. (Reply “Linux” to receive essential resources.)

0 followers
Reader feedback

How this landed with the community

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.