【Linux学习】磁盘结构与寻址原理&EXT2文件系统&inode&软硬链接

目录

十.磁盘结构与原理

        10.1 内存文件与磁盘文件

        10.2 存储和硬盘

        10.2.1 存储

        10.2.2 硬盘(固态硬盘vs机械硬盘)

        10.3 磁盘的结构

        10.4 磁盘的工作原理

        10.5 磁盘的寻址

        CHS寻址(物理寻址方式):

        LBA寻址(逻辑寻址方式):

        CHS与LBA之间的可以相互转换:

        采用LBA而不用CHS的原因:

十一:文件系统

        11.1 磁盘分区与格式化介绍

        磁盘分区(Disk Partitioning):

        格式化(Formatting):

        11.2 EXT2文件系统

        11.3 inode 

        inode 在哪里:

        inode 是什么:

        文件属性存储: 

        文件内容存储: 

        文件名和 inode 编号的关系:

        inode number:

        11.4 创建和删除文件,OS做了什么?

十二.软硬链接

        12.1 软链接(Symbolic Link)

        12.2 硬链接(Hard Link)


十.磁盘结构与原理

        10.1 内存文件与磁盘文件

文件=文件内容+文件属性

1.内存文件(struct file 结构体)
在 Linux 中,为了管理打开的文件,系统使用 struct file 结构体来描述每个打开的文件。这些 struct file 结构体通过双链表的形式组织在一起,以方便系统追踪和管理。每个 struct file 结构体代表一个打开的文件,包含了文件的一些元数据和操作函数指针。
内存中的表示: 内存文件是指在进程运行时,文件的部分或全部内容被加载到内存中,形成 struct file 数据结构。这种方式是为了提高文件的访问速度,因为在内存中的文件可以更快地被读取和写入。

延后加载数据: 内存文件采用延迟加载数据的方式,实际的文件内容并不一开始就全部加载到内存中,而是在进行文件操作(读取或写入)时才将相应的数据加载到内存。

2.磁盘文件

磁盘文件指的是文件在物理磁盘上的存储形式。
加载到内存: 当一个文件被打开时,系统会创建一个对应的 struct file 结构体,将文件的属性信息加载到内存中,形成内存文件。这样,内存文件中包含了文件的一些元数据,以及指向文件操作函数的指针。

总的来说,内存文件和磁盘文件分别代表了文件在内存中的表示和在磁盘上的物理存储。在文件被打开时,系统会同时维护这两份文件的信息,通过 struct file 结构体来处理内存文件,而磁盘文件则是文件在物理存储介质上的持久化表示。

        10.2 存储和硬盘

10.2.1 存储

存储是计算机系统中用于保存和访问数据的关键组件。在计算机系统中,存储通常分为内存和外存两类。
内存(RAM):
        1.临时存储: 内存是计算机用于临时存储数据和程序的地方。当计算机启动或运行程序时,相关的数据和代码会被加载到内存中以提高访问速度。
        2.易失性: 内存是易失性的,也就是说,当计算机断电或重新启动时,内存中的数据就会丢失。因此,内存主要用于临时存储
速度快: 内存的读写速度非常快,允许计算机迅速访问存储在其中的数据。
容量相对较小: 内存的容量通常相对较小,以确保数据可以迅速读取。
外存(存储器):
        1.长期存储: 外存用于长期存储数据,例如硬盘驱动器(HDD)、固态硬盘(SSD)、光盘等。数据在外存中不会因为断电而丢失。
        2.长期保存数据和程序: 与内存不同,外存是非易失性的,即使计算机断电,数据也会保持在存储设备上
        3.速度较慢: 外存的读写速度相对较慢,与内存相比,访问外存中的数据需要更多的时间。
容量较大: 存储器通常具有较大的存储容量,允许长期保存大量的数据、应用程序和操作系统。
        4.成本较低: 相对于内存,外存的存储成本较低


在计算机系统中,内存和外存通常协同工作。程序和数据首先从外存加载到内存中,计算机在内存中进行操作,而结果则可能被保存回外存以长期存储。这种分工使得计算机系统更加灵活和高效。

10.2.2 硬盘(固态硬盘vs机械硬盘)

