🐧 Linux 文件系统深度解析

从目录树到 inode,从 VFS 到权限模型,全面理解 Linux 文件系统原理

📁 目录结构 🔩 inode 机制 🌐 VFS 虚拟层 🔐 权限模型 💾 文件类型 ⚙️ 系统调用 📌 挂载机制
📁 Linux 目录结构(FHS 标准)
Filesystem Hierarchy Standard — 点击任意目录查看详细说明
🌳 目录树(可交互)
📊 挂载点 vs 目录

Linux 只有一个根 /,所有设备和分区通过 挂载(mount) 到某个目录点上,形成统一的树形命名空间。

# 查看所有挂载点 df -hT # 常见挂载情况 /dev/sda1 → / # 根分区 /dev/sda2 → /boot # 引导分区 /dev/sdb1 → /data # 数据盘 tmpfs → /tmp # 内存文件系统
⚡ 重要路径速查
路径用途是否可写
/etc系统配置文件root
/var/log系统日志可写
/proc内核进程信息(虚拟)只读
/sys设备/驱动信息(虚拟)只读
/dev设备文件设备
/tmp临时文件(重启清除)可写
🔩 inode — 文件的底层身份证
每个文件/目录都有唯一 inode,存储元数据和数据块指针
🧬 inode 结构可视化
📋 inode #12345
文件类型普通文件 (-)
权限0644
硬链接数1
UID / GID1000 / 1000
文件大小4,096 bytes
atime(访问)2026-05-12 10:00
mtime(修改)2026-05-10 08:30
ctime(变更)2026-05-10 08:30
直接块指针×12→ 数据块
一级间接块→ 指针块
二级间接块→ 指针块×2
三级间接块→ 指针块×3
💾 磁盘数据块(4KB/块)
点击数据块查看内容
🔗 硬链接 vs 软链接

硬链接(Hard Link):两个目录项指向同一个 inode。删除任意一个,文件仍在(引用计数 > 0)。不能跨文件系统,不能链接目录。


软链接(Symbolic Link):独立的 inode,文件内容是目标路径字符串。可以跨文件系统、可以链接目录。源文件删除后,软链接失效(悬空链接)。

