ToB企服应用市场:ToB评测及商务社交产业平台

标题: 文件体系--底层架构(图文详解) [打印本页]

作者: 灌篮少年    时间: 2024-12-28 22:23
标题: 文件体系--底层架构(图文详解)
一、文件体系的底层存储与寻址 

当我们谈到文件体系的底层结构时,最关键的题目是:文件的数据与元数据(属性)怎样存储在磁盘上,以及体系是怎样定位这些数据的?在谈及文件体系之前,我们要先对储存文件的硬件有一些根本相识
首先,我们来看一下传统磁盘的基础结构 

我们可以看到这种传统的机械磁盘的构成,那么它是怎样运转的呢,又是怎样进行文件里的内容存储的呢?
首先,计算机是不是只能识别二进制语言啊,而这个二进制语言说起来又有些广泛,有人说二进制不就是0和1吗? 0和1又是什么呢?实在啊,0和1也只是相对的一种概念,它也可以由我们自己更换,好比阴和阳?水和火?这些相对的概念也可以称之为0和1,因此在磁盘中,磁盘由于具有磁性,所以就代表他有南北极,我们就可以近似的把它的磁性之分代表对应的0和1,通过修改它的磁场,是不是就可以到达对“0”和“1”的修改呢?也就可以轻松完成数据的存储。
那具体它又是怎样通过以上图片里的这些电子元件完成我们的目标的呢?以下是它的工作步调:

有同学看到这里就大概没太看懂,那我们来总结以下,大抵如下:

磁盘呢实在是一个里面结构,它每个面都是光滑的,都是可读可写的,我们家用的从前的DVD,只是单面且只读的,也就是在盘片高速旋转的过程中,磁头通过左右摇摆和前后移动来到达对应的位置然后改变它下面盘片的磁性,从而到达对数据进行更改存储,那么题目来了,它怎么知道我要改的地域是哪里,这么大一个盘片,怎么能精确的我所要更改的数据存储在哪个地域呢,因此我们来细致的讲解以下盘片的地域划分:

这里我们就要提到一些概念:
首先是磁道 ,一个大的盘面,可以由若干个同心圆由内向外扩散,这每一个圆圈都叫做一个磁道,而这个磁道由圆心开始﹐在同一表面上分别画出无数条半径﹐然後每两条半径所分割的磁轨﹐我们称为磁区(Sector),也就是扇区,所以终极经过层层确认,每个扇区内的那一小块就是我们要寻找的地方。
因此,传统磁盘内怎样找到一个指定位置的扇区?
也就是我们的“CHS定址法
a. 首先确定我们在第几个磁头(Header),也就是第几个盘片
b.找到磁头后确定对应的磁道(Cylinder)
c.找到磁道后确认在哪个扇区(Sector)
通过以上步调我们就可以找到文件所对应在磁盘的准确位置了,是不是很神奇,这是不是也意味着
文件的巨细归根结底就是占用多少个扇区的地方嘛!
可如今随着科技的发展,我们所接纳的已经不是这种很老的磁盘了,一般企业会接纳这种,由于它不会挪动,拿来做服务器刚刚好,一旦做成便携式笔记本,磁头和盘片一打仗直接就会造成不可避免的数据损失,我们如今所接纳的是固态硬盘(SSD),无需运动,而且有更高的效率。
那么话归正传,既然我们已经知道怎样在磁盘里寻找对应的文件地址了,是不是意味着每次我都要进行计算啊,这完全依赖于硬件配置啊,难道我作为一家企业要为每一个差别磁盘规格都编译一份操作体系吗,这肯定不可,因此我们要封装一下这个步调,让我们的操作体系不需要去依赖硬件才能找到地址,那我们的操作体系是怎样做的呢?
之前我们是不是说过,机械磁盘里盘面实在是链接在一起的,各人小学时应该都见过这个东西

它内部实在就是雷同两个盘片,中间用线将他们连接起来,反复播放,实在我们的磁盘也同理,n个盘片是不是也可以以线性的方式将他们连接到一起啊!
这是不是相当于将他们都整合成了一个近似的数组啊,这个数组里存放的是不是就是对应的扇区啊!
 也就是说我只需要存放对应位置的下标,然后进行一些列的计算就可以转换成机械硬盘所需要的CHS地址啊,而我操作体系内部就可以按照计算方式来进行管理,是不是很方便
假设我们当前一共有1000个扇区,10个磁道,那么此时我们的对应下标是500,那么如今我们要计算出在第几个磁头,然后转化成当前盘面的对应扇区下标,然后计算出在哪个磁道后计算出对应扇区,步调如下