硬盘属于外存,是计算机系统中用于长期存储数据的一种存储设备。硬盘有两种主要类型:机械硬盘驱动器(HDD)和固态硬盘(SSD)

固态硬盘(SSD):

SSD的特点

  • 使用flash技术存储信息,数据传输速度比HDD快
  • 内部没有机械结构因此耗电量更小、散热小、噪音小
  • SSD盘使用寿命受擦写次数影响(硬盘最小组成单元Cell不断擦写,当擦写次数达到极限后,就不能继续读写数据了)
  • 存储成本高

SSD架构

SSD主要是由存储单元(主要是闪存颗粒)和控制单元组成

机械硬盘(磁盘)(HDD):

 HDD的特点:

  1. 机械结构: HDD内部包含旋转的磁性盘片,数据通过机械臂和磁头进行读写。这种机械结构是HDD与SSD最显著的不同之一。

  2. 相对较慢的读写速度: 由于涉及机械运动,HDD的读写速度相对较慢。随着机械臂移动到正确的磁道和盘片旋转到正确的位置,访问数据会有一定的延迟。

  3. 较低的存储成本: 相对于SSD,HDD的存储成本通常较低,提供更大的存储容量,适合长期存储大量数据的应用场景。

  4. 适用于大容量存储: 由于相对较低的成本和较大的容量,HDD常用于需要大容量存储的场景,如文件存储、备份等。

  5. 不受擦写次数限制: 与SSD不同,HDD没有像擦写次数这样的使用寿命限制,可以进行大量的读写操作而不太容易损坏。

        10.3 磁盘的结构

机械硬盘(HDD)的结构包含几个关键的组件,这些组件共同协作以实现数据的读写。以下是机械硬盘的主要结构的介绍:

1. 磁性盘片(Platter):

  • 描述: 机械硬盘通常包含多个磁性盘片,它们是圆形的金属或玻璃碟片,覆盖有磁性涂层。

  • 作用: 数据通过在盘片表面上的磁性颗粒的变化来进行存储。每个盘片都被划分为一系列的同心圆磁道。

2. 磁头(Read/Write Head):

  • 描述: 磁头是一组微小的电磁臂,悬浮在盘片的表面上。

  • 作用: 磁头用于读取和写入数据。当盘片旋转时,磁头通过测量磁性颗粒的变化来读取或改变磁性颗粒的方向来写入数据。

3. 磁头臂(Actuator Arm):

  • 描述: 磁头臂是支撑磁头的机械结构,可以在水平方向上移动。

  • 作用: 控制磁头的位置,使其能够访问不同磁道上的数据。移动磁头臂是机械硬盘中的一项关键操作。

4. 主轴电动机(Spindle Motor):

  • 描述: 主轴电动机用于旋转磁性盘片,通常以高速旋转。

  • 作用: 使盘片在磁头上方以高速旋转,以便读取和写入数据。盘片的旋转速度通常以每分钟转数(RPM)来衡量。

5. 控制电路和控制器(Controller):

  • 描述: 控制电路和控制器位于硬盘内部,负责管理硬盘的整体运作。

  • 作用: 包括数据缓存、错误检测和纠正、以及与计算机系统进行通信的功能。控制器通过磁头臂的移动和盘片的旋转来确保磁头能够正确地访问所需的数据。

 

        10.4 磁盘的工作原理

盘面上一个个同心圆便是磁道,每个同心圆被划分的一小段区域叫做扇区扇区是磁盘存储的基本单位。多个盘面半径相同(一个磁盘有多个盘面)的同心圆连起来叫做柱面。

每个扇区的大小是512K字节,所以内磁道的扇区密度高,外磁道的扇区密度低。

每个盘片的表面被涂覆上一层磁性材料。这个材料通常是氧化铁(iron oxide),被称为磁性材料。这些材料可以在磁场的作用下被磁化,形成磁性区域,代表数字数据的0和1。

读/写磁头是通过电磁感应原理来感知和改变盘片表面的磁性。当电流通过磁头时,它产生一个磁场,这个磁场与盘片表面的磁场相互作用。根据这个交互作用,磁头可以感知或改变盘片表面上的磁性,从而读取或写入数据。

