Skip to main content
☘️ Septvean's Documents
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

Linux 文件系统(FS)

先讲 VFS,再讲 FS。

下面是一份 「内核级视角」Linux 文件系统子系统(VFS, Virtual File System)详解

不是 ls / mount 的用法,而是从内核抽象层 -> 数据结构 -> 路径解析 -> IO 调用 -> 容器/UnionFS 的完整认知体系

适用 RHEL / AlmaLinux / Debian / Ubuntu / 云 / 容器 / 数据库 / 虚拟化

一、VFS 是什么(先立核心认知)

VFS = Linux 的“文件系统抽象层”

它解决的问题:

  • ext4 / xfs / nfs / proc / overlayfs
  • 不同文件系统 -> 统一接口
用户程序
系统调用(open/read/write)
VFS(抽象)
具体文件系统实现

📌 没有 VFS,就没有“一切皆文件”

二、VFS 的设计目标

  1. 文件系统无关
  2. 高性能(缓存)
  3. 支持网络 / 虚拟 FS
  4. 支持 namespace / 容器

三、VFS 核心对象(四大结构)

理解 VFS,只要吃透这 4 个结构

结构 作用
super_block 文件系统
inode 文件元数据
dentry 目录项(名字)
file 打开的文件

1️⃣ super_block(文件系统实例)

struct super_block {
    struct file_system_type *s_type;
    struct dentry *s_root;
    struct block_device *s_bdev;
}
  • 每个 mount 一个
  • 描述“这个 FS 是什么”

2️⃣ inode(文件本体)

struct inode {
    umode_t i_mode;
    uid_t i_uid;
    loff_t i_size;
    struct inode_operations *i_op;
}

📌 inode ≠ 文件名

3️⃣ dentry(名字映射)

struct dentry {
    struct inode *d_inode;
    struct qstr d_name;
}
  • 路径解析核心
  • dentry cache 性能关键

4️⃣ file(打开实例)

struct file {
    loff_t f_pos;
    struct file_operations *f_op;
}

📌 同一个 inode 可被多个 file 引用

四、路径解析(Path Walk)全过程

/open("/a/b/c")

步骤:

  1. 查 dentry cache
  2. 若 miss -> inode lookup
  3. 若不存在 -> 创建 dentry
  4. 权限检查
  5. 返回 file

📌 目录越深,dentry cache 越重要

五、系统调用如何落到文件系统

1️⃣ open()

sys_open ->
  do_filp_open ->
    path_lookup ->
      inode_operations

2️⃣ read/write()

sys_read ->
  file->f_op->read_iter

📌 VFS 通过 function pointer 调度

六、Page Cache 与 VFS(性能核心)

文件 IO = Page Cache + VFS

1️⃣ 读流程

read ->
  page cache hit -> copy_to_user
  miss -> disk -> cache -> user

2️⃣ 写流程

write ->
  page cache dirty ->
    writeback

📌 fsync 才是真正落盘

七、文件系统类型分类

类型 示例
本地 FS ext4, xfs
网络 FS nfs, cifs
虚拟 FS proc, sysfs
Union FS overlayfs
特殊 tmpfs

八、Mount 机制(VFS 核心)

1️⃣ 挂载本质

把一个 super_block 挂到 dentry 上

/mnt
  └─ ext4 super_block

2️⃣ Mount Namespace

  • 每个容器独立视图
  • mount 私有化

九、权限模型(VFS 层)

权限检查顺序

  1. UID/GID
  2. Mode bits
  3. ACL
  4. Capability

📌 root 也要过 VFS 权限

十、inode 与链接

1️⃣ 硬链接

  • 同 inode
  • 引用计数

2️⃣ 软链接

  • 独立 inode
  • 内容是路径

十一、文件锁(VFS 层)

说明
flock 建议锁
fcntl POSIX 锁

📌 跨 FS / NFS 行为不同

十二、UnionFS / overlayfs(容器核心)

overlayfs 层次

lowerdir (image)
upperdir (container)
workdir
  • Copy-on-write
  • dentry / inode 映射复杂

📌 性能瓶颈常在 metadata

十三、VFS 与容器 / Kubernetes

  • 每个容器:
    • mount namespace
    • overlayfs rootfs
  • volume = 真实 FS

📌 数据库 volume ≠ overlay 层

十四、VFS 与数据库

影响
fsync 性能关键
inode cache 元数据
page cache buffer pool
Direct IO 绕过 cache

📌 DB 强烈依赖 VFS 行为

十五、常见误区纠正

❌ inode 就是文件

✅ inode 是元数据

❌ overlayfs 很慢

✅ metadata 慢,IO 还行

❌ page cache 是浪费

✅ 是性能命根子

十六、调试与观察接口

/proc/filesystems
/proc/self/mountinfo
/sys/fs

十七、一句话终极总结

VFS = inode + dentry + file + super_block,是 Linux 文件世界的“统一中枢神经系统”


下面是一份 「真正文件系统(FS)层面的 Linux 内核核心子系统详解」

这一次刻意不再停留在 VFS 抽象,而是往下走一层,回答三个关键问题:

  • 磁盘上的数据是如何组织的?
  • 内核如何把块设备变成“文件”?
  • ext4 / XFS / tmpfs / overlayfs 的本质差异是什么?