通过如许的计算我们就可以成功找到对应的位置了
但是我们可以思索一下,一个扇区一个扇区的计算,对于操作体系的消耗是不是太繁琐了啊,由于扇区的单位实在是太小了,每次都要去计算出这个很小的精确位置十分消耗资源,因此操作体系在于磁盘交互的时候其根本单位是4kb,也就是八个扇区的巨细。
操作体系和文件体系通常利用“块(block)”作为根本分配和访问单位。一个块大概由若干扇区构成(比方4KB=8个512字节扇区)。文件体系通过块号(Block Number)来定位文件数据,从而屏蔽底层扇区的复杂定位。假设有N个连续的块可以利用,则文件体系在逻辑上将磁盘空间看成一个块数组(block0, block1, block2, ...)。通过块号,我们可以快速找到对应的扇区,进而从磁盘中读写数据。 如图所示

所以也意味着我们只需要一个起始地址,磁盘的总巨细,就可以知道磁盘每个单位的下标,然后通过计算就可以取到对应的CHS地址!
所以也就是今世方法“逻辑区块地址(Logical Block Address, LBA)”
LBA是非常单纯的一种定址模式﹔从0开始编号来定位区块,第一区块LBA=0,第二区块LBA=1,依此类推。这种定址模式取代了原先操作体系必须面临存储设备硬件构造的方式。最具代表性的首推CHS(cylinders-heads-sectors,磁柱-磁头-扇区)定址模式,区块必须以硬盘上某个磁柱、磁头、扇区的硬件位置所合成的地址来指定。CHS模式对硬盘以外的设备来说没什么作用(比方磁带或是网络存储设备),所以通常也不会用在这些地方。已往MFM(Modified Frequency Modulation, 改良调频式)和RLL(Run Length Limited)存储设备都曾利用CHS模式,ATA-1设备更将延伸CHS(Extended Cylinders-Heads-Sectors, ECHS)也派上了用场。
那仅仅到这里就完成我们文件体系的管理了吗?
我们的整个磁盘巨细但是有800GB啊,难道每次就对这800GB的磁盘巨细进行挨个查询吗,这显然也是不现实的,因此我们的操作体系接纳了“分治头脑
要管理好我们的磁盘,实在内存是很大的,这个时候我们接纳的就是分区,800GB分成若干个地域,有管理好200GB的机制,就可以以此类推管理好剩余地域,分区下面再分组,就完成了文件体系的管理
大型磁盘每每被分割为多个分区(Partition),每个分区作为独立的逻辑存储地域,安装(mount)为独立的文件体系。比方,一个1TB磁盘可以分成200GB、200GB、300GB、100GB等多个分区。如许做的目标是“分而治之”,简化管理和提升灵活性。
在类UNIX文件体系(如ext系列)中,分区内部还分成块组(block group)。块组内包含inode表、块位图、inode位图以及数据块地域。通过将文件体系分块组管理,可以提升文件体系的本地性和查找效率。

   如图所示,Linux ext2  文件体系,上图为磁盘文件体系图(内核内存映像肯定有所差别),磁盘是典型的块设备,硬盘分区被划分为一个个的block  。一个  block  的巨细是由格式化的时候确定的,而且不可以更改。比方  mke2fs  的  -b  选项可以设定block  巨细为  1024  、  2048  或  4096  字节。而上图中启动块(  Boot Block  )的巨细是确定的  那我们每个分组内的这些信息都代表什么呢?

 我们之前说过Linux内文件是由什么构成的?
文件 = 内容 + 属性 ,那么文件在磁盘中的存储就是文件的内容+文件的属性数据,本质上都是数据,存储在磁盘里,一个正常的文件,就要有他的对应的属性啊,这个属性就是inode,也就是一个正常文件就要有对应的inode属性聚集。
那么先说我们的inode,
inode表是存放文件元数据(属性)的地域。这里的inode是一个结构体,记录了文件的:

需要注意的是,在Linux的ext2/3/4文件体系中,inode并不存放文件名。文件名存储在目录的data block中,而inode指针是通过目录项(directory entry)将文件名映射到inode号(number)上。
inode Bitmap(inode位图)

inode位图(inode Bitmap)与块位图雷同,只不外它是标记inode的利用情况。

当需要创建新文件时,文件体系会在inode位图中查找空闲inode(即bit为0的位置),然后分配给新文件,并将该位清为1表示已占用。
Block Bitmap(块位图)

块位图(Block Bitmap)是用于记录本块组中哪些数据块已经被分配,哪些还空闲的位图数据结构。每一位(bit)对应一个block:

当文件需要分配新的数据块时,文件体系会在对应块组的Block Bitmap中找到一个置0的bit,将其置1,并分配给文件。由于是位图结构,查找和修改都很高效,只需简单的位操作即可。
数据区(Data Area)

其次是我们的Data Blocks,这就是我们的数据区,也就是存放文件的内容的地方,里面的一个个根本单位就是4KB,实在就是我们磁盘最开始一个个小扇区单元块,完全同等。实际上我们在寻找文件时必须用inode号来寻找,inode是以分区为单位分配的而不是以分组的形式分配的,每个组只需要记录自己的起始inode和竣事inode即可,也就是在上层确定一个inode后直接在下面的分组确定自己在哪个分组里就行,但是题目是我们每个分组里不都是inode要从0开始吗,这也怎么区分呢?实在可以用inode号减去当前分组的起始inode,剩下的数字就可以进去bitinode检察是否被占用和后续利用了.
超等块(Super Block)