数字数据在硬盘上以二进制形式存储,通过在盘片表面的不同区域改变磁性的方向来表示0和1。这些磁性变化可以被读/写磁头读取,进而被计算机系统解释为存储的数据。

        10.5 磁盘的寻址

                                  那么在物理上,如何把数据写入指定的扇区呢?

CHS寻址(物理寻址方式):

CHS(Cylinder-Head-Sector)寻址是一种早期的磁盘寻址方式,通过指定柱面(Cylinder)、磁头(Head)和扇区(Sector)的组合来定位磁盘上的数据

通过指定柱面、磁头和扇区的组合,可以唯一地定位磁盘上的一个数据块。CHS地址通常表示为 C:H:S,其中 C 是柱面号,H 是磁头号,S 是扇区号。

使用CHS寻址时,读写数据的过程通常涉及以下步骤:

  1. Seek(寻道): 磁头移动到指定柱面。

  2. Rotational Delay(旋转延迟): 等待磁盘旋转,使所需扇区位于磁头下方。

  3. Read/Write(读/写): 执行实际的读取或写入操作。

CHS寻址方式随着硬盘容量的增加变得不够灵活,因为它难以有效地表示大量的柱面、磁头和扇区。随着技术的发展,LBA(Logical Block Addressing)逐渐取代了CHS成为更为普遍的寻址方式。

这样一来,我们就可以定位任意一个扇区,然后进行读写数据。比如,0号磁头,0号柱面,0号扇区,此时,磁头就会摆动到0号柱面处,当0号磁头对应的盘面中的0号磁道里的0号扇区旋转到磁头位置时,就可以向磁盘中读写数据。


磁盘抽象(逻辑,虚拟)结构:

我们小时候应该见过磁带吧,那种一拉很长的那种,那时候英语听力基本用一个录音机,然后放上磁带,练习英语听力,就像下面这样:

每个磁面上都有多个磁道,每个磁道上有多个扇区,类比磁带,扇区就可以看成一圈一圈缠绕在一起的

一个磁带原本物理结构是圆形结构,我们可以把它拉出来,相当于抽象成了一种线性结构

我们可以把这个卷起来的磁带想象成磁盘的盘片,然后把磁盘的盘面抽象成一种线性结构!

 

LBA寻址(逻辑寻址方式):

LBA(Logical Block Addressing)寻址是一种现代磁盘寻址方式,与CHS(Cylinder-Head-Sector)相比更为直观和简单。LBA使用逻辑块地址来唯一标识磁盘上的数据块,而不再需要指定柱面、磁头和扇区的具体位置。

关键点和步骤如下:

  1. 逻辑块: 磁盘被看作是一个逻辑块的连续序列,每个逻辑块都有一个唯一的逻辑块地址(LBA)。逻辑块是数据的最小单元,通常表示为连续的扇区。

  2. 地址计算: LBA地址是一个线性的、简单的地址。计算LBA地址的公式通常是 LBA=(C×HPC+H)×SPT+(S−1),其中 C 是柱面号,HPC 是每个柱面的磁头数,H 是磁头号,SPT 是每个磁道的扇区数,S 是扇区号。

    这个公式将CHS地址转换为LBA地址,以便更容易地进行线性寻址。

  3. 读写操作: 操作系统或硬盘控制器使用LBA地址进行读写磁盘上的数据块。这样的寻址方式对应用程序和操作系统来说更为简便,因为不再需要关注磁盘的物理结构。

LBA寻址的优势在于它提供了一种更灵活、更简单的方式来访问磁盘上的数据,而无需考虑磁盘的几何结构。这使得LBA成为现代计算机系统中主流的磁盘寻址方式。

CHS与LBA之间的可以相互转换:

以下是一个简化的LBA到CHS的转换公式。请注意,这里的转换并非唯一确定,实际上有多种转换算法,具体实现取决于硬盘的物理结构:

C = ⌊ LBA / (HPC × SPT) ⌋

H = ⌊ (LBA mod (HPC × SPT)) / SPT ⌋

S = (LBA mod SPT) + 1

其中:

  • C 表示柱面号(Cylinder)
  • HPC 表示每个柱面的磁头数(Heads Per Cylinder)
  • H 表示磁头号(Head)
  • SPT 表示每个磁道的扇区数(Sectors Per Track)
  • S 表示扇区号(Sector)
  • ⌊ ⌋ 表示向下取整函数

