从文件系统的角度区分硬链接与软连接

时间:2024-05-23 14:55:31

摘要

链接的目的是为了实现文件共享

同一个文件系统中如果两个文件(目录也是文件)具有相同的inode号码,那么就称它们是“硬链接”关系。这些具有硬链接关系的文件系统对象名字具有相同的inode号码,彼此是平等的。即首个被创建的文件并没有特殊的地位。

软链接有着自己的inode号以及用户数据块。只不过用户数据块中存放的内容是被链接文件的路径。当用户访问这个文件时,系统会根据所存储的路径,层层找到被链接的文件,如果这个文件已经被删除了,则会提示No such file or directory。

通过文件名打开文件,实际上是分成三步实现:首先,操作系统找到这个文件名对应的inode号码;其次,通过inode号码,获取inode信息;最后,根据inode信息,找到文件数据所在的block,读出数据。

1 引言

本人不喜看书,因为低效。看大半部分便草草结束。所以从汤小丹《计算机操作系统原理》,到郑刚的《操作系统 真象还原》,再到Tanenbaum的《现代操作系统》,才理解鸟哥书上(该书本处图不看也罢)关于硬链接与软连接的区别。
网上很多文章挺好,但是“缺少图片”。文字描述,有时候不好理解。故结合多篇文章与上面书籍中的相关内容,揉在一起,产生了下面的内容:从文件系统的角度区分硬链接与软连接。

2 文件系统的相关概念

2.1 创建文件系统的目的

首先,为什么需要文件系统?(只有需要,human才创建它,当然不是为了好玩)

现代操作系统为解决信息能独立于进程之外被长期存储引入了文件,文件作为进程创建信息的逻辑单元可被多个进程并发使用。在 UNIX 系统中,操作系统为磁盘上的文本与图像、鼠标与键盘等输入设备及网络交互等 I/O 操作设计了一组通用 API,使他们被处理时均可统一使用字节流方式。换言之,UNIX 系统中除进程之外的一切皆是文件,而 Linux 保持了这一特性。为了便于文件的管理,Linux 还引入了目录(有时亦被称为文件夹)这一概念。目录使文件可被分类管理,且目录的引入使 Linux 的文件系统形成一个层级结构的目录树。

其实往简单点说:因为硬盘能长期存储,为了管理硬盘,产生了文件系统。
操做系统提取处理器的概念来建立进程的抽象,提取物理存储器(内存)的概念来建立进程(虚拟)地址空间的抽象;从硬盘中建立抽象----文件,来解决信息长久存储/调用等问题。

硬盘上的文件由进程创建。硬盘上的文件使用之前,要被进程加载进入内存。
而“文件描述符,进程,文件之间的关系”,可以参看下面的链接。由于和本篇文章的关系不大,咱们不做介绍。(咱也不清楚,咱也不敢问。因为这里面最起码有硬盘驱动得事。)
文件描述符(File Descriptor)简介
Linux文件描述符到底是什么?
每个Unix进程都有的三个标准POSIX文件描述符

思考一个问题:内存和硬盘都为存储介质,为什么建立了不同的抽象?(一个为虚拟地址空间,一个为文件系统)
从文件系统的角度区分硬链接与软连接

2.2 文件系统的概念简介

硬链接与软连接的区别呢?为啥还在说文件系统。糊你一脸。
无奈啊,从文件系统的角度,可以很好的理解硬链接与软连接。所以咱们还得接着扛。
硬盘可以长久保存信息。咱们需要硬盘来保存文件。
所以,咱们如何在硬盘上组织文件系统,使得硬盘可以合理得存储文件,便于增删改查?

前提:我们现在考虑的范围,只有一个文件系统(不考虑虚拟文件系统(VFS))
能力有限,无法引导思考,咱们直接看文件系统得布局。(图片来自《操作系统 真象还原》)
从文件系统的角度区分硬链接与软连接
关于引导,主分区,逻辑分区之类咱们跳过。具体情况,我不知道,下面引用wiki-inode的一段话,来说明上面这张图的目的(di)。(当然,很明显,wiki这段解释,很不严谨。能力有限,不能修正)

文件系统创建(格式化)时,就把存储区域分为两大连续的存储区域。一个用来保存文件系统对象的元信息数据,这是由inode组成的表,每个inode默认是256字节或者128字节。另一个用来保存“文件系统对象”的内容数据,划分为512字节的扇区,以及由8个扇区组成的4K字节的块(block)。块是读写时的基本单位。一个文件系统的inode的总数是固定的。这限制了该文件系统所能存储的文件系统对象的总数目。典型的实现下,所有inode占用了文件系统1%左右的存储容量。

从文件系统的角度区分硬链接与软连接从文件系统的角度区分硬链接与软连接

上面可知:文件 = 元信息(inode) + 内容数据(blocks)。
元信息可以包含文件的字节数,文件拥有者,文件读、写、执行权限、时间戳、链接数、blocks位置。

那目录如何处理?
首先明确一点,目录也是文件。不管文件是普通文件,还是目录文件,它总会存在于某个目录中,所有的普通文件或目录文件都存在于根目录’/'之下,根目录是所有目录的父目录。目录下面有文件,也可以有目录。目录也是文件。一个目录数据块中 目录项数==文件数
从文件系统的角度区分硬链接与软连接
如上图所示。从根目录出发。文件 = 元信息(inode) + 内容数据(blocks)
根目录文件,有个inode。里面除了相关信息之外,包含 若干个目录项。每个目录项对应一个文件。如果该文件是一个非目录文件,直接找到文件对应的inode编号,然后找到对应的block。如果是一个目录文件,找到对应的inode编号,如果有执行(x)权限,则可以打开目录,进入新的目录。以此类推。

