全面剖析 Linux 文件系统
Linux文件系统其实没那么神秘,它就是让电脑记住东西的一套规则。我最近翻了内核文档、看了几遍`strace read`的输出、还手贱`dd`坏过一块U盘,才搞懂——原来我们敲个`cat /etc/passwd`,背后要过七层代码,从VFS跳到ext4,再到块层,最后才摸到磁盘上的某个扇区。这事儿真不靠玄学,全靠代码里那一行行`if (inode->i_flags & S_DIRTY)`。
很多人以为文件系统就是能建文件夹、存照片,其实它得扛住断电、坏道、并发写,还要让`/proc`这种根本没磁盘的地方也能`ls`。VFS不是摆设,它是内核里一块硬骨头:`dentry`缓存路径,`inode`管文件属性,`file`结构体才是你`read()`真正操作的对象。我试过把`/proc/sys/vm/drop_caches`写成3,再看`ls /usr/bin`慢了快一秒——就是因为`dentry`全没了,得重新爬目录树。
ext4为啥现在还是主流?不是因为它多先进,而是它把老毛病都缝合了。ext2时代,一个大文件要用三层间接块找数据,写一次可能触发五次磁盘寻道。ext4用extent,一段连续空间直接记起始+长度,一个inode能管4GB。我还试过用`debugfs -R "stat
XFS和Btrfs真不是拿来替换ext4的。我搭过一套影视渲染NAS,XFS挂了30TB盘,`xfs_info`一看分配组有256个,每个组自己管空闲块,`rm -rf`大目录不卡;但换Btrfs跑Docker,一个`btrfs subvolume snapshot`秒建环境,快照里改配置不影响原系统,后台看`btrfs filesystem usage /`,共享块数清清楚楚。它们压根不是同类选手。
`/proc`和`/sys`更绝。我`echo deadline > /sys/block/nvme0n1/queue/scheduler`,再跑`iostat`,随机读延迟真降了20%。这不是魔法,是内核把调度器指针一换,后面所有IO请求就走新逻辑。还有`tmpfs`,我`mount -t tmpfs -o size=2g tmpfs /mnt/ram`,往里塞1.8G文件,内存直接涨,关机就清空,连`rm`都省了。
`mount`参数不是贴膏药。`noatime`关掉访问时间更新,数据库日志写入少15%元数据操作;`commit=60`让日志60秒刷一次,Kafka吞吐上去了,但断电真会丢近一分钟的`mkdir`记录;`errors=remount-ro`最老实,一出错自动只读,比崩掉强。我上次U盘报`EXT4-fs error`,就是靠`dmesg | grep EXT4`先定位,再`e2fsck -n`看能不能救,最后发现是USB线接触不良。
Btrfs快照看着炫,但`btrfs filesystem balance`跑起来CPU干到100%,SSD寿命也在掉。XFS的`xfs_repair`能重放日志修B+树,但得先确保日志没被覆盖。这些没一个能“一键修复”,全是盯着`dmesg`里那几行字,再查`man 8`一个参数一个参数试出来的。
`read()`进内核第一步是`vfs_read()`,最后一步是`blk_mq_submit_bio()`把`bio`结构体塞进块队列。中间每一步都有锁、缓存、回写、日志。没看源码前,我以为`open()`只是找路径,后来才发现它要在`dcache`里翻、在`inode_cache`里查、还要判断ACL、seccomp规则、甚至cgroup io.limit。一行`cat`背后,是几千行C代码在默默干活。