采用LBA而不用CHS的原因:

  1. 便于管理: LBA提供了一种更为直观和简单的方式来寻址磁盘上的数据块。通过使用线性逻辑块地址,LBA简化了对磁盘空间的管理,而无需考虑柱面、磁头和扇区的具体位置。这种管理方式使得操作系统能够更高效地组织和利用磁盘空间。

  2. 数组管理方便且高效: LBA将磁盘视为一个连续的逻辑块序列,类似于一个数组。这种线性结构使得对磁盘的管理更为方便和高效。逻辑块之间的顺序关系更为清晰,简化了数据的组织和寻址。

  3. 减少操作系统与硬件的耦合: 使用LBA降低了操作系统与硬件之间的耦合度。CHS依赖于磁盘的物理几何结构,这使得操作系统必须更深入地了解硬件的细节。而LBA提供了一种抽象的方式,允许操作系统更专注于高级的文件系统和数据管理,而不需要深入理解底层硬件的物理结构。

十一:文件系统

        11.1 磁盘分区与格式化介绍

磁盘分区(Disk Partitioning):

  • 定义: 磁盘分区是将一个物理硬盘分割成若干个逻辑部分的过程。每个分区在逻辑上看起来就像是一个独立的硬盘,有自己的文件系统、目录结构和存储空间。
  • 目的: 磁盘分区的主要目的是将一个大的硬盘划分成多个小的逻辑单元,这样可以更有效地管理数据和操作系统。每个分区可以被用于不同的目的,例如安装操作系统、存储用户数据、备份等。

磁盘通常被称为块设备,一般以扇区为单位,一个扇区的大小通常为512字节。我们若以大小为512G的磁盘为例,该磁盘就可被分为十亿多个扇区。

  • 为了提高效率,磁头每次访问磁盘的基本单位是4KB(绝大多数情况下)。即使访问磁盘的一个bit,磁头也是将包过这一个bit在内的周围4KB大小的数据加载到内存
  • 页面(Page): 这是虚拟地址空间中的一个固定大小的块,通常是4KB。进程的虚拟地址空间被划分为页面,每个页面可以映射到物理内存中的一个页框。

  • 页框(Page Frame): 这是物理内存中的一个与页面大小相对应的块。操作系统将物理内存划分为一系列的页框,每个页框与虚拟内存中的页面相对应。

虽然磁盘的基本单位是扇区(512字节),但是操作系统(文件系统)和磁盘进行IO的基本单位是4KB(8*512字节).

也就是说,就算OS想从磁盘中读取一个字节的数据,那么最少也必须读取4KB的数据。至于为什么是4KB,这是一种经过精心考虑的折衷选择。较小的块大小可能会导致更多的 I/O 操作,增加寻址和传输的开销,而较大的块大小可能会导致浪费,特别是在处理小文件时。4KB 的大小在绝大多数情况下被认为是一种平衡,适用于各种工作负载。

如果操作系统与磁盘 I/O 的基本单位一致,并且硬件发生变化,可能需要调整操作系统的源代码以适应新的硬件结构。通过使用独立于硬件的块大小,可以更容易地适应硬件变化,而无需修改操作系统的源代码。这样就完成了软件和硬件的解耦

计算机为了更好的管理磁盘,于是对磁盘进行了分区。磁盘分区就是使用分区编辑器在磁盘上划分几个逻辑部分,盘片一旦划分成数个分区,不同的目录与文件就可以存储进不同的分区,分区越多,就可以将文件的性质区分得越细,按照更为细分的性质,存储在不同的地方以管理文件,例如在Windows下磁盘一般被分为C盘和D盘两个区域。

在Linux操作系统中,我们也可以通过以下命令查看我们磁盘的分区信息:

ls /dev/vda* -l


格式化(Formatting):

  • 定义: 格式化是在分区上创建文件系统的过程,它为分区提供了一种组织数据的结构,使得操作系统能够正确地读取和写入数据。
  • 目的: 格式化的主要目的是为分区准备文件系统,以便于存储和检索文件。不同的操作系统使用不同的文件系统,例如Windows使用NTFS或FAT32,Linux使用ext4等。格式化会在分区上创建文件目录、文件表和其他必要的数据结构。

