【从浅学到熟知Linux】基础IO第三弹=>文件系统介绍、软链接与硬链接(含磁盘结构、文件系统存储原理、软硬链接的创建、原理及应用详解)

🏠关于专栏:Linux的浅学到熟知专栏用于记录Linux系统编程、网络编程等内容。

🎯每天努力一点点,技术变化看得见

文章目录


理解文件系统

在计算机中存在着已经被打开的文件,也存在着没有打开的文件。由于内存空间较小,资源较为紧张,故没有打开的文件都会存储在磁盘上。此时,我们会关注哪些问题呢?无非是文件如何存储在磁盘上的,如何获取该文件的属性和文件内容,磁盘上读取文件效率,不同路径上的文件如何被分门别类地存储在磁盘上的。下面,我们就一起聊聊文件系统中如何管理各个文件的。

物理角度认识磁盘

磁盘是计算机上唯一的机械设备,但现在计算机多采用固态硬盘(SSD)替代了磁盘,这里仅讨论磁盘。磁盘是外设中的一种,它是通过磁盘的磁性(N/S级)存储0或1,属于永久性存储介质。(ps:非永久性存储设备,如内存,其为掉电易失设备)

每个磁盘由多个盘片组成,每个盘面的上下两面均是光滑的,均可以存储数据。磁盘需要借助磁头来读取数据,故每个面需要一个磁头,即一个盘片上的上下两个盘面均有一个磁头(一个盘面合计2个磁头)。而磁盘读取盘面上某个位置的数据时,通过摆动磁头和转动盘面来实现。

磁盘中的每个盘面,以中心向外,划分了不同的同心圆,这些同心圆称为磁道 ,如下图左侧所示。两个磁道与两半径构成的扇形区域称之为扇区 ,如下图右侧所示。磁盘被访问的基本单元就是扇区,扇区的大小一般为512字节或4KB。我们可以把磁盘看作无数个扇区构成的存储介质。

在磁盘中,定位某个扇区的方法是:①磁头左右摆动定磁道(也称为柱面);②确定数据在哪个盘面,确定具体从哪个磁头读取数据;③盘面转动确定扇区。这种方法简称为CHS(Cylinder、Header、Sector)。

【示例】若要读取下图左侧中,橙色方块处的数据(假设已经确定使用哪个磁头读取的情况下)。

①磁头摆动到指定磁道上,即确定读取的磁道。

②一个磁道上,包含许多个扇区,需要通过转动盘面来确定扇区。转动后,如右图所示,此时可以读取数据存储区域的内容了。

由于磁盘属于机械设备,它的整体速度较慢。故在使用磁盘时,要让磁盘运动越少,效率才能越高;若磁盘运动越多,则效率越低。同时,我们也意识到:具有相关性的数据要存储在一起,这样可以减少磁盘运动。

逻辑角度认识磁盘

磁盘寻址

在十年前左右,流行使用磁带听读英语。磁带中的塑料带被卷成圆圈,但实际读取是线性读取的。如下图右侧所示,当我们将磁带中的塑料袋拉出来,可以看出,它存储数据是线性存储的。

我们也可以将磁盘看作线性结构。即将磁道上的扇区按照某种规则,给予线性顺序编号。如下图所示,从左向右依次是盘面1、盘面2、盘面3...;每个盘面内,从左向右分别是该盘面的不同磁道;每个磁道又由多个扇区组成。(这里我们假设每个磁道的扇区个数相同)

【示例】假设有一个磁盘,它的每个盘面有50个磁道,每个磁道有400个扇区(即一个盘面有20000个扇区)。若某个文件存储在第28888号扇区中,则它属于哪个盘面的哪个磁道的哪个扇区呢?

盘面号 = 28888 / 20000 = 1号盘面(即第2个盘面),磁道号 = 8888 / 400 = 22 号(即第23个磁道),扇区号 = 8888 % 400 - 1 = 87号扇区(即第88个扇区)。

像上述示例中寻找扇区的方式,称为LBA寻址方式(又称为逻辑寻址方式)。

磁盘中的寄存器

不仅CPU中包含寄存器,其他外部设备中也存在寄存器。如果某个进程要向磁盘中写入数据,则需要将磁盘中的r/w寄存器标志为写状态,将要写入的数据放入数据寄存器中,将要写入的地址空间首地址写入地址寄存器。当磁盘完成当前读写操作后,磁盘会将状态寄存器改为读写失败或读写成功(在读写时,则标志为正在读写)。

ps:这里仅仅要说明,磁盘中也包含寄存器,并未列出磁盘中的所有寄存器。

磁盘存储管理

由于一个磁盘中包含大量的扇区,为了方便管理,我们可以将一个磁盘划分为多个扇区。但每个分区依然包含许多扇区,我们可以进一步将每个分区划分为多个块组(Block Group),每个块组中包含该块组的数据存储情况及具体的数据。

