先谈硬链接
在外传03中我们知道,ext4 文件系统会把分区主要分为两大部分
- 小部分用于保存文件的 inode信息;
- 剩余的大部分用于保存 block 信息;
- 每个文件都独自占用一个 inode,文件内容存储在block中,由 inode 的记录来指向(数据块指针);
- 如果想要读取文件内容,就必须借助目录中记录的文件名找到该文件的 inode,才能成功找到文件内容所在的 block 块。
现在我们就需要知道,文件名保存在哪里
在上一篇外传03中,inode table格式可用看出,inode是不会记录文件名称的,那么文件名称是记录在哪里呢?答案是把文件名记录在上级目录的 block 中。也就是说,目录的 block 中记录的是这个目录下所有一级子文件和子目录的文件名及 inode 的对应;而文件的 block 中记录的才是文件实际的数据。
当我们查找一个文件,比如 /tmp/test 时,要经过以下步骤:
- 首先找到根目录的 inode(根目录的 inode 是系统已知的,inode 号是2),然后判断用户是否有权限访问根目录的 block。
- 如果有权限,则可以在根目录的 block 中访问到 /tmp 的文件名及对应的 inode 号。
- 通过 /tmp/ 目录的 inode 号,可以查找到 /tmp/ 目录的 inode 信息,接着判断用户是否有权限访问 /tmp/ 目录的 block。
- 如果有权限,则可以从 /tmp/ 目录的 block 中读取到 test 文件的文件名及对应的 inode 号。
- 通过 test 文件的 inode 号,就可以找到 test 文件的 inode 信息,接着判断用户是否有权限访问 test 文件的 block。
- 如果有权限,则可以读取 block 中的数据,这样就完成了 /tmp/test 文件的读取与访问。
按照这个步骤,在给源文件 /tmp/test 建立了硬链接文件 /home/test-hard 之后,在 /tmp/ 目录和 /home/ 目录的 block 中就会建立 test 和 test-hard 的信息,这个信息主要就是文件名和对应的 inode 号。但是我们会发现 test 和 test-hard 的 inode 信息居然是一样的,那么,我们无论访问哪个文件,最终都会访问 inode 号是 881202的文件信息。
硬链接的特点如下
- 不论是修改源文件,还是修改硬链接文件,另一个文件中的数据都会发生改变。
- 不论是删除源文件,还是删除硬链接文件,只要还有一个文件存在,这个文件都可以被访问
- 硬链接不会建立新的 inode 信息,也不会更改 inode 的总数
- 硬链接不能跨文件系统(分区)建立,因为不同的文件系统中,inode 号是重新计算的。
- 硬链接不能链接目录,因为如果给目录建立硬链接,那么不仅目录本身需要重新建立,目录下的所有子文件,包括子目录中的所有子文件都需要建立硬链接,这对当前的 Linux 来讲过于复杂
再谈软链接
软链接的源文件必须写绝对路径,否则建立的软链接文件就会报错,无法正常使用。软链接完全可以当作 Windows 的快捷方式来对待,它的特点和快捷方式一样。
硬链接不会建立自己的 inode 和 block,而是直接指向源文件的 inode 信息和 block,所以硬链接和源文件的 inode 号是一致的;
而软链接会真正建立自己的 inode 索引和 block,是一个真正的文件。所以软链接和源文件的 inode 号是不一致的,而且在软链接的 block 中,写的不是真正的数据,而仅仅是源文件的文件名完整路径及 inode 号。
删除软链接时,源文件不受影响;删除源文件时,软链接依旧存在,但是会提升文件不存在。
软链接可用跨分区,可用链接目录
因此软链接比硬链接更加常用。