当磁盘完成分区后,我们还需要对磁盘进行格式化。磁盘格式化就是对磁盘中的分区进行初始化的一种操作,这种操作通常会导致现有的磁盘或分区中所有的文件被清除。
简单来说,磁盘格式化就是对分区后的各个区域写入对应的管理信息。

其中,写入的管理信息是什么是由文件系统决定的,不同的文件系统格式化时写入的管理信息是不同的,常见的文件系统有EXT2、EXT3、XFS、NTFS等。

        11.2 EXT2文件系统

   ext2(Extended File System 2)是 Linux 系统中使用的一种文件系统,是 Linux 文件系统家族的一部分,虽然在现代 Linux 系统中使用得相对较少,但在一些特殊场景和嵌入式系统中仍然可能被选用

  1. Boot Block(引导块):是文件系统中的一个区域,通常位于文件系统的开头,用于存储引导加载程序(Boot Loader)。引导加载程序是计算机在启动时加载操作系统的程序,它从引导块读取必要的信息,然后将控制权传递给操作系统的内核。

  2. Block Group(块组):ext2文件系统会根据分区的大小划分为数个Block Group。而每个Block Group都有着相同的结构组成。

  3. Super Block (超级块):存放文件系统本身的结构信息。记录的信息主要有:bolck 和 inode的总量, 未使用的block和inode的数量,一个block和inode的大小,最近一次挂载的时间,最近一次写入数据的 时间,最近一次检验磁盘的时间等其他文件系统的相关信息。(Super Block的信息被破坏,可以说整个 文件系统结构就被破坏了)

  4. GDT(Group Descriptor Table) (块组描述符):存储了每个块组的关键信息,包括块组的起始块、块位图和 inode 位图的块号、块组中的空闲块和 inode 数量等。

  5. Block Bitmap(块位图):它的每一个比特位和特定的block是一一对应的,对应的bit位位1, 表示该block已经被占用,否则表示空闲可用。通过块位图,操作系统可以快速了解文件系统上哪些块是可用的,从而进行块的分配和释放。当需要分配一个块给新的文件或目录时,操作系统会查找位图中的空闲位,并将其设置为已分配状态,然后返回该块的地址 给请求的进程。

  6. inode Bitmap(inode位图):它的内部也是一个位图,每一个比特位和 特定的inode是一一对应的,如果该比特位为1,说明该inode已经被占用,否则表示空闲可用。

    假设有10000+的inode,那么就有10000+的比特位,分别一一对应,然后用0和1表示未被占用和已占用的两种状态.

  7. Inode Table(i节点表): 该块组内,所有文件的inode集合,在ext2文件系统中,每个文件都有一个对应的 Inode,用于存储文件的元数据信息
     

  8. Data block (数据区):数据区存储了实际的文件内容,包括文件数据块、目录数据块等 ,每个块组都有自己的数据区

在 ext2 文件系统中,块组(Block Group)的大小并没有硬性的统一规定,它是在创建文件系统时根据文件系统总大小等因素动态计算的。因此,每个块组的大小可以根据文件系统的配置而异。

在创建 ext2 文件系统时,你可以通过指定块组的大小来影响文件系统的结构。这个大小通常是以块为单位的,可以通过mke2fs 命令的 -g 参数来设置。例如:

mke2fs -g block_group_size /dev/sdX

其中block_group_size 是你指定的块组的大小,而 /dev/sdX 是目标分区的路径。

选择块组的大小时,通常需要权衡一些因素,包括文件系统的性能、磁盘空间的利用效率以及对碎片化的影响。较小的块组可能会导致更高的文件系统性能,但可能会浪费一些磁盘空间。较大的块组可以更有效地利用磁盘空间,但可能导致碎片化问题。

        11.3 inode 

inode 在哪里:

  • inode  存储在文件系统的 Inode Table 中,用于存储文件或目录的元数据。
  • file 结构体存储在操作系统内核中,用于表示打开文件的状态,其中包含指向文件的 inode 的指针。

inode 是什么:

