磁盘的认识
了解磁盘的结构:
1、盘片
硬盘首先会有多个盘片构成,类似很多个独立的光盘合并在一起,每个盘片都有2个面,每个盘片都有一个对应的磁头,我们的磁头横移和盘面的旋转就可以读写到盘面的每一个位置,而我们的磁盘数据实际上就是在盘面上保存的。2、扇区和磁道
每个盘片会分成若干个相同同心圆的磁道,磁道从外围开始编号,从0开始,每个磁道又会划分成若干个扇区,扇区是硬盘的最小存储单元,一般是存储512字节。3、磁头和柱面
磁头用于读取盘面中磁道内的扇区中存储的数据。一个盘片有上下2个盘面对应2个磁头(盘面数 = 磁头数)。柱面是所有盘面中相同磁道的柱面,形成的是一个立体的柱体形状,磁盘的柱面数和磁道数是相等的。
CHS定位法
早期可以通过柱面号(Cylinder)、磁头号(Head)和扇区号(Sector)来精确定位硬盘驱动器上的数据。柱面号用来指示在哪个柱面上进行读写操作,磁头号用来指示在哪个磁头对应的磁面上进行读写操作,而扇区号用来指示在某个磁头的某个磁道上的哪个扇区进行读写操作。
现代硬盘驱动器采用的是LBA(Logical Block Addressing,逻辑块寻址)定位方式,通过逻辑块号来寻址数据。
对磁盘结构的逻辑抽象
我们知道磁盘的盘面中存放数据的单元其实就是若干个扇区,而我们将这旋转着的一圈圈扇区都排成一排,此时的结构就像一个顺序表数组了:
以下是数据管理硬件的逻辑:
如上所示,可以将每一个扇区就是最小单元,此时就可以对扇区进行软件层的数据结构处理,将每个扇区都编号,因此对每个扇区的访问就是对编号的访问。而一般磁盘有十面,而每个盘面的扇区一致,所以就可以将编号数除以每个盘面的扇区数得到的就是对应的盘面,而进而再将除下的数据再除以每个盘面的扇区数就是对应磁面的对应扇区。因此就是可以形成一一映射的关系,进而可以实现软硬件交互。
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
我们操作系统下的文件系统其实并不是以扇区为单位进行编号的,因为我们知道一个扇区基本上就是512字节,其实并不大,如果这样访问(IO)起来的话就会比较频繁。实际上文件系统大多数是以8个扇区为一个单元,也就是512byte*8=4kb。因此就是对这4kb的内存块编号。
而这每一个内存块的地址就是LBA(逻辑块地址)
磁盘的区域划分
我们磁盘一般都是以GB为单位,甚至大一点的都是TB为单位。所以说我们对磁盘的管理会采用分区的方式,毕竟将每一区域的空间管理好,然后其他的区域直接套用该种管理方法就行了。就拿我们大多数的电脑来说,其实像C盘D盘就是一块磁盘分成的两个区。
其实将磁盘分成一个个区以后还是不够的,空间还是非常大的,所以我们还将对应的区划分成一个个组,因此,我们对分区的管理就可以转换成分组的管理。
假设我们磁盘有500GB的大小,分成5个区,然后每个区分成50个组:
以上就是对磁盘空间的抽象划分。所以具体我们就是对组的管理,而对这分区的100GB稍微具体化就是如下:
BootBlock:启动块,一般会在编号为0的磁头所对应的盘面,的第一块扇区。负责计算机的启动。
而其他部分就是我们的块组,而块组对应着以上的五六个小部分,其实其中存的就是文件的数据(内容+属性)信息和文件管理的数据信息。而我们最开始的块组就是需要先将管理数据写入到块组当中,管理数据其实就是管理块组中的空间使用信息以及文件对应的块空间等等,而这一操作其实就是格式化。
分组后的细分
首先我们要认识一下文件的inode编号。
我们使用 ll -i 指令得到的信息中,最前面的一段数字码(1580394和1580395)就是文件的inode信息:一般都是一个文件对应着一个inode编号,每个文件都有其对应的inode编号,在整个分区具有唯一性,Linux中识别一个文件与文件名没有关系,只和inode编号有关。而且磁盘中保存文件的属性数据是通过inode来保存的1所以说inode就相当于是一个结构体一样:
struct inode//大小固定sizeof(inode)=128字节
{//拥有者、所属组、ACM时间、大小权限、inode编号...}
inodeTable
inode表,就相当于是一个存放上面struct inode结构体的数组,而该数组的下标对应的就是inode编号。
Data blocks
数据区,将该组的空间划分成一个个文件块单元(每个文件块4KB大小),存放的就是整个块组里所有文件的内容数据。简略的抽象图如下:
而我们想要将inode对应文件所存储的信心对应起来该怎么做呢???我们的struct inode中还会为我们维持一个数组就个inode所对应文件的内存块,4KB不够则采用一对多的形式映射。
struct inode//大小固定sizeof(inode)=128字节
{//拥有者、所属组、ACM时间、大小权限、inode编号...int blocks[n]//n一般是15}
1.我们的文件和数据块的映射也才15个,共15*4KB,那么如果文件不仅仅只有60KB呢???
其实我们的15个块并不是直接映射的,13号和14号下标会通过间接映射的方式,例如:13号块大小是4KB,会保存更多的块列表,也就是会指向其他的块儿编号,所以此时就会形成二次1映射,而14号块也同理,此时就会形成三级映射,此时的结构就有点像多叉树。
2.如果该组的空间还不够,或者数据块已经用光了呢???
此时会进行跨组访问,将文件信息存到其他组的块儿中,此时只需要记录其他组的组好和对应的块号就可以。
inode Bitmap
我们知道bitmap就是表示位图,而位图最大的特点就是节省空间以及表示“是和否”的问题。
所以对于inode Bitmap标识的就是inode编号的使用情况,如果编号为n的比特位被使用了,那么就可以将编号为n对应的比特位设置为1,没使用的话就是原初始值0。
Block Bitmap
有inode bitmap表示这inode的使用情况,那么同理block bitmap标识的就是数据块Data blocks的使用情况。同样也是采用0和1来表示。
所以知道磁盘的空间的使用与否其实就是取决于数据块位图的标识符是为0还是为1,因此我们如果先要删除文件其实就是将位图为1改为0,此时并不需要将内存数据块的数据清空。如果需要使用该块,则会采用覆盖的形式进行。
Group Descriptor Table
简称GDT:块组描述符,描述块组属性信息。存放的一般是该块组的其实inode编号(inode编号在整个区是唯一的),组中inode总数,inode的使用数量,组中块组总数,块组使用数量……
Super Block
超级块(Super Block):存放文件系统本身的结构信息。Super Block并不是每个块组都存在,只在个别的块组中前面会存在Super Block(保存多份就是为了防止出错后整个分区故障,故障后可以借助其他的Super Block拷贝修复)。
记录的信息主要是整个分区的相关把信息:bolck 和 inode的总量,未使用的block和inode的数量,一个block和inode的大小,最近一次挂载(确定分区根目录)的时间,最近一次写入数据的时间,最近一次检验磁盘的时间等其他文件系统的相关信息。Super Block的信息被破坏,可以说整个(分区)文件系统结构就被破坏了。
文件系统
我们的用户都是通过文件名进行访问的,而系统中只认识inode编号,所以说此时我们的文件名就会和inode编号构成映射关系。而我们的目录文件也不例外,也有自己的inode编号,但是目录的数据块内容并不是和普通文件一样存放的是一些代码或音频等信息,而目录文件中一般会创建有其他文件,所以目录文件的数据块中存放的是该目录下的文件与inode编号的映射关系。
我们的文件名一般相当于是键值对key-val中的key结构,所以说我们同一个目录下不能存放同名文件。而且我们Linux中文件名并不属于文件属性,文件名是用户创建的,而操作系统会为我们分配文件inode编号与文件名映射。
所以说对于文件的查找我们其实都是从根目录中开始查找的,然后通过inode编号与数据块映射,找到数据块信息,然后层层剥离,最终找到目标文件,就相当于是从多叉树的根节点开始找某个节点。
对于我们进程打开一个文件是通过该进程的CWD工作目录和打开的文件名来确定当前文件所在位置,而根据最起始的路径确定磁盘分区,然后通过文件inode确定具体的分组以及对应的数据块,然后将数据块的内容刷新出来就行。
软硬链接
软链接和硬链接是像unix操作系统中用于创建文件链接的两种方式。
软链接
软链接也被称为符号链接或者软连接。它是一个特殊类型的文件,其中包含了指向另一个文件或目录的路径。软链接类似于Windows中的快捷方式。它可以跨越文件系统边界和目录边界,指向其他文件或目录。软链接的删除不会影响原始文件,但是如果原始文件被删除,软链接就会失效。
就像我们电脑上下载好的软件其实就是以一个文件夹的形式下载好,其中会有配置文件、日志文件、可执行文件……而我们的可执行程序(也就是双击进入的软件)就是在可执行文件中,此时需要进入可执行文件再双击可执行程序才可以运行该进程。所以我们就会在外层桌面文件中建立软链接的形式直接创建快捷方式。
软链接的创建使用ln -s
命令:
ln -s <原始文件路径> <链接文件名>
创建好的软链接与原来的文件inode是不一样的,因此软链接是独立的文件。但是当我们向test文件还是test.soft.link链接文件的其中一方写入数据的话,最终在另一方中也是会被写入(硬链接也一样):
硬链接
硬链接是指两个或多个文件共享相同的iNode,它们指向同一份数据块。它是文件系统内部的文件系统链接,没有独立的文件实体。硬链接只能在同一个文件系统中创建,不能跨越文件系统边界。当原始文件被删除时,硬链接仍然可以继续访问原始文件的内容。因为硬链接中会指向同一个inode而此时会通过引用计数的方式来将inode和文件名构成一对多的映射关系。
硬链接的创建使用ln
命令:
ln <原始文件路径> <链接文件名>
我们知道文件inode和文件名是会构成一对多的映射关系的,采用引用计数的方式,而且对于一个inode有没有与文件名映射,以及映射数目也会存在struct inode的结构体当中:
struct inode//大小固定sizeof(inode)=128字节
{//拥有者、所属组、ACM时间、大小权限、inode编号...int blocks[n]//n一般是15int ref_count;//引用计数
}
而且我们ll指令显示出的文件属性也是会将映射的数目情况展示出来:
删除文件应用计数--;创建硬链接,引用计数++; 而且对于目录文件都会有两个默认文件.和..
所以在创建目录文件时一般引用计数就为2:
软链接和硬链接的使用目的和特性不同。软链接通常用于创建快捷方式或跨越目录的链接,而硬链接则通常用于创建多个文件名指向同一个文件的链接。另外,软链接可以指向目录,而硬链接只能指向文件。 其实硬链接不能指向目录的原因就是因为如果指向某个目录的话,那么在查找文件时就会造成死循环(因为此时目录文件inode相同)但是也有例外,ll -a 目录文件时就会有.和..文件,也是硬链接的。