假设,有一个800GB的磁盘,先将其分为5个区,第1个200GB,第2个100GB,第3个150GB,第4个150GB,第5个200GB。

由于每个分区的存储空间依然很大,每个分区被进一步分为不同的块组(Block Group)。

★ps:在某些分区中会在分区开头存储一个Boot Block(引导块),Boot Block用于存储引导加载程序,这个程序负责在系统引导时加载操作系统,并启动计算机。Boot Block用于启动系统,是关键的数据,它在其他分区中也可能被重复存储,以保证某个分区存储的Boot Block出问题时,能从其他分区读取并启动系统。

而每个块组(Block Group)开始处包含着该块组的描述信息,描述信息后面才是存储的具体数据。每个块组第一个存储的Super Block(超级块),而接下来的Group Descriper Table包含了当前块组的信息,包含剩余的块数、inode数量等。接下来,我们再来聊聊余下的4个区域:Block BitMap、Inode BitMap、InodeTable及Data Block。

★ps:Super Block是文件系统中的一个关键数据结构,用于存储文件系统的整体信息,包括文件系统的大小、单个数据块大小等;Super Block提供了文件系统的基本参数和元数据,使操作系统能够正确地管理文件和目录(为了保证文件系统能安全运行,避免因当前Super Block存储区域错误导致文件系统无法访问,故Super Block也被存储了多份)。

文件的数据包含文件属性及文件内容。Linux 系统在磁盘存储文件时,将文件的属性和数据分开存储。其中,文件的内容存储在数据块中(Data Block,以块的形式程先,常见的块大小为4KB),而文件的属性存储在Inode中(Linux系统中规定,单个文件的所有属性占128字节)。

一个文件有特定的一组属性,而属性存放于Inode中,即一个文件配有一个Inode 。为了保证Inode的唯一性,每个Inode的编号是唯一的。我们可以通过ls -li查看当前目录下所有文件的Inode↓↓↓

也可以通过stat [文件名]查看某个文件的Inode↓↓↓

Inode中保存着对应文件的文件类型、权限、引用计数、所属组、所有者、ACM时间、文件存储在哪些数据块中等。

★注意:Linux系统中,文件的属性不包含文件名

★ps:Linux系统中,一个文件一个Inode,每一个Inode都有自己的Inode编号。Inode的设置,是以分区为单位的,不能跨分区。

Inode存储文件的所有属性,文件名不属于Inode内的属性!那我们怎么知道一个文件的Inode的编号?使用者从来没有关心过Inode,用的都是文件名。

关于上面这个问题,我们就需要聊聊Linux中的目录了!那怎么理解目录呢?目录本质也是文件,也有自己的inode,因为目录也有自己的属性↓↓↓

而目录也有自己的存储内容,目录的内容中存储着该目录中包含了哪些文件。既然有数据,故目录也要有自己的数据块。那里面存的具体的内容就是它所包含的各个文件名与其Inode的映射关系。因而,使用者只需要使用文件名就可以访问一个文件了(因为有了文件名,就能在当前目录的数据块中找到该文件名映射的Inode,也就能访问该文件了)。

有了上面的认识,我们可以总结出以下内容:

  • ①为什么同一个目录下不能存在同名文件呢?
    因为文件名与Inode的映射关系唯一,如果存在同名文件,则会存在多个文件映射到用一个Inode的情况,故一个目录下不能存在同名文件。
  • ②如果没有一个目录的w权限,则不能在该目录下创建文件,这是为什么?
    在文件中创建文件,需要将文件名与Inode的映射关系写入该目录的数据块中,由于没有w权限,故无法写入数据块。
  • ③如果没有一个目录的r权限,则不能查看目录中的文件存储情况,这是为什么?
    要查看目录中存储的文件情况,则需要读取目录的数据块,由于没有r权限,则不能读取。
  • ④如果没有一个目录的x权限,则不能进入该目录,这是为什么?
    可以将目录假想成一个程序,要进入这个目录就要执行这个目录,由于没有x权限,故无法进入。

BlockBitMap:比特位的位置与块映射起来,比特位的内容表示该块是否被使用。

InodeBitMap:比特位的位置和Inode编号映射起来,比特位的内容表示该Inode是否有效(是否被使用)。

  • 新建一个文件,系统做了什么?

①在InodeBitMap申请一个Inode;

②在BlockBitMap申请当前文件需要的对应数量的Data Block,并在这些Data Block中存储文件的内容;

③并在InodeTable中找到申请的Inode,存储该文件的信息及申请了哪些Data Block;

④在当前目录的Data Block保存该文件的文件名与Inode的映射关系。

  • 删除一个文件,系统做了什么?

①将文件存储内容的块在BlockBitMap中的对应位置设置为无效;

②将文件存储属性的Inode在InodeBitMap中的对应位置设置为无效;

③删除当前目录的数据块中存储的该文件与Inode的映射关系。