超等块(Super Block)是整个文件体系的“全局信息表”,其中记录了文件体系的关键信息,包括但不限于:

在ext2中,超等块不但在分区开头的特定位置存储,还会在每个Block Group中存放一份副本(除非格式化时指定了不存放备份)。这些副本作为冗余信息存在,一旦主超等块破坏,可以从块组的副本中恢复文件体系的结构信息。
假如超等块信息被全部破坏,那么文件体系的结构信息就无法找回,整个文件体系相当于“失去了地图”。
但是到这里为止,各人有没有想过,inode编号的存在我们已经掌握了,但是你真正对文件进行操作的时候什么时候用inode号了,是不是都说以文件名的方式来进行操作啊,跟inode有什么关系呢?
那么到了这里我们就不得不谈一个相关的概念了:目录
我们说Linux里是不是一切皆文件啊,我要组织这些文件,那我目录是不是就担当这个角色呢,所以目录也有自己的内容+属性,他的属性是不是和inode差不多,内容呢,我们之前说过inode里不存文件名,实在文件名是存放到目录里的,我们通过目录里文件名对应的inode来进行寻找文件,实在是文件名和inode建立了一层映射关系,让我们可以通过目录直接分配对应的Inode来进行后续的管理啊,所以我们可以引申出一些结论
一个目录下不能建立同名文件的关系是什么,是不是无法区分对应的是哪个inode号啊,
而查文件的本质就是 文件名-> inode号
所以对一个文件没权限写的本质是什么,是不是没有访问inode的权利啊,找不到映射关系怎么写入呢?
所以我们每次访问是不是都要从目录里进行访问,那么我们的目录不也是文件吗?
目录名不也是一个inode吗,他也有对应的数据块啊,所以实际上我们在访问一个路径下的文件时,实在是对路径进行一个逆向剖析,先找到根目录,然后通过根目录的inode找到下一个目录的Inode,紧接着一步步在inode里找inode,最后找到文件的inode就可以进行操作了,所以根目录的inode一定是刚打开操作体系的时候就已经确定好了,
这些操作都是操作体系自己做的
这就是为什么我们在打开文件时都必须要有路径!
一个文件访问前都是先访问目录,这个目录就已经确定好分区了
所以目录是谁提供的呢,进程在启动时就已经携带了,都是由操作体系提供的
为了提高效率,Linux内核有dentry(directory entry)缓存,用于缓存最近剖析的路径信息。如许在多次访问同一路径时,无需重复进行层层目录查找,能显著减少体系开销。
这些组件是怎样协同工作的?

下面将通过一个较为完整、详细的流程来描述当我们在用户步伐中利用 fwrite() 向一个新建文件中写入数据时,在底层发生了什么。从用户态的C标准库调用开始,一直到数据终极被写入到磁盘文件体系的实际块中,以及新文件创建过程中的元数据分配与更新流程。
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. int main() {
  4.     FILE *fp = fopen("newfile.txt", "w");
  5.     if (fp == NULL) {
  6.         perror("fopen");
  7.         return 1;
  8.     }
  9.     const char *data = "Hello, fwrite!\n";
  10.     size_t wrote = fwrite(data, 1, sizeof("Hello, fwrite!\n") - 1, fp);
  11.     if (wrote < sizeof("Hello, fwrite!\n") - 1) {
  12.         perror("fwrite");
  13.     }
  14.     fclose(fp);
  15.     return 0;
  16. }
复制代码
实行过程分解

1. 文件创建(fopen阶段)

当你实行 fopen("newfile.txt", "w") 时,底层流程大抵如下:
2. 写入数据(fwrite阶段)

当实行 fwrite(data, 1, len, fp) 时,发生了如下过程:
3. 文件体系同步与落盘

当内核需要将数据实际写入磁盘(大概是耽误一段时间后):
4. 文件关闭(fclose阶段)

当你调用 fclose(fp):

此时,从应用步伐的角度看,文件已经成功写入并关闭。数据终极会在一定时间内被写回磁盘(假如还未写回),从而持久地存储在分区对应的data block中。
总结底层过程

通过上述过程,从调用fwrite()往新建文件中写入数据,到文件数据真正写入磁盘,中间经过了用户态缓冲—>内核态缓冲—>磁盘的多层抽象,期间涉及路径剖析、inode与block分配、目录项更新、位图修改和inode表修改等关键步调。这就是利用 fwrite 和新建文件这两个实行在底层全面展开的实际流程。
 
总体来说,这些元数据结构(超等块、GDT、位图、inode表)与数据区紧密协作,形成了ext2文件体系的“管理层”(元数据)与“内容层”(数据区),借助块组的分条理管理和位图的高效查找,使得文件体系在底层能够有效组织和管理海量文件与数据,包管文件读写、创建、删除和寻址的高效与可靠。 
 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4