虚拟文件系统(VFS)

一、VFS 的角色

VFS(Virtual File System)是 Linux 内核对所有文件系统的抽象层:
- 统一接口(open/read/write/...)
- 上层(应用)透明
- 下层对接各种具体文件系统(ext4、vfat、proc、sysfs、...)

┌──────────────────────────┐
│  用户态:open/read/write │
├──────────────────────────┤
│  VFS(file_operations)   │
├──────────────────────────┤
│  具体文件系统(ext4...)   │
├──────────────────────────┤
│  通用块层 / 网络层        │
├──────────────────────────┤
│  设备驱动                 │
└──────────────────────────┘

二、四大对象

1. super_block(超级块)

2. inode(索引节点)

3. dentry(目录项)

4. file(打开文件)

四对象关系:

进程 fd_table
   ↓
[fd] → struct file
            ↓
       struct dentry
            ↓
       struct inode
            ↓
       struct super_block

三、关键结构

struct file_operations {
    struct module *owner;
    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 *);
    long (*unlocked_ioctl)(struct file *, unsigned int, unsigned long);
    int (*mmap)(struct file *, struct vm_area_struct *);
    int (*open)(struct inode *, struct file *);
    int (*release)(struct inode *, struct file *);
    int (*fsync)(struct file *, loff_t, loff_t, int);
    // ...
};

struct inode_operations {
    int (*create)(struct inode *, struct dentry *, umode_t, bool);
    struct dentry *(*lookup)(struct inode *, struct dentry *, unsigned);
    int (*link)(struct dentry *, struct inode *, struct dentry *);
    int (*unlink)(struct inode *, struct dentry *);
    int (*mkdir)(struct inode *, struct dentry *, umode_t);
    // ...
};

struct super_operations {
    struct inode *(*alloc_inode)(struct super_block *);
    void (*destroy_inode)(struct inode *);
    void (*write_super)(struct super_block *);
    int (*sync_fs)(struct super_block *, int);
    int (*remount_fs)(struct super_block *, int *, char *);
    void (*put_super)(struct super_block *);
    // ...
};

四、注册文件系统

#include <linux/fs.h>

static struct file_system_type my_fs_type = {
    .owner    = THIS_MODULE,
    .name     = "myfs",
    .mount    = myfs_mount,
    .kill_sb  = myfs_kill_sb,
    .fs_flags = FS_USERNS_MOUNT,
};
register_filesystem(&my_fs_type);
unregister_filesystem(&my_fs_type);

挂载:

mount -t myfs none /mnt/myfs

五、注册字符设备

详见 09-char-device.md

六、调试 VFS

# /proc/filesystems:已注册文件系统
# /proc/mounts:挂载点
cat /proc/mounts
mount
findmnt

# dcache 状态
cat /proc/sys/fs/dentry-state

# inode 状态
cat /proc/sys/fs/inode-state

# 调试特定 inode
debugfs/.../inode_dump

七、嵌入式常用文件系统

FS 用途
ext4 通用
vfat U盘、SD卡启动
tmpfs /tmp、/run
devtmpfs /dev
procfs /proc
sysfs /sys
squashfs 压缩只读 rootfs
jffs2 / ubifs NAND 闪存
overlayfs OTA、容器
f2fs eMMC 优化

八、文件系统挂载流程

mount -t ext4 /dev/mmcblk0p2 /mnt
  ↓
sys_mount → do_mount → do_new_mount
  ↓
vfs_kern_mount(...)
  ↓
alloc_super → fill_super(读磁盘填充 sb)
  ↓
分配根 inode 和 dentry
  ↓
挂载成功

九、O_DIRECT / O_SYNC

十、buffer_head 与 bio