文件系统
文件系统基本概念
文件系统是操作系统用于组织和管理存储设备(磁盘、SSD、NVMe)上数据的方法和结构。
核心功能:
- 命名管理:文件和目录的组织
- 空间管理:分配和回收存储空间
- 权限控制:文件访问权限
- 数据完整性:日志、校验、快照
文件系统结构
应用层
↓ 系统调用(open/read/write/close)
VFS(虚拟文件系统)
↓
具体文件系统(ext4 / NTFS / XFS / Btrfs ...)
↓
块层(Block Layer / IO 调度)
↓
设备驱动(SATA / NVMe / virtio)VFS(Virtual File System)
VFS 是 Linux 文件系统的核心抽象,定义了一组通用接口(inode、dentry、file、super_block),使得上层应用无需关心底层文件系统的具体实现。
VFS 四大对象:
- super_block:已挂载文件系统的元信息
- inode:文件/目录的元数据(权限、大小、位置、时间戳)
- dentry:目录项,维护路径名到 inode 的映射(缓存加速)
- file:进程打开的文件实例,含文件偏移、访问模式
inode
inode(索引节点)是文件系统中最关键的数据结构,存储文件的元数据而非文件名:
inode 内容:
├── 文件类型(普通/目录/管道/设备……)
├── 权限(rwx)
├── 硬链接计数
├── 文件大小(字节)
├── 时间戳(atime/mtime/ctime)
├── 属主(UID/GID)
├── 扩展属性(xattr)
└── 数据块指针(直接/间接/双重/三重)数据块指针结构(ext4):
inode 数据块索引(15 个指针):
0-11: 直接块指针(48KB)
12: 一级间接块(单个块指向 ~4MB)
13: 二级间接块(单个块指向 ~4GB * 块大小)
14: 三级间接块(单个块指向 ~4TB)dentry 缓存
路径名解析(如 /usr/local/bin)需要逐级查找目录,dentry 缓存将最近访问的"路径组分段 → inode"的映射存入内存,大幅加速文件路径查找。
磁盘空间管理
连续分配 vs 链式分配 vs 索引分配
| 方式 | 优点 | 缺点 |
|---|---|---|
| 连续分配 | 读取快,顺序 IO 性能好 | 碎片问题,难以动态增长 |
| 链式分配 | 空间利用率高 | 随机访问需遍历 |
| 索引分配(现代 FS) | 兼顾随机/顺序访问 | 间接块增加开销 |
空闲空间管理
- 位图(Bitmap):每个块用 1 bit 表示空闲/占用,ext4 使用
- 空闲链表:将空闲块链接,分配时取头
- B+ 树:Btrfs、XFS 使用 B+ 树管理
常见文件系统对比
| 文件系统 | 最大文件 | 最大卷 | 日志 | 特点 |
|---|---|---|---|---|
| ext4 | 16TB | 1EB | 含 | Linux 默认,成熟稳定 |
| XFS | 8EB | 8EB | 含 | 大文件高性能,RHEL 默认 |
| Btrfs | 16EB | 16EB | 含 | 写时复制、快照、压缩、校验和 |
| NTFS | 16EB | 256TB | 含 | Windows 默认,日志 + 压缩 + 加密 |
| FAT32 | 4GB | 2TB | 无 | 兼容性最好,无权限控制 |
| exFAT | 127PB | 128PB | 无 | 大文件 U 盘,广泛兼容 |
日志(Journaling)
- 写前日志(Write-ahead Logging):在修改元数据之前,先将操作写入日志
- 崩溃后通过回放日志恢复一致性
- 三种模式:Journal(全日志)/ Ordered(仅元数据 + 数据先写)/ Writeback(仅元数据)
- Ordered 模式是 ext4 默认,兼顾性能与安全
磁盘调度算法
- 先来先服务(FCFS):按请求顺序调度
- 最短寻道优先(SSTF):优先服务离磁头最近的请求
- 电梯算法(SCAN):磁头单向运动,沿途服务
- 循环扫描(C-SCAN):单向到末端后直接回起始
- NOOP:FIFO 合并,适合 SSD(无寻道开销)
- CFQ(完全公平队列):按进程分配 IO 时间片
SSD 无机械寻道和旋转延迟,使用 NOOP 或 NONE 调度器即可。
Linux 文件系统常用命令
bash
# 查看磁盘和分区
lsblk
fdisk -l
df -hT # 查看挂载点和文件系统类型
# inode 信息
stat file.txt
ls -li file.txt # 查看 inode 号
# 查看打开的文件
lsof
lsof -p <PID>
# 文件系统检查
fsck /dev/sda1
badblocks /dev/sda1
# 文件系统创建
mkfs.ext4 /dev/sdb1
mkfs.xfs /dev/sdc1常见面试问题
- inode 是什么?为什么修改文件权限不需要写数据块?
- 硬链接和软链接的区别?为什么硬链接不能跨文件系统?
- VFS 的作用?为什么 Linux 能挂载各种文件系统?
- ext4 的日志 Ordered 模式下如何保证一致性?
- SSD 上的文件系统和 HDD 上的有什么不同考虑?
- 删除一个大文件时,系统做了什么?为什么有时删除后磁盘空间没有立即释放?