为什么Linux不需要删除文件系统调用
最近看了操作系统关于文件系统的组织方式, 突然想到了为什么 Linux 没有一个删除文件的系统调用. 😂说来还真是有种欧亨利式 “意料之外, 情理之中” 的感觉.
倒不如说 Linux 的设计是如此的简洁, 文件的逻辑存储通过硬链接实现就好了, 何必多此一举设计一个 delete
呢?
Linux 如何删除文件?
我们习惯了用 rm
命令来删除文件, 但是 rm
命令并不是一个系统调用, 它是一个用户空间的命令行工具.
实际上, rm
包装的是 unlink
系统调用. 啊? 为什么叫 unlink
而不是 delete
🤔?
strace rm test
# unlinkat(AT_FDCWD, "test", 0) = 0
索引节点
Linux 的文件系统基于索引节点, 索引节点是一个文件的元数据, 包含了文件的权限, 所有者, 大小, 时间戳等信息. 索引节点的编号是唯一的, 通过索引节点可以找到文件的数据块(盘块 whatever).
然而, 我们直接使用的都是逻辑文件, 我们当然可以通过目录项找到文件的索引节点, 然而这个索引节点本身, 为何不可以被看作是 “链接”? 我们可以建立多个链接指向同一个索引节点, 这样可以实现文件的共享. 但是作为文件所有者的我所创建的新文件其实也是一个链接, 这个链接很特殊, 它就是一个计数为 1 的 hard link. 当我们删除这个文件时, 我们只是删除了这个 hard link, 而不是删除了文件的数据块.
所以 Linux 如何删除文件的?
我们知道对于多个硬链接文件, 只有当所有的硬链接文件都被删除时, 文件系统才会回收这个文件的数据块. 那么硬链接计数为 1 不就是特例吗?
当我们删除一个文件时, 我们只是删除了这个文件的目录项, 也就是删除了这个文件的 hard link.
当这个文件的 hard link 计数为 0 时, 文件系统会回收这个文件的数据块. 这就是为什么 rm
命令实际上是 unlink
系统调用的原因.
我们使用 stat
命令查看一个我们从来没显式建立链接的文件, 我们会发现这个文件的硬链接数目是 1.
stat README.md
# File: "README.md"
# Size: 441 FileType: Regular File
# Mode: (0644/-rw-r--r--) Uid: ( 501/ xxx) Gid: ( 20/ xxx)
# Device: 1,17 Inode: 6922408 Links: 1
# Access: Sat Jan 18 00:50:20 2025
# Modify: Sat Jan 18 00:50:19 2025
# Change: Sat Jan 18 00:50:19 2025
# Birth: Sat Jan 18 00:50:19 2025