目录
一、理解磁盘结构
1、磁盘的物理结构
2、硬件层面理解
3、磁盘的具体物理存储结构
4、进行逻辑抽象
5、磁盘文件的管理
6、创建新文件的过程
二、理解文件系统
1、文件的构成
2、为何选择4KB而非512字节作为基本单位?
3、文件系统的组成
数据块(Data Blocks)
inode表(inode Table)
块位图(Block Bitmap)
inode位图(inode Bitmap)
块组描述符(GDT)
超级块(Super Block)
文件与inode和数据块的关系
4、目录与inode
二、软链接和硬链接
1、概念
2、使用方法
3、软链接相当于快捷方式
4、硬链接相当于起别名
5、引用计数
文件删除与inode的关系
目录的引用计数
6、总结
一、理解磁盘结构
1、磁盘的物理结构
磁盘作为计算机系统中不可或缺的存储介质,尤其是传统的机械硬盘(HDD),是唯一具有机械设备性质的核心外设。尽管当前固态硬盘(SSD)逐渐普及并取代了部分HDD市场,但其基本原理和数据持久化功能仍与磁记录技术紧密相关。磁盘利用磁性材料在盘片上记录信息,以实现大规模二进制数据的长久保存,即使在断电状态下也能确保数据不丢失。
-
磁盘,作为计算机系统中倚重的存储技术核心,采用磁记录原理持久化存储海量二进制信息,并能够在断电后依然维持数据完整性。磁盘实质上是一个精密的机械电子设备,其构造主要包括磁盘盘片、读写磁头组件、主轴驱动系统以及传动机构等关键部件。
-
磁盘盘片是储存数据的核心载体,在其光滑的表面上划分出一系列精细的逻辑结构——磁道和扇区。磁道呈同心圆状分布于盘片之上,而扇区则进一步将磁道细分为更小的数据存储单元。此外,所有盘片在相同径向位置上的磁道集合构成一个柱面,这种三维的空间布局设计确保了对磁盘上数据的高效定位与存取操作。
-
为了优化磁盘空间管理和提高数据保护水平,操作系统不会直接使用未经分区的整个物理磁盘。通过磁盘分区这一过程,原始硬盘被划分为多个独立且逻辑上隔离的区域,我们称之为磁盘分区。这种分割不仅有助于增强数据安全性,防止不同分区之间的数据相互干扰,同时也极大地便利了存储资源的组织与管理。
-
本地磁盘,则特指那些固着于同一台计算机主板内部,无法自由插拔或移动的存储硬件单元。此类磁盘通常包括承载操作系统运行所必需的系统分区以及其他用户数据分区,它们共同构成了计算机不可或缺的基础存储架构。
2、硬件层面理解
- 磁盘是一种利用磁记录技术来存储数据的硬件设备,其核心组成部分包括磁盘盘片、磁头、主轴与传动组件等。数据实质上被存储在磁盘盘片的特定区域中。
- 磁盘盘片经过精细划分以实现逻辑上的定位和存取管理,具体表现为磁道、扇区及柱面结构。
- 磁道是盘片表面上的一系列同心圆;
- 扇区则是将每个磁道划分为若干个相等的弧段;
- 而柱面则是一个包含同一半径上所有磁道的整体,跨越了多个盘片。
- 磁头作为硬盘读写操作的关键部件,其精密程度至关重要。它由缠绕着线圈的磁芯构成,工作原理基于特殊材料的电阻值随磁场变化的特性,从而实现在盘片上进行数据的读写操作。
- 磁头的移动与定位主要依赖于磁头驱动组件,该组件由电磁线圈电机、磁头臂架(或称磁头驱动小车)以及防震装置组成。高精度且轻量化的磁头驱动机构能够确保磁头准确、迅速地响应系统指令,精确地定位至指定磁道,进而保障数据读写的稳定性与可靠性。
- 主轴组件是整个磁盘系统中的重要部分,它包含了主轴部件、轴承以及主轴电机等。随着硬盘容量和速度的发展,主轴电机的速度也在不断提升,部分厂商已采用液态轴承机电技术,这种技术的应用显著降低了硬盘运行时产生的噪音,并提高了整体性能表现。
- 前置放大电路负责控制磁头感应信号的处理、主轴电机转速调节、磁头驱动以及伺服定位等一系列关键功能。由于磁头读取的数据信号极其微弱,因此将放大电路封装在密闭腔体内,可有效减少外部干扰,增强操作指令的准确性与可靠性。
磁头与盘面保持微小间隙不直接接触。
这是因为在硬盘的物理结构中,磁头和盘片之间极小的距离(通常在纳米级别)是为了防止二者之间的任何物理接触。一旦磁头与高速旋转的盘面发生碰撞或刮擦,不仅会严重磨损磁头,还会导致盘面上存储数据的磁介质受损,进而引发数据丢失或损坏,这可能导致操作系统无法正常启动以及其他严重的数据完整性问题。
机械硬盘由于其内部物理机制限制,在一定程度上已被固态硬盘(SSD)所取代。这种淘汰趋势的原因包括但不限于:
- 性能瓶颈:机械硬盘受限于磁头移动速度(寻道时间)和磁盘转速(决定数据传输速率),而固态硬盘则基于闪存芯片,无须机械运动部件,从而提供更快的数据读写速度。
- 耐用性与可靠性:正如之前所述,机械硬盘的磁头与盘片间的距离虽小但必须保持,因此易受振动、冲击等因素影响,造成潜在故障风险;而固态硬盘没有活动部件,更耐冲击且整体可靠性更高。
- 功耗与发热:固态硬盘具有更低的功耗及工作时产生的热量较少,更适合便携设备和需要节能的应用场景。
磁盘伺服电路是硬盘驱动器中的一个重要组成部分,它负责控制磁头定位系统,确保磁头能够精确地在预定的磁道上进行读写操作,实现对存储在盘面上微观磁化区域(即比特位0和1)的高效读取与修改。
怎么消磁?
关于磁盘消磁,传统意义上讲,确实可以通过加热至一定温度来消除磁介质上的磁场强度,从而抹去存储的数据。然而,这种方法并不适用于日常数据清除需求,因为过度加热会导致硬件损坏,而且不适用于大规模数据销毁。现代数据安全标准倾向于采用专门的数据擦除软件工具或者多次覆盖写入的方法来安全、有效地清除磁盘上的信息。
3、磁盘的具体物理存储结构
磁盘的最基本存储单元是扇区,通常情况下,标准磁盘中的每个扇区大小为512字节。在同一圆周半径上的所有扇区集合在一起构成了一个逻辑概念——磁道。磁道沿盘片半径方向排列,如同一圈圈同心圆分布在磁盘表面。
定位磁盘上的特定扇区是一项精密操作,它依赖于三个关键参数:柱面号(Cylinder)、磁头号(Head)和扇区号(Sector)。这三个数值共同组成了磁盘的物理地址,用于唯一确定一个具体的存储位置。
定位扇区的过程可细分为两个阶段:
- 寻道阶段:首先,磁头臂会根据目标柱面号移动磁头到相应的磁道上,这个过程的时间称为“寻道时间”,其长短与磁头需要跨越的物理距离有关。
- 旋转延迟阶段:当磁头到达目标磁道后,等待目标扇区随着磁盘的转动而转至磁头下方。这一时段被称为“旋转延迟时间”,它的长度取决于磁盘每分钟转速(RPM),即磁盘旋转一周所需时间的特定比例。
为了准确高效地定位扇区,磁盘访问技术采用了多种方法:
- CHS寻址方式:通过柱面-磁头-扇区的三维坐标系统来指定扇区地址。
- LBA逻辑块地址法:将磁盘空间线性编址,忽略实际的物理布局,简化了操作系统对磁盘的管理。
- GPT全局唯一标识分区表:在更现代的磁盘管理系统中,尤其是对于大容量硬盘,使用GPT能够提供更加灵活、扩展性和容错性更强的分区及寻址方案。尽管GPT主要涉及分区层面而非直接的扇区寻址,但其高级抽象层之下仍基于LBA或其他底层寻址机制。
4、进行逻辑抽象
谈到过物理层面定位某个扇区运用的算法是CHS定位法,那么LBA如何转到CHS定位呢?其实很简单,只需通过一些计算方式就可以进行转换,下面图片中的计算方法是捏出来的数据,方便大家理解LBA转到CHS定位的过程。
H磁头用来判断是哪个扇面,C柱面用来判断是哪个磁道,S就是确定在具体扇面的具体磁道中的具体某个扇区,这些工作在软件层面都可以解决,解决的过程其实就是LBA转到CHS的过程。
为什么OS要进行磁盘的逻辑抽象呢?直接用CHS定位不行吗?
操作系统(OS)对磁盘进行逻辑抽象,而非直接采用如CHS(柱面-磁头-扇区)等物理寻址方式,主要基于以下两个关键考量:
首先,从管理层面看,将复杂的三维物理结构简化为软件层面易于操作的一维线性地址空间至关重要。直接使用CHS等物理定位方法时,操作系统必须处理磁盘的立体几何布局,这不仅增加了管理的复杂度,而且不利于系统的简洁性和高效性。通过逻辑抽象,操作系统只需维护一个线性数组形式的存储结构,大大降低了数据存取和组织的难度。
其次,也是更为重要的一点是,逻辑抽象有助于实现软硬件解耦。如果操作系统直接与特定硬件架构强绑定,一旦底层存储设备发生变更,比如由传统的硬盘驱动器(HDD)升级为固态硬盘(SSD),由于两种设备的工作原理及内部结构差异,原有的OS代码可能无法正常运行或至少需要大幅度调整。而通过引入逻辑块地址(LBA)等抽象层,操作系统可以不关心具体存储设备的物理特性,而是统一将所有类型的存储设备视为单一的、连续的数据区块集合。这样一来,无论底层硬件如何更新换代,操作系统都能保持相对稳定且具备良好的兼容性和适应性。
5、磁盘文件的管理
- 在磁盘文件的管理中,操作系统采取的“分而治之”的策略基于对磁盘空间的高效和灵活抽象。这种抽象形式为“数据块”,通常大小设定为4KB。这一决策并非随意,而是经过计算机科学家的深入测试和研究得出。他们发现,以4KB作为I/O操作的基本单位,能够达到最优的性能表现。这背后支持的是一系列学术论文和研究成果。
- 此外,磁盘文件管理的设计理念还深受“局部性原理”的影响。这一理论指出,计算机在访问某些数据时,很有可能会紧接着访问其附近的数据。因此,在进行I/O操作时预加载更多数据可以显著提高操作系统的效率,并减少多次I/O操作的需求。相较于链表,顺序表因数据更集中而具有更高的缓存命中率,体现了以空间换取时间的策略。
- 在实际应用中,内存被划分为许多4KB大小的“页框”,它们是内存中的基本数据存储单位。类似地,磁盘上的文件,尤其是可执行文件,也被划分为4KB大小的“页帧”。因此,从磁盘向内存加载数据时,操作系统按照这些块进行操作,实现页帧数据向页框的加载。这不仅体现了文件系统和内存管理之间的紧密耦合,而且突显了以4KB为单位的划分的普遍适用性。
- 对于磁盘分区管理,采用相同的管理策略,通过复制和粘贴这些方法,可以轻松管理不同区域。细分区域间的管理策略亦是如此,彰显了通过细节管理控制整体空间的思路。
- 从文件类型的角度看,操作系统通过起始地址加上偏移量的方式访问数据。因此,了解一个数据块的起始地址,就可以访问到特定的数据内容。在本质上,块的地址可以视为数组索引,通过线性索引即可精确定位任何一个数据块。这种方法不仅简化了文件管理,也优化了数据访问的效率和速度。
6、创建新文件的过程
创建新文件的过程中,系统执行的关键步骤如下:
-
初始化文件属性: 当用户请求创建新文件时,操作系统内核首先查找可用的inode资源,例如本例中找到编号为263466的inode。内核会在选定的inode中填充文件的相关元数据信息,包括文件大小、权限、创建时间等属性。
-
分配并存储文件内容: 文件的实际内容需要存储在磁盘块中。假设新文件内容需占用三个连续的磁盘块,内核会分配三个空闲的磁盘块,分别为300、500和800。随后,内核将待写入文件的数据依次缓存,并逐步将缓冲区中的数据转移到对应的磁盘块中,确保第一段数据写入到300号块,紧接着是500号块,最后是800号块。
-
更新磁盘块映射: 为了维护文件内容所在的物理位置,内核在inode的磁盘块指针区域记录下这些分配的块号,形成一个有序的块列表(300、500、800),以便后续能够高效地定位和访问文件内容。
-
将文件名关联到目录项: 若要在当前工作目录下创建名为“abc”的新文件,内核会在当前目录文件的结构中添加一个新的目录项。这个目录项包含了新文件的inode编号(263466)和文件名“abc”。这样一来,就建立了文件名与inode之间的重要联系,使得系统可以根据文件名查找对应的inode,并通过inode找到相关的文件属性和内容,从而实现了文件系统的逻辑组织和数据寻址。
二、理解文件系统
1、文件的构成
在Linux系统中,文件的管理方式采取了一种区分文件内容与文件属性的策略,实现了高效和灵活的文件存储机制。这种设计将文件本身的数据(内容)与描述文件的信息(属性)分开存储,以优化访问速度和管理效率。
- 内容:即文件实际保存的数据,被存储在所谓的数据块(Data blocks)中,通常这些数据块的大小为4KB,相当于8个扇区(每个扇区512字节)。
- 属性:包括文件的大小、权限、所有者、创建和修改时间等信息,这些信息被存储在称为inode的数据结构中。每个文件都有一个唯一的inode编号,通过这个编号可以访问文件的属性信息。
2、为何选择4KB而非512字节作为基本单位?
尽管磁盘的物理存储基本单位是扇区,每个扇区通常为512字节,但Linux操作系统在与磁盘进行I/O操作时,采用了4KB(即8个扇区)作为基本单位。这一设计决策背后有几个重要的考虑因素:
-
提高效率:使用更大的单位可以减少进行I/O操作的次数,尤其是在处理大文件时,这种策略能显著提高数据的读写效率。
-
减少碎片:较大的存储单位有助于减少文件系统碎片,使得文件存储更加连续,进一步优化读写性能。
-
软硬件解耦:选择一个与磁盘扇区大小不直接相关的存储单位,使得操作系统的设计在一定程度上独立于硬件。这意味着即使磁盘技术发生变化(例如扇区大小的变动),操作系统也无需进行大幅度修改,从而保持了良好的兼容性和适应性。
3、文件系统的组成
Linux文件系统的组成包括数据块(Data blocks)、inode表(inode Table)、块位图(Block Bitmap)、inode位图(inode Bitmap)和组描述符表(GDT)。这些组件共同工作,使得文件的信息可追溯、可管理。
数据块(Data Blocks)
数据块是存储文件内容的单位,每个数据块通常大小为4KB,相当于8个扇区的大小。这种设计旨在提高读写效率,减少I/O操作次数。
inode表(inode Table)
inode表由一系列inode组成,每个inode大小为128字节,存储了文件的属性信息(如权限、大小、所有者等)。每个文件或目录在文件系统中由一个唯一的inode表示,每个inode都有一个唯一的编号。
块位图(Block Bitmap)
块位图是一个简单的位图结构,用来追踪数据块的使用情况。假设系统有10000个数据块,那么块位图就有10000个比特位,每个比特位对应一个数据块。如果比特位为1,表示对应的数据块已被占用;如果为0,则表示数据块可用。
inode位图(inode Bitmap)
inode位图与块位图类似,但用于追踪inode的分配情况。对于系统中的每个inode,inode位图都有一个对应的比特位。这个位图帮助系统快速判断哪些inode已被分配,哪些仍然可用。
块组描述符(GDT)
块组描述符记录了块组的详细信息,包括块组的大小、已使用的inode数量、剩余的inode数量、总的数据块数以及已使用的数据块数等。块组是文件系统组织数据的一种方式,有助于优化存储管理和减少碎片。
超级块(Super Block)
- bolck 和 inode的总量,
- 未使用的block和inode的数量,
- 一个block和inode的大小,
- 最近一次挂载的时间,
- 最近一次写入数据的时间,
- 最近一次检验磁盘的时间等其他文件系统的相关信息。
- Super Block的信息被破坏,可以说整个文件系统结构就被破坏了
文件与inode和数据块的关系
- 每个文件在Linux中对应一个inode节点,该inode节点包含了文件的属性信息。但是,一个文件的数据可能不仅仅存储在一个数据块中。对于较大的文件,可能需要多个数据块来存储其内容
- inode结构中有一个
blocks
数组,用于记录文件内容所在的数据块编号。这个数组不仅可以直接指向数据块,还可以指向其他块,这些块中存储的是进一步的数据块编号,从而实现对大文件的支持。
struct inode {// 文件的大小// 文件的inode编号// 其他属性int blocks[15]; // 和它同一个块组的块的编号// blocks数组中的元素指向数据块或者是指向存储数据块编号的块
};
4、目录与inode
在Linux和其他类Unix文件系统中,一个目录可以保存大量文件,但同一目录下不允许存在文件名完全相同的文件,也就是说,每个文件在该目录中的名字必须唯一。
- 目录本质上也是一种特殊的文件,它确实拥有自己的inode(索引节点)和相应的data blocks(数据块)。inode是用来记录文件元数据(如大小、权限、修改时间等)和文件内容所在数据块的位置,而数据块则是用来存储实际文件内容或目录项列表的地方。
- 当我们在目录中创建文件时,操作系统会在文件系统中分配一个新的inode,并在目录对应的data block中添加一个目录项,这个目录项包含新文件的名字以及指向该文件inode的引用。当我们进入目录、创建文件或显示文件及其属性时,正是通过目录文件找到对应的inode信息,再由inode定位到具体的文件内容。
- 换言之,inode在文件系统中是固定的标识符,它与文件名并非一一对应,而是与文件实体关联。用户通过文件名与目录中的目录项相联系,进而访问到文件的inode,而inode又指向固定的数据块。简而言之,用户看到的文件名与文件系统内部的inode编号之间存在着一种映射关系,这种关系在目录结构中起到了关键作用,确保了文件的有效组织和定位。
二、软链接和硬链接
1、概念
软链接和硬链接是在文件系统中用于创建文件之间关联的两种方式,它们之间的本质区别在于如何引用和处理文件的物理位置。
-
软链接: 软链接是一个指向目标文件的指针,类似于Windows系统中的快捷方式。软链接本身是一个独立的文件,它包含了指向目标文件的路径信息。软链接有独立的inode,因此它是一个独立的实体。如果原始文件被删除或移动,软链接仍然存在,但指向的文件可能会失效。
-
硬链接: 硬链接是直接指向存储数据块的文件系统结构,它们共享相同的inode。硬链接不是一个独立的文件,而是文件系统中相同数据块的另一个入口。因此,对于硬链接和原始文件来说,它们实际上是同一个文件的不同名称。如果原始文件被删除,硬链接仍然可以访问文件数据,因为它们共享相同的数据块。
总的来说,软链接是一个独立的文件,指向目标文件的路径,而硬链接是文件系统中同一数据块的多个入口,它们共享相同的inode。
我们通过下面例子来体会一下:
2、使用方法
在这个例子中,我们来看一下如何在Linux系统中创建软链接和硬链接。
[hbr@VM-16-9-centos DLL&SL]$ echo "hello" > testlink.txt
[hbr@VM-16-9-centos DLL&SL]$ ll
total 12
-rw-rw-r-- 1 hbr hbr 6 Mar 19 20:38 testlink.txt
[hbr@VM-16-9-centos DLL&SL]$ cat testlink.txt
hello
[hbr@VM-16-9-centos DLL&SL]$ touch testlink1.txt testlink2.txt
[hbr@VM-16-9-centos DLL&SL]$ ll
total 12
-rw-rw-r-- 1 hbr hbr 0 Mar 19 20:40 testlink1.txt
-rw-rw-r-- 1 hbr hbr 0 Mar 19 20:40 testlink2.txt
-rw-rw-r-- 1 hbr hbr 6 Mar 19 20:38 testlink.txt
- 首先创建了一个名为
testlink.txt
的文件,并向其中写入了文本"hello" - 接着创建了两个空文件
testlink1.txt
和testlink2.txt
。
[hbr@VM-16-9-centos DLL&SL]$ ln -s testlink.txt soft.link
[hbr@VM-16-9-centos DLL&SL]$ ln testlink1.txt hard.link
[hbr@VM-16-9-centos DLL&SL]$ ll -i
total 12
1183153 -rw-rw-r-- 2 hbr hbr 0 Mar 19 20:40 hard.link
1183155 lrwxrwxrwx 1 hbr hbr 12 Mar 19 20:40 soft.link -> testlink.txt
1183153 -rw-rw-r-- 2 hbr hbr 0 Mar 19 20:40 testlink1.txt
1183154 -rw-rw-r-- 1 hbr hbr 0 Mar 19 20:40 testlink2.txt
1183152 -rw-rw-r-- 1 hbr hbr 6 Mar 19 20:38 testlink.txt
-
通过执行
ln -s testlink.txt soft.link
命令,用户创建了一个指向testlink.txt
的软链接soft.link
。软链接是一个特殊类型的文件,它包含一个指向另一个文件的路径。这意味着soft.link
是对testlink.txt
的一个引用,通过它可以访问testlink.txt
的内容。 -
然后,用户执行
ln testlink1.txt hard.link
命令创建了一个硬链接hard.link
,指向testlink1.txt
。硬链接直接关联到文件的inode(文件系统中的一个索引节点),这意味着testlink1.txt
和hard.link
实际上指向同一份数据。在这个例子中,我们可以看到testlink1.txt
和hard.link
有相同的inode号(1183153),这确认了它们是彼此的硬链接。 -
使用
ll -i
命令(显示文件inode信息),可以看到文件和链接的详细信息。soft.link
显示为一个指向testlink.txt
的软链接,而hard.link
和testlink1.txt
共享相同的inode号,表明它们是硬链接。
使用unlink删除软硬链接。
[hbr@VM-16-9-centos DLL&SL]$ unlink soft.link
[hbr@VM-16-9-centos DLL&SL]$ unlink hard.link
[hbr@VM-16-9-centos DLL&SL]$ ll -i
total 8
1183154 -rw-rw-r-- 1 hbr hbr 0 Mar 19 20:40 testlink2.txt
1183152 -rw-rw-r-- 1 hbr hbr 6 Mar 19 20:38 testlink.txt
3、软链接相当于快捷方式
在bin/exe目录下有一个可执行程序myexe,如果我们想要运行它每次都需要带上路径,这样比较麻烦。
[hbr@VM-16-9-centos DLL&SL]$ tree bin
bin
└── exe└── myexe1 directory, 1 file
[hbr@VM-16-9-centos DLL&SL]$ ./bin/exe/myexe
hello
hello
hello
hello
hello
我们可以创建一个myexe同名的动态链接,这次直接在当前目录运行myexe即可,这个软连接就相当于Windows的快捷方式。
[hbr@VM-16-9-centos DLL&SL]$ ln -s bin/exe/myexe myexe
[hbr@VM-16-9-centos DLL&SL]$ ll
total 8
drwxrwxr-x 3 hbr hbr 4096 Mar 19 20:58 bin
lrwxrwxrwx 1 hbr hbr 13 Mar 19 21:02 myexe -> bin/exe/myexe
[hbr@VM-16-9-centos DLL&SL]$ ./myexe
hello
hello
hello
hello
hello
4、硬链接相当于起别名
当我们删掉硬链接所链接的源文件,这并不影响文件本身,因为硬链接的inode与源文件是相同的,而且观察hard.link属性第三列由2变为1,这个属性就是硬链接数,也就是只要有人使用这个inode,那么这个文件就一直存在,那文件被删除是什么状态呢?我们通过下面inode的讲解就知道了。
[hbr@VM-16-9-centos DLL&SL]$ ll -i
total 8
1183159 drwxrwxr-x 3 hbr hbr 4096 Mar 19 20:58 bin
1183153 -rw-rw-r-- 2 hbr hbr 0 Mar 19 20:40 hard.link
1183144 lrwxrwxrwx 1 hbr hbr 13 Mar 19 21:02 myexe -> bin/exe/myexe
1183155 lrwxrwxrwx 1 hbr hbr 12 Mar 19 20:40 soft.link -> testlink.txt
1183153 -rw-rw-r-- 2 hbr hbr 0 Mar 19 20:40 testlink1.txt
1183154 -rw-rw-r-- 1 hbr hbr 0 Mar 19 20:40 testlink2.txt
1183152 -rw-rw-r-- 1 hbr hbr 6 Mar 19 20:38 testlink.txt
[hbr@VM-16-9-centos DLL&SL]$ rm testlink1.txt
[hbr@VM-16-9-centos DLL&SL]$ ll -i
total 8
1183159 drwxrwxr-x 3 hbr hbr 4096 Mar 19 20:58 bin
1183153 -rw-rw-r-- 1 hbr hbr 0 Mar 19 20:40 hard.link
1183144 lrwxrwxrwx 1 hbr hbr 13 Mar 19 21:02 myexe -> bin/exe/myexe
1183155 lrwxrwxrwx 1 hbr hbr 12 Mar 19 20:40 soft.link -> testlink.txt
1183154 -rw-rw-r-- 1 hbr hbr 0 Mar 19 20:40 testlink2.txt
1183152 -rw-rw-r-- 1 hbr hbr 6 Mar 19 20:38 testlink.txt
5、引用计数
文件删除与inode的关系
创建硬链接时,实际上并没有真正创建新的文件,而是在指定的目录下建立了文件名和指定inode的映射关系。这意味着硬链接与原始文件共享相同的inode和数据块,它们只是文件系统中相同数据的不同入口。
- 在文件属性中,会有一个数字表示硬链接的数量,这个数字也被称为引用计数。
- 引用计数的作用是跟踪有多少个文件名与同一个inode相关联。
- 当我们删除一个文件时,并不是立即删除这个文件的inode,而是将这个文件的inode引用计数减少。
- 只有当引用计数减少到0时,文件的inode才会被真正删除,这意味着没有文件名与该inode相关联,也就是没有用户关心这个文件了。
通过引用计数,系统可以有效地管理文件的关联关系,确保在没有任何文件名与文件关联时才真正删除文件的数据块和inode,从而避免意外删除或数据丢失的情况。
目录的引用计数
在Linux和其他类Unix文件系统中,每个目录都有至少两个硬链接。这是因为文件系统设计的一个基本原则。
[hbr@VM-16-9-centos DLL&SL]$ mkdir dir
[hbr@VM-16-9-centos DLL&SL]$ ll
total 1
drwxrwxr-x 2 hbr hbr 4096 Mar 19 21:25 dir
-
指向自己的硬链接: 每个目录都有一个指向自身的硬链接。当你在文件系统中创建一个新的目录时,它会自动地包含一个对该目录本身的引用,也就是其inode(索引节点)计数加1。这个内部的自我引用是必要的,因为它确保了目录即使在其父目录的链接数减少到1时(比如父目录内除了
.
和..
之外没有其他条目引用它时),也不会被删除,因为至少还有一个硬链接(即它自己)在引用它。 -
"." (当前目录自身的引用):这是目录自身的一个硬链接。每个目录都有这样一个链接,指向自己,因此计数至少为1。
指向其父目录的硬链接: 同时,每个目录中都有两个特殊的条目,.
(点)和..
(双点)。.
指向当前目录自身,而..
指向其父目录。这里的..
其实就是一个硬链接,它增加了父目录的硬链接计数。这样,每当有一个新的子目录创建在某个目录下时,那个父目录的硬链接数就会增加1,因为子目录中的..
相当于对其父目录的硬链接。
我们可以通过目录的引用计数减2得到目录的文件数,我们来分析下面目录和文件的引用计数:
[hbr@VM-16-9-centos DLL&SL]$ ll -ai
total 16
1183143 drwxrwxr-x 4 hbr hbr 4096 Mar 19 21:25 .789117 drwxrwxr-x 10 hbr hbr 4096 Mar 19 20:30 ..
1183159 drwxrwxr-x 3 hbr hbr 4096 Mar 19 20:58 bin
1183153 drwxrwxr-x 2 hbr hbr 4096 Mar 19 21:25 dir
1183144 lrwxrwxrwx 1 hbr hbr 13 Mar 19 21:02 myexe -> bin/exe/myexe
1183152 -rw-rw-r-- 1 hbr hbr 0 Mar 19 21:24 test.c
[hbr@VM-16-9-centos DLL&SL]$ tree
.
├── bin
│ └── exe
│ └── myexe
├── dir
├── myexe -> bin/exe/myexe
└── test.c3 directories, 3 files
-
.
(当前目录):引用计数为4。这是因为在Linux系统中,每个目录都包含一个指向自身的硬链接,同时还有一个指向其父目录的硬链接(即".."),以及在文件系统中myexe的两个标准硬链接。所以总共有4个硬链接指向当前目录。 -
..
(父目录):引用计数为10。这是因为在父目录中有10个子目录,每个子目录都包含一个指向父目录的硬链接(即".."),所以引用计数为10。 -
bin
(目录):引用计数为3。这是因为当前目录中有一个指向该目录的硬链接(即"dir"),另外一个是指向它的父目录(即".."),以及在文件系统中的一个标准硬链接。 -
dir
(目录):引用计数为2。这是因为当前目录中有一个指向该目录的硬链接(即"dir"自身),另外一个是指向它的父目录(即"..")。 -
myexe
(符号链接):引用计数为1。因为它只是一个指向另一个文件的符号链接,没有额外的硬链接。 -
test.c
(文件):引用计数为1。因为它是一个普通文件,没有其他硬链接指向它。
6、总结
总结软硬链接的区别:
-
软链接(Symbolic Link):
- 类似于Windows系统中的快捷方式。
- 包含目标文件的路径信息。
- 可以跨文件系统链接文件。
- 指向文件或目录。
- 如果原文件被删除,软链接将失效。
-
硬链接(Hard Link):
- 指向文件系统中的inode,和原始文件共享相同的数据块。
- 不能跨文件系统。
- 不能链接目录,只能链接文件。
- 如果原文件被删除,任何指向同一inode的硬链接仍然可以访问文件内容,直到所有的硬链接都被删除。