土法炼钢兴趣小组的算法知识备份

【操作系统百科】VFS 四层抽象

文章导航

分类入口
os
标签入口
#vfs#inode#dentry#dcache#superblock

目录

“一切皆文件” 不是口号——ext4、btrfs、procfs、sysfs、FUSE、网络 socket 都通过同一套 VFS 接口暴露给用户。VFS 用四层抽象 + 操作表把具体实现和通用语义分开。

一、先看图

flowchart TD
    APP[用户 open/read/write] --> FD[struct file<br/>fd 表项]
    FD --> DENTRY[struct dentry<br/>目录项缓存]
    DENTRY --> INODE[struct inode<br/>元数据]
    INODE --> SB[struct super_block<br/>文件系统实例]
    SB --> FS[具体 FS 实现<br/>ext4/btrfs/xfs...]
    FD -.f_op.-> FOP[file_operations<br/>read/write/mmap...]
    INODE -.i_op.-> IOP[inode_operations<br/>lookup/create/link...]
    SB -.s_op.-> SOP[super_operations<br/>alloc_inode/sync_fs...]
    classDef vfs fill:#388bfd22,stroke:#388bfd,color:#adbac7;
    classDef ops fill:#a371f722,stroke:#a371f7,color:#adbac7;
    class FD,DENTRY,INODE,SB vfs
    class FOP,IOP,SOP ops

二、superblock

每个挂载的文件系统实例一个 super_block

struct super_block {
    struct list_head s_list;        // 全局链表
    dev_t s_dev;                    // 设备号
    unsigned long s_blocksize;
    struct file_system_type *s_type;
    const struct super_operations *s_op;
    struct dentry *s_root;          // 根目录
    struct hlist_bl_head s_roots;
    ...
};

s_op 包含 alloc_inodedestroy_inodesync_fsstatfs 等。

三、inode

每个文件/目录/符号链接一个 inode(内存中的):

struct inode {
    umode_t i_mode;                 // 权限 + 类型
    kuid_t i_uid; kgid_t i_gid;
    loff_t i_size;
    struct timespec64 i_atime, i_mtime, i_ctime;
    const struct inode_operations *i_op;
    const struct file_operations *i_fop;
    struct super_block *i_sb;
    struct address_space *i_mapping;  // 页缓存
    unsigned long i_ino;
    ...
};

inode 缓存(inode_cache)在 slab 里,hash 索引。

四、dentry

dentry 缓存路径组件 → inode 的映射:

struct dentry {
    struct dentry *d_parent;
    struct qstr d_name;             // 组件名 hash + len + name
    struct inode *d_inode;          // NULL = negative dentry
    const struct dentry_operations *d_op;
    struct super_block *d_sb;
    struct hlist_bl_node d_hash;    // dcache hash 桶
    struct list_head d_subdirs;
    ...
};

dcache

全局 hash 表 dentry_hashtable:按 (parent, name_hash) 查。命中 dcache 的路径查找只需内存操作,不碰磁盘。

negative dentry

d_inode = NULL 表示”这个名字不存在”——缓存 ENOENT,避免重复磁盘查找。

cat /proc/sys/fs/dentry-state
# nr_dentry  nr_unused  age_limit  want_pages  nr_negative

五、struct file

open() 创建一个 struct file

struct file {
    struct path f_path;             // {vfsmount, dentry}
    struct inode *f_inode;
    const struct file_operations *f_op;
    atomic_long_t f_count;          // 引用计数
    unsigned int f_flags;           // O_RDONLY/O_WRONLY/O_RDWR...
    fmode_t f_mode;
    loff_t f_pos;                   // 当前偏移
    struct address_space *f_mapping;
    ...
};

file 是”打开实例”——同一 inode 可有多个 file(多次 open)。

六、操作表模式

VFS 的设计模式:每层一个操作表(函数指针结构体),具体 FS 填充实现。

// ext4 注册
static const struct inode_operations ext4_dir_inode_operations = {
    .create     = ext4_create,
    .lookup     = ext4_lookup,
    .link       = ext4_link,
    .mkdir      = ext4_mkdir,
    ...
};

这是经典的”C 语言面向对象”。

七、mount 与 vfsmount

struct vfsmount {
    struct dentry *mnt_root;
    struct super_block *mnt_sb;
    int mnt_flags;
};

mount -t ext4 /dev/sda1 /mnt → 创建 super_block + vfsmount + 根 dentry。

mount namespace 隔离不同进程看到的挂载树。

八、RCU 路径查找

路径查找(path_lookup)的 RCU 模式(LOOKUP_RCU):

  1. 不加任何锁
  2. RCU 保护 dcache 读
  3. 每步验证 d_seq(sequence count)
  4. 成功 → 零锁路径解析
  5. 验证失败 → 降级到加锁模式(LOOKUP_LOCK

这让 stat() / access() 等频繁操作几乎无开销。

九、观察

# dcache/inode cache 大小
cat /proc/slabinfo | grep -E 'dentry|inode_cache'

# 挂载点
cat /proc/mounts

# 文件系统类型
cat /proc/filesystems

# VFS 统计
cat /proc/sys/fs/file-nr
# allocated  unused  max

十、小结


参考文献

工具


上一篇用户态分配器 下一篇路径名解析

同主题继续阅读

把当前热点继续串成多页阅读,而不是停在单篇消费。

2025-08-22 · storage

【存储工程】文件系统基础:inode、目录与 VFS

磁盘是一个线性的块数组,但没有人愿意用"第 48372 号扇区"来定位自己的文档。文件系统(File System)就是那个把"名字"映射到"数据"的翻译层——它把一片平坦的块空间组织成人类可以理解的层级结构,同时维护着每个文件的权限、大小、时间戳等元数据(Metadata)。

2026-05-16 · os

【操作系统百科】VFS I/O 路径全景

一次 read(fd, buf, n) 从用户态到磁盘要穿过多少层?本文追踪 VFS read/write 全路径——file_operations、iter_iov、iomap、页缓存命中与 miss、直接 I/O 旁路、块层提交、fsnotify 插桩。

2026-04-27 · os

【操作系统百科】内存回收

Linux 内存回收是 VM 最复杂的子系统之一。本文讲 active/inactive LRU、kswapd 与 direct reclaim、watermark 三线、swappiness 的真实含义、MGLRU 改造、memcg 回收与 PSI。

2026-04-28 · os

【操作系统百科】交换

swap 还值得开吗?本文讲 swap area 基础、swap cache、zram 压缩内存、zswap 前端压缩池、swappiness 的真实含义、容器里的 swap 策略,以及为什么现代 Android 全靠 zram 不靠磁盘。


By .