表面上,用户通过文件名,打开文件。实际上,系统内部这个过程分成三步:首先,系统找到这个文件名对应的inode号码;其次,通过inode号码,获取inode信息;最后,根据inode信息,找到文件数据所在的block,读出数据。

2.3文件共享

文件共享使多个用户(进程)共享同一份文件,系统中只需保留该文件的一份副本。如果系统不能提供共享功能,那么每个需要该文件的用户都要有各自的副本,会造成对存储空间的极大浪费。

为解决文件的共享使用,Linux 系统引入了两种链接:硬链接 (hard link) 与软链接(又称符号链接,即 soft link 或 symbolic link)。链接为 Linux 系统解决了文件的共享使用,还带来了隐藏文件路径、增加权限安全及节省存储等好处。

图片来自《现代操作系统》,4.3.4文件共享。
下面这张图,方框表示目录,圆圈表示文件。它仅仅是一个示意图,表文件共享即一个文件只有一个副本,但是可以放在不同的目录下,通过不同的路径访问。

从文件系统的角度区分硬链接与软连接
那我们如何通过链接实现文件共享?

2.3.1 硬链接实现文件共享

在目录中增添新的目录项。目录项中存储被链接文件的inode。
所以:若一个 inode 号对应多个文件名,则称这些文件为硬链接。换言之,硬链接就是同一个文件使用了多个别名。
从文件系统的角度区分硬链接与软连接

2.3.2 软连接实现文件共享

软链接与硬链接不同,若文件用户数据块中存放的内容是另一文件的路径名的指向,则该文件就是软连接。软链接就是一个普通文件,只是数据块内容有点特殊。软链接有着自己的 inode 号以及用户数据块
从文件系统的角度区分硬链接与软连接

2.3.3 硬/软链接特性对比

由于硬链接是有着相同 inode 号仅文件名不同的文件,因此硬链接存在以下几点特性:

  • 文件有相同的 inode 及 data block;
  • 只能对已存在的文件进行创建;
  • 不能交叉文件系统进行硬链接的创建;
  • 不能对目录进行创建,只可对文件创建;不能跨文件系统;
  • 删除一个硬链接文件并不影响其他有相同 inode 号的文件。

由于软连接是一个存储着被链接文件的特殊文件,所以软连接具有一下特性:

  • 软链接有自己的文件属性及权限等;
  • 可对不存在的文件或目录创建软链接;
  • 软链接可交叉文件系统;
  • 软链接可对文件或目录创建;
  • 创建软链接时,链接计数 i_nlink 不会增加;
  • 删除软链接并不影响被指向的文件,但若被指向的原文件被删除,则相关软连接被称为死链接(即 dangling link,若被指向路径文件被重新创建,死链接可恢复为正常的软链接)。

2.3.4为什么硬链接不能指向目录

因为硬链接文件和普通文件一样,他们地位平等,系统无法区分(.和…除外)。
如果硬链接的对象,是普通文件,如上图所示,没有什么问题。
但如果硬链接的对象,是目录。比如这个目录是自身,即目录项中的存储的inode节点是自身。那么在树形的目录结构中,遍历的时候,会产生死循环。因为图结构中有自回环。同理,如果链接的目录不是自身,就更加复杂。
这也是:为什么 允许目录的硬链接可能会打破文件系统的有向无环图结构。
而,软连接不会打破有向无环图。因为因为链接多产生一个文件,而且系统能够识别出它的属性(l)。
详细内容可以参考:多角度分析为什么 Linux 的硬连接不能指向目录

2.3.4 linux操作系统链接操作

上面只涉及理论知识,没有具体的操作佐证。因为我想操作挺简单。
Linux建立文件硬链接和软链接,王海军老师告诉你两种链接之区别(视频)
理解inode --阮一峰
5分钟让你明白“软链接”和“硬链接”的区别
理解 Linux 的硬链接与软链接

最后

为什么硬链接不能跨文件系统?
因为当前,我的讨论默认只有一个普通的文件系统。
从文件系统的角度区分硬链接与软连接
这篇文章的缺点,没有将操作与理论结合:
详细内容,可以参考:理解 Linux 的硬链接与软链接
另外,如果想更详细的了解文件系统知识,可以阅读操作系统的相关书籍。

我不维护这篇文章,即使文章中出现错误。
上面帮助理解的图片,可能是错的,我也不会修改。
能力有限,这篇文章的目的只有一个:在没有操作系统源码的支持情况下,理解了硬链接与软连接的区别,仅此而已。


参考文章
(参考文章中的内容本人并不是都明白,特别是在VFS的地方)
Linux 文件系统剖析 --M. Jones
文件系统 --wiki
理解inode --阮一峰
inode --wiki
5分钟让你明白“软链接”和“硬链接”的区别
理解 Linux 的硬链接与软链接
多角度分析为什么 Linux 的硬连接不能指向目录
文件描述符(File Descriptor)简介
Linux文件描述符到底是什么?
每个Unix进程都有的三个标准POSIX文件描述符