inode是文件系统中的一个数据结构,用于存储文件或目录的元数据信息,而不包含实际的文件内容。在类Unix文件系统(如ext2, ext3, ext4等)中,每个文件或目录都有一个对应的 inode 来描述其属性和状态。

文件 = 属性 + 内容,所以在磁盘上管理一个文件,也要管理它的属性和内容,而文件的属性就放在一个叫inode的结构体中,文件的内容就放在数据块中。

每个 inode 记录了文件的各种属性,包括但不限于:

  1. 文件类型: 指示该 inode 所关联的文件是普通文件、目录、符号链接等类型。
  2. 文件权限: 包括文件所有者、所属组和其他用户的读、写、执行权限。
  3. 文件大小: 记录文件的大小,对于目录来说,它通常是固定的。
  4. 时间戳: 记录文件的创建时间、最后修改时间和最后访问时间。
  5. 链接计数: 记录有多少硬链接指向这个 inode。
  6. 数据块指针: 指向存储文件实际内容的数据块的指针。

文件属性存储: 

struct ext2_inode {
    __le16  i_mode;         // 文件类型和访问权限
    __le16  i_uid;          // 文件所有者的用户ID
    __le32  i_size;         // 文件大小(字节)
    __le32  i_atime;        // 最后访问时间
    __le32  i_block[15];    // 存储文件数据块的位置信息
    // ... 其他 inode 字段 ...
};

文件内容存储: 

文件的内存就存储在这个Data blocks中,而这个块区中又有多个数据块,并且有相应的编号。

现在属性被存放好了,内容也被存放好了,下面就是将一个文件的属性和内容对应起来。

这时,inode结构体中的i_block[15]就是干这个事情的。

 数组中每个元素存放着一个一个数据块的block id(编号)。每个数据块中存放着内容数据。

这个数组一共才能放15个编号,如果这个文件的内容有很多呢,需要很多的数据块(超出了15个)呢?

在 EXT2 文件系统中,inode结构体中的i_block数组确实用于存储文件的数据块的位置信息。然而,前 12 个元素用于直接存储数据块的块号,而剩余的 3 个元素用于间接块的情况。

  • 直接块(Direct Blocks): i_block[0] 到 i_block[11] 中的每个元素都存储一个直接数据块的块号。这些直接块直接包含文件的内容数据。
  • 一次间接块(Indirect Block): i_block[12] 存储一个间接块的块号,该块中包含了一组额外的数据块的块号。这个间接块可以被视为一个指针数组,其中每个指针指向一个数据块。
  • 二次间接块(Double Indirect Block): i_block[13] 存储一个二次间接块的块号,该块中包含一组指向一组间接块的指针。每个间接块又包含一组指向数据块的指针。
  • 三次间接块(Triple Indirect Block): i_block[14] 存储一个三次间接块的块号,该块中包含一组指向一组二次间接块的指针。每个二次间接块包含一组指向一组间接块的指针,最终每个间接块包含一组指向数据块的指针。

虽然一个数组中的一个元素只能存放一个数据块的下标,但是指向的数据块中可以存放多个数据块的下标,这样一来,大文件也能存放的下了。


 这些信息使得操作系统能够快速访问和管理文件的元数据,而不必每次都读取整个文件。当你创建一个文件或目录时,文件系统会分配一个新的 inode 并为其分配一个唯一的 inode 号。该 inode 号在文件系统内部是唯一的,与文件路径无关。

需要注意的是,inode 不包含文件实际的数据内容,而是存储有关文件的属性和位置信息。文件的实际数据存储在由 inode 中的数据块指针引导的数据块中。

在文件系统中,inode 的使用允许系统更高效地管理文件和目录,提高对文件元数据的访问速度。


文件名和 inode 编号的关系:

在 Linux 文件系统中,目录是一种特殊的文件,它包含了文件名到 inode 编号的映射关系。目录中的数据块存储了这些映射,以便系统能够根据文件名找到相应的 inode,从而获取文件的元数据和内容。

  1. 目录数据块中的映射: 目录的数据块中存储了文件名与 inode 编号之间的映射。这个映射关系表达了在特定目录下,每个文件名对应的 inode 编号。在同一个目录下,可以保存很多的文件,但是文件名不能重复

  2. 创建文件时的过程: 当你在目录中创建一个新文件时,系统会在目录的数据块中添加一个新的条目,将新文件的文件名与其分配的 inode 编号建立映射关系。目录里的data block 存储的是inode 编号 和 文件名的映射关系.它们互为key值的,也就是说即可用inode编号做key值,也可以用文件名做key值.

  3. 读取文件时的过程: 当你试图访问一个文件时,系统首先通过目录中的映射关系找到文件名对应的 inode 编号,然后根据这个 inode 编号去找到文件的元数据和内容。

  4. 目录权限的重要性: 所以说为什么创建文件需要目录有写权限,是因为目录保存的是文件名与 inode编号映射关系,只有目录有了写权限,才能将这个映射关系写到磁盘,才能创建成功. 

总体而言,目录的数据块中存储的映射关系是文件系统管理文件名和 inode 编号之间联系的关键,确保系统可以根据文件名迅速定位到相应的 inode。


inode number:

在文件系统中,每个文件都与一个唯一的标识符相关联,该标识符称为inode号码(inode number)。每个inode包含有关文件的元数据,如文件大小、权限、拥有者等。而inode号码就是用来唯一标识文件系统中的每个inode的数字。

在Linux中我们可以使用下面这个命令,来显示目录中文件的详细信息,包括它们的inode号码

ll -i

具体而言,inode号码是一个非负整数,用于在文件系统内部唯一标识一个inode。当你在文件系统上创建新文件时,操作系统会为该文件分配一个空闲的inode,并为该inode分配一个唯一的inode号码。这个inode号码是在整个文件系统内部是唯一的

通过inode号码,操作系统可以快速地找到文件的元数据信息,包括文件的物理位置、大小、权限等。当你执行文件操作时(例如打开、读取、写入文件),操作系统使用文件路径和inode号码来查找和管理文件。

总的来说,inode号码是文件系统内部用来标识和管理文件的一种标识符,与用户使用的文件名是分开的。不同的文件可以有相同的文件名(不同的目录中),但它们具有不同的inode号码。

        11.4 创建和删除文件,OS做了什么?

创建文件:

  1. 分配inode:操作系统首先需要分配一个空闲的inode来表示新创建的文件。在inode位图中找到一个空闲的位(表示一个inode是否被使用),将其标记为已使用,并返回相应的inode号码。

  2. 为文件分配数据块: 操作系统会为文件分配磁盘上的数据块来存储文件的实际内容。这可能涉及到分配一个或多个数据块,具体取决于文件的大小。

  3. 初始化inode和数据块: 一旦inode和数据块被分配,文件系统会初始化inode的相关信息,例如文件大小、访问权限等。同时,文件系统还会初始化数据块,将它们标记为已分配并清零以确保数据的干净状态。

  4. 更新目录项: 操作系统会在文件所在目录的data blocks中创建一个新的项,将文件名与分配的inode关联起来。这样,文件系统就能够通过目录来找到文件的inode。

删除文件:

  1. 根据文件名和inode的映射关系,找到文件对应的inode: 文件系统通过文件名找到对应的inode,其中存储了文件的元数据信息。

  2. 根据inode找到数据块所对应的Blocks Bitmap,将对应位清0: 通过文件的inode,文件系统找到与该文件相关的数据块位图(Blocks Bitmap)。数据块位图用于跟踪磁盘上哪些数据块已经被分配。在文件删除过程中,相应的位会被清零,表示这些数据块现在是空闲的。

  3. 将inode对应的inode Bitmap清0: 同样,文件系统会找到inode位图(Inode Bitmap),将与被删除文件对应的inode的位清零,标志着该inode现在是未使用的

文件的删除并不会去清理磁盘上数据块中的内容,只是将对应的位图清0,后续再来的内容进行覆盖就可以。这也是为什么拷贝一个文件比较慢,但是删除一个文件很快的原因。

 当你误删一个文件的时候,最好的做法就是什么都不要做,只要对应的inode和data blocks没有被覆盖,这个文件时可以恢复的。

十二.软硬链接

软链接(符号链接)和硬链接是文件系统中两种不同类型的链接方式,它们用于在文件系统中创建文件之间的关联。

        12.1 软链接(Symbolic Link)