适用:RHEL / AlmaLinux / Rocky / Debian / Ubuntu / 云 / 容器 / 数据库 / 虚拟化

一、FS 在 Linux 内核中的位置

用户程序
VFS(抽象层)
具体文件系统(ext4 / xfs / nfs / tmpfs)
Block Layer
Block Device / Disk

📌 FS 是“VFS 的实现者 + Block Layer 的使用者”

二、文件系统(FS)到底解决什么问题?

把“线性的块设备” -> “结构化的文件与目录”

必须解决 6 个核心问题:

  1. 空间如何分配
  2. 元数据如何存储
  3. 文件如何定位
  4. 目录如何组织
  5. 崩溃如何恢复
  6. 性能如何保证

三、磁盘视角:文件系统的基本组成

几乎所有 FS 都包含:

[ Superblock ]
[ Metadata 区 ]
[ Data Blocks ]

1️⃣ Superblock(文件系统身份证)

保存:

  • FS 类型
  • block size
  • inode 数量
  • UUID
  • mount 状态

📌 superblock 损坏 = FS 无法识别

2️⃣ Metadata(元数据区)

包括:

  • inode 表
  • 位图(block / inode bitmap)
  • B+Tree / extent tree

3️⃣ Data Blocks(数据区)

  • 真正的文件内容
  • 由 inode 指向

四、inode:文件系统的“灵魂”

inode 是“文件”,而不是文件名

典型 inode 包含:

权限
UID / GID
大小
时间戳
指向数据块的指针

inode 如何指向数据?

早期(ext2)

  • 直接块
  • 间接块
  • 双重 / 三重间接

❌ 大文件效率差

现代(ext4 / xfs)

Extent(区段)

[start_block, length]
  • ✅ 连续 IO
  • ✅ 少 metadata
  • ✅ 更适合大文件 / DB

五、空间分配策略(性能关键)

1️⃣ Block Allocation(块分配)

目标:

  • 减少碎片
  • 连续 IO

2️⃣ 延迟分配(Delayed Allocation)

写的时候不立刻分配磁盘块

  • 先写 page cache
  • 刷盘时统一规划

📌 ext4 / xfs 默认启用

3️⃣ Preallocation(预分配)

  • 数据库常用
  • 减少碎片

六、目录的真实结构

目录 ≠ 特殊文件

目录 = “文件名 -> inode”的映射表

ext4 / xfs 目录结构

  • 小目录:线性表
  • 大目录:B-tree / HTree

📌 大量小文件性能看目录结构

七、日志(Journaling)机制

为什么需要日志?

防止断电 / crash 导致元数据损坏

日志三种模式(ext4)

模式 特点
writeback 快但不安全
ordered(默认) 数据先写
journal 数据 + 元数据

📌 XFS 永远是 ordered 类似行为

日志写入流程

metadata -> journal
commit
checkpoint -> main FS

八、ext4 vs XFS(内核级差异)

维度 ext4 XFS
设计目标 通用 大文件 / 并发
inode 固定数量 动态
日志 JBD2 内建
扩容 支持 更强
fsck 几乎不用
并发

📌 数据库 / 大盘:XFS

📌 系统盘 / 通用:ext4

九、Block Layer 与 FS 的关系

FS -> submit_bio -> block layer -> IO scheduler -> disk
  • FS 决定 “读什么块”
  • Block Layer 决定 “怎么读”

IO 调度器影响

  • mq-deadline(数据库)
  • none(NVMe)

十、fsync / fdatasync 的真相(数据库生死线)

fsync = 数据 + 元数据落盘

  • ext4 ordered:数据已先写
  • XFS:log 强一致

📌 fsync ≠ 立刻写磁盘,而是立刻保证持久性

十一、tmpfs(内存文件系统)

  • 不走 block layer
  • 页 = 内存

📌 /run /tmp /dev/shm

十二、overlayfs(容器 FS)

结构:

lowerdir(只读镜像)
upperdir(写层)
workdir

行为:

  • 写时复制(CoW)
  • metadata 映射复杂

📌 overlayfs 不适合数据库数据目录

十三、FS 与 Page Cache 的关系

  • FS 不直接读磁盘
  • 先查 page cache
  • writeback 异步

📌 数据库 buffer pool ≠ page cache

十四、FS 与容器 / 云

容器

  • rootfs = overlayfs
  • volume = ext4 / xfs

云盘

  • 写延迟大
  • fsync 成本高

十五、常见 FS 级“坑”

  • ❌ inode 用完但磁盘还有空间
  • ❌ overlayfs metadata 爆炸
  • ❌ fsync 频繁导致 TPS 掉崖
  • ❌ ext4 小 inode + 大文件数

十六、生产级 FS 选择建议

场景 建议
系统盘 ext4
数据盘 XFS
容器数据 直挂 volume
临时数据 tmpfs
日志 XFS + noatime

十七、总结

Linux 文件系统(FS)本质是:inode + block allocation + journaling + cache + IO 调度,把“块设备”变成“可靠、高效的文件世界”。