ps:不需要情况Inode和Data Block中的数据,等下一个文件直接覆盖该文件的内容即可。

  • 修改or查询一个文件,系统做了什么?

①在当前目录的数据块中,通过文件名找到该文件的Inode;

②从Inode中获取文件的属性信息及文件内容存储在哪些Data Block中;

③返回文件属性及文件内容。

★ps:为什么拷贝数据慢,而删除数据快呢?

拷贝数据数据时,需要将数据挨个比特位写入到文件对应的Data Block中;而删除数据的时候,不需要情况Data Block中的数据,只需要将该文件的Data Block对应在BlockBitMap中的位置置为无效即可。

★ps:为什么系统提示还有空间,但却无法创建文件呢?

Inode还有但DataBlock没有了,或Inode没了但DataBlock还有。

软链接与硬链接

软链接

建立软链接的方法

bash 复制代码
ln -s [file-name] [soft-link-name]

我们可以通过软链接向file1中写入"Jammingpro"↓↓↓

我们再来看一下file1与soft-file1的inode↓↓↓

由上面的结果可知,软链接是一个独立的文件,因为它有独立的inode,故它们的数据块(Data Block也是不同的)。软链接中存储的是file1的路径

当访问软链接时,它会到对应的路径中找到file1的文件名与inode的映射关系,并访问对应的inode。软链接就类似与Windows中的快捷方式(它在Linux系统中的应用也是用于创建快捷方式)↓↓↓

如果要删除软链接,除了使用rm [软链接名称],也可以使用unlink [软链接名称]↓↓↓

硬链接

创建硬链接的方法

bash 复制代码
ln [file-name] [hard-link-name]

从上面的建立结果可以看出,file1在创建硬链接前的引用计数为1,当建立硬链接后的引用计数变为了2。我们再来看看者两个文件的信息↓↓↓

两个文件除了文件名不同,其他信息(Inode编号,占用数据块数量、大小等)均相同。故所谓建立硬链接,本质其实就是在特定的目录的数据块中新增文件名和指定文件的Inode编号的映射关系,并将对应文件的引用计数+1。也就是说,硬链接就是给对应的文件取别名。

★ps:任意一个文件(无论是目录还是普通文件)都有Inode,每个Inode内部都有一个叫做引用计数的字段。只有该文件的引用计数变为0时,该文件的Inode及Data Block才会被删除。

硬链接用途有什么呢?关于它的用途,我们需要先来探索关于目录的一些问题↓↓↓

为什么我们创建文件夹的使用,它的引用计数为2呢?

下图查看了dir的Inode,并进入dir中,查看了.的Inode。可以看出,dir的Inode与.的Inode是相同。也就是说,当我们创建目录时,会在该目录中自动创建一个该目录的硬链接,其名称为.。

如果在dir目录中创建一个名为start的目录,可以发现,.的引用计数变为3。这是为什么呢?

进入start目录,可以发现该文件夹中的...的Inode与上一级目录中的.的Inode编号相同,也就说:每当在当前目录下创建一个目录,该目录中会自动创建一个名为...的上一级目录的硬链接。

通过上面我们可以知道,硬链接可以用于目录的跳转。因为我们使用.、...来跳转目录。但Linux并不允许用户给目录创建硬链接,这是为什么呢?

假如我们将某个目录中的.和...均改为根目录,则此时会出现环结构。当我们使用搜索指定时,就会出现无穷循环的现象。

🎈欢迎进入从浅学到熟知Linux专栏,查看更多文章。

如果上述内容有任何问题,欢迎在下方留言区指正b( ̄▽ ̄)d

相关推荐
摸鱼也很难1 小时前
Docker 镜像加速和配置的分享 && 云服务器搭建beef-xss
运维·docker·容器
watermelonoops1 小时前
Deepin和Windows传文件(Xftp,WinSCP)
linux·ssh·deepin·winscp·xftp
woshilys1 小时前
sql server 查询对象的修改时间
运维·数据库·sqlserver
疯狂飙车的蜗牛2 小时前
从零玩转CanMV-K230(4)-小核Linux驱动开发参考
linux·运维·驱动开发
恩爸编程3 小时前
探索 Nginx:Web 世界的幕后英雄
运维·nginx·nginx反向代理·nginx是什么·nginx静态资源服务器·nginx服务器·nginx解决哪些问题
Michaelwubo4 小时前
Docker dockerfile镜像编码 centos7
运维·docker·容器
远游客07134 小时前
centos stream 8下载安装遇到的坑
linux·服务器·centos
马甲是掉不了一点的<.<4 小时前
本地电脑使用命令行上传文件至远程服务器
linux·scp·cmd·远程文件上传
jingyu飞鸟4 小时前
centos-stream9系统安装docker
linux·docker·centos
好像是个likun4 小时前
使用docker拉取镜像很慢或者总是超时的问题
运维·docker·容器