软链接(Symbolic Link),也被称为符号链接,是文件系统中的一种特殊文件类型,用于创建文件之间的符号性链接。软链接是一个独立的文件,它包含了指向另一个文件或目录的路径。

当访问软链接时,实际上是通过路径引导来访问目标文件或目录。软链接可以跨越文件系统边界,在不同的位置创建链接。

创建软链接:

使用 ln -s 命令可以创建软链接。语法如下:

ln -s 目标文件(被链接的文件) 软链接的文件

软链接就类似于Windows操作系统当中的快捷方式 :

比如说Windows桌面上的微信图标,这个微信其实就是一个软链接的文件,然后我们右击微信,然后点击属性: 

便可以发现源文件其实在和这个桌面毫不相干的一个地方存着,而桌面上的这个微信其实是它的一个软链接,即快捷方式。 

软链接有自己的 inode:

 通过ll -i命令我们可以看到,软链接文件的inode号与源文件的inode号是不同的,也就是说软链接是一个独立的文件,有自己的 inode 和数据块

        12.2 硬链接(Hard Link)

硬链接(Hard Link)是文件系统中的一种链接方式,它允许一个文件拥有多个有效的文件名,这些文件名指向相同的 inode 号码。硬链接实际上是文件系统中相同文件的不同名称。

创建硬链接:

使用ln命令可以创建硬链接。语法如下:

ln  目标文件(被链接的文件) 软链接的文件

相同inode与共享数据块:

所有硬链接和原始文件都有相同的 inode 号码,因为它们实际上是相同的文件。硬链接之间的文件没有所谓的源文件和副本之分,它们都是平等的硬链接文件

硬链接和原始文件共享相同的数据块,即它们实际上指向相同的存储位置。这意味着修改一个硬链接也会影响其他硬链接和原始文件。

硬链接和目标文件共享相同的磁盘空间。删除其中一个硬链接并不会影响其他硬链接或原始文件,直到最后一个链接被删除

查看文件的硬链接数:

 红框里面的数字就是我们对应文件里的硬链接数

这里被硬链接后的proc_test与proc_h对应的数字是2,而新建的test.txt对应的数字是1,这很好理解

但为什么刚刚创建的目录的硬链接数是2?

 原来每个目录都包含两个默认的硬链接:

  1. 自身链接: 每个目录都包含一个指向自身的链接,表示目录自身的存在。也就是自己的目录名 与 inode编号的映射

  2. 目录内部的 ' . ' 与inode的映射: 每个目录都包含一个特殊的条目' . ',它表示当前目录。这个' . '条目与目录自身的inode号码形成了映射(目录下默认会有两个隐含文件'.''..'它们分别代表当前目录和上级目录)

因此,刚刚创建的目录的硬链接数为2是正常的。

当你在目录中创建新文件或子目录时,目录的硬链接数可能会增加,因为每个新增的子目录都会在父目录中创建一个新的链接(子目录的上一级路径就是父目录,对应子目录中的 '..' 所以此时又与父目录建立了一个硬链接,使得其数量增加了1)

取消与某个文件的软硬链接本质上就是删除对应的文件

用法:

unlink 文件名

取消链接之后,链接的文件也就随之删除了.

注意:删除其中一个硬链接并不会影响其他硬链接或原始文件,直到最后一个链接被删除

最近更新

  1. TCP协议是安全的吗?

    2023-12-10 12:54:03       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2023-12-10 12:54:03       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2023-12-10 12:54:03       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2023-12-10 12:54:03       18 阅读

热门阅读

  1. MyBatis框架中的5种设计模式总结

    2023-12-10 12:54:03       39 阅读
  2. FPGA | Modelsim仿真

    2023-12-10 12:54:03       42 阅读
  3. pytorch 钩子函数hook 详解及实战

    2023-12-10 12:54:03       41 阅读
  4. vue.js怎么保证计算精度

    2023-12-10 12:54:03       36 阅读
  5. rollup打包报错“semantic error TS2802”

    2023-12-10 12:54:03       37 阅读
  6. 4-Docker命令之docker rename

    2023-12-10 12:54:03       29 阅读