# 硬链接 ln file.txt hardlink.txt ls -li # 同一 inode 号 # 软链接 ln -s /etc/hosts mylink readlink mylink # → /etc/hosts
📁 目录文件本质
目录在 Linux 中也是一种文件,其内容是目录项(dirent)的列表,每个条目包含文件名和 inode 号的映射。
📂 /home/user/ 的数据块内容
inode文件名
2.  (当前目录)
1.. (父目录)
12345file.txt
67890src/
11111.bashrc
🗂️ 磁盘布局:超级块 + inode 表 + 数据区
引导块
Boot Block
超级块
Super Block
inode数量/大小
块大小/状态
inode 位图
inode Bitmap
记录哪些inode已用
块 位图
Block Bitmap
记录哪些数据块已用
inode 表
inode Table
存储所有inode结构体
数据块区
Data Blocks
文件/目录的实际内容
🌐 VFS — 虚拟文件系统
Virtual File System:Linux 内核的文件系统抽象层,点击各层查看详情
🧱 VFS 分层架构
📦 核心数据结构
结构体含义对应概念
super_block文件系统元信息整个 FS 实例
inode文件元数据(内存中)磁盘 inode 的镜像
dentry目录项缓存路径 ↔ inode 映射
file打开的文件实例进程视图
address_space页缓存映射文件数据缓存
/* 每个进程的 fd 表 */ struct task_struct { struct files_struct *files; // fd[0]=stdin fd[1]=stdout ... } struct file { struct dentry *f_dentry; // 目录项 loff_t f_pos; // 文件偏移 struct file_operations *f_op; }
🔄 open() 调用路径:从用户态到磁盘
用户程序
open("/etc/hosts")
glibc
syscall(SYS_open)
VFS 层
路径解析/dentry缓存
具体FS
ext4_open()
Page Cache
内存页缓存查找
块设备层
I/O 调度器/驱动
磁盘
物理读写
📊 常见文件系统对比
文件系统类型最大文件最大分区特性
ext4Linux 标准16 TB1 EB日志、高兼容、稳定
XFS高性能8 EB8 EB大文件、并发写入强
Btrfs写时复制16 EB16 EB快照、RAID、校验
tmpfs内存 FSRAM限制RAM限制/tmp、共享内存、重启清除
procfs虚拟 FS--内核进程信息接口
sysfs虚拟 FS--设备/驱动信息暴露
NFS网络 FS网络限制-远程挂载、网络共享
🔐 权限模型
UGO 权限、特殊位、ACL — 点击权限位切换状态
🎚️ 权限位交互演示
所有者 (User)
群组 (Group)
其他 (Others)
🔑 权限含义对比
权限对文件对目录
r (4)读取文件内容列出目录内容 (ls)
w (2)修改/删除文件创建/删除子条目
x (1)执行文件进入目录 (cd)
⚡ 特殊权限位
名称效果
SUIDSet UID执行时以文件所有者身份运行
chmod u+s file / chmod 4755
SGIDSet GID执行时以文件所属组运行;目录中新文件继承组
chmod g+s dir / chmod 2755
Sticky粘滞位目录中只有文件所有者才能删除自己的文件
chmod +t /tmp / chmod 1777
🔢 chmod 数字法速记
# rwxrwxrwx → 777 # rwxr-xr-x → 755(常用于目录和可执行文件) # rw-r--r-- → 644(常用于普通文件) # rw------- → 600(私有文件,如私钥) chmod 755 script.sh # 数字法 chmod u+x script.sh # 符号法 chmod go-w file.txt # 移除组和其他的写权限 chown user:group file # 修改所有者:群组 umask 022 # 新文件默认权限掩码(文件=644,目录=755)
📄 Linux 文件类型
Linux 中"一切皆文件"— 7 种文件类型
🔍 ls -l 输出解读
drwxr-xr-x 2 user group 4096 May 12 10:00 src/ ↑ ↑↑↑ ↑↑↑ ↑↑↑ ↑ ↑ ↑ ↑ ↑ 文件类型 user权限 group权限 other权限 硬链接数 所有者 群组 大小(字节) 最后修改时间 文件名
-普通文件
d目录
l符号链接
c字符设备
b块设备
p管道
s套接字
💾 挂载机制
将设备/文件系统附加到目录树的过程
🔧 挂载原理可视化
📀 /dev/sda1(根分区)
/ ← 挂载点
├── bin/
├── etc/
├── home/
├── mnt/ ← 挂载点
└── usr/
+
💿 /dev/sdb1(数据盘)
/ ← 设备根
├── data/
├── backup/
└── media/
🌳 挂载后的统一视图
/
├── bin/
├── etc/
├── home/
├── mnt/
│ ├── data/ ← sdb1
│ ├── backup/ ← sdb1
│ └── media/ ← sdb1
└── usr/
⌨️ 常用 mount 命令
# 挂载磁盘分区 mount /dev/sdb1 /mnt/data # 只读挂载 mount -o ro /dev/sdb1 /mnt/data # 挂载 tmpfs(内存文件系统) mount -t tmpfs -o size=512m tmpfs /tmp/ramdisk # bind 挂载(目录绑定) mount --bind /home/user /var/chroot/home # 卸载 umount /mnt/data # 查看挂载信息 cat /proc/mounts findmnt
📋 /etc/fstab 开机自动挂载
# 设备/UUID 挂载点 类型 选项 dump pass UUID=xxx / ext4 defaults 0 1 UUID=yyy /boot ext4 defaults 0 2 UUID=zzz /data xfs defaults 0 2 tmpfs /tmp tmpfs size=1g 0 0 /dev/sr0 /media iso9660 ro,user 0 0

pass 字段:0=不检查,1=先检查(根分区),2=后检查

dump 字段:0=不备份,1=备份(已基本废弃)

• 推荐使用 UUID 而不是设备名(设备名可能变化)

🐳 Docker 与 Linux 挂载的关系
Docker 容器文件系统本质上是基于 Linux 内核的多种挂载技术:
OverlayFS
联合文件系统,将镜像层(只读)和容器层(可写)叠加。是 Docker 默认存储驱动
bind mount
-v /host:/container 本质是 bind 挂载,让容器访问宿主机目录
tmpfs mount
--tmpfs 挂载内存文件系统,容器停止后数据消失,用于临时安全数据
⚙️ 文件系统调用
用户空间如何通过系统调用操作文件 — 点击步骤查看代码示例
← 点击左侧步骤查看代码示例
📖 常用文件系统调用速查
系统调用原型功能
openint open(path, flags, mode)打开/创建文件,返回 fd
readssize_t read(fd, buf, count)从 fd 读取数据
writessize_t write(fd, buf, count)向 fd 写入数据
closeint close(fd)关闭文件描述符
lseekoff_t lseek(fd, offset, whence)移动文件读写位置
statint stat(path, statbuf)获取文件元信息(inode)
mmapvoid* mmap(addr,len,prot,flags,fd,off)内存映射文件
unlinkint unlink(path)删除文件名(减少硬链接)
renameint rename(old, new)原子重命名(mv 的底层)
fsyncint fsync(fd)刷新页缓存到磁盘(持久化)
🧠 知识测验
测试一下你的理解程度