当前位置: 首页 > 科技观察

图-你管这狗屎叫文件系统?

时间:2023-03-16 18:43:06 科技观察

你手上有个硬盘,1T大小,还有一堆文件。从硬盘的角度来看,这些文件只是一堆二进制数据。您将把这些文件存储在硬盘上,并在需要时将它们读出。应该设计什么样的软件来更方便的读写硬盘中的这些文件呢?1、首先,我不想处理复杂的扇区和设备驱动等细节问题,所以先实现了一个简单的功能,将硬盘逻辑上一个一个地划分为Block,可以以block为单位进行读写.每个块定义为两个物理扇区的大小,即1024字节,也就是1KB。硬盘太大,无法分析。让我们假设你的硬盘只有1MB,那么这个硬盘有1024个块。好的,让我们开始保存文件吧!准备一个文件,选择一个block放到里面,block3!成功!首战告捷!2保存另一个文件!嗯?发现一个问题,万一这个文件也保存到block3,原来的文件不是被覆盖了吗?不行,必须有一个地方记录现在有哪些块可用,像这样。Block0:UnusedBlock1:UnusedBlock2:UnusedBlock3:UsedBlock4:Unused...Block1023:Unused那我们就用block0来记录下所有block的使用情况吧!如何记录呢?位图!我们给block0起个名字,叫blockbitmap,然后这个block0用来记录所有block的使用情况,不再用来存放具体的文件。当我们保存一个新文件时,我们只需要找到块位图中第一个为0的位,就可以找到第一个未使用的块并保存文件。同时别忘了将block位图中对应的位置设置为1,完美!3接下来我们尝试读取刚才的文件。嗯?我又遇到了问题。怎么才能找到刚才的文件呢?根据块号?合理的。所以我们给每个文件起一个名字,叫做文件名,用它来查找文件。那么一定要有一个地方记录文件名和块号的对应关系,像这样。向日葵合集.txt:Block3的数学期末复习资料.mp4:Block5的低并发编程秘诀.pdf:Block10...不用着急,既然要选地记录文件名,不妨多记录一点我们关心的信息,比如文件大小、文件创建时间、文件权限等,自然这些东西也需要存储在硬盘上。我们选择使用固定大小的空间来表示这些信息。空间有多大?128字节。为什么是128字节?我喜欢。我们称这个128字节的结构为inode。之后,我们每存储一个新文件,不仅需要占用一个block来存储文件本身,还需要占用一个inode来存储文件的元信息,inode的块号字段指向文件的位置。块号。如果一个inode是128字节,那么一个block可以容纳8个inode,我们可以给这些inode编号。如果觉得inode数量不够,也可以用两个或更多的block来存储inode信息,但是这样存储数据的block会变少,就看自己的平衡了。同样,就像块位图管理块的使用一样,我们也需要一个inode位图来管理inode的使用。让我们把inode位图放在块1中!同时我们把inode信息放在block2里面,一共有8个inode,所以我们的block2就叫做inode表。现在,我们的文件系统结构变成了这样。注意:块位图用于管理可用块,每一位代表一个块是否被使用。inode位图是一个一个管理inode,而不是inode占用的block。比如上图中有8个inode,那么inode位图中就有8位来管理它们的使用与否。4现在,我们的文件很小,可以放在一个块中。但是,如果需要两个块、三个块或四个块怎么办?很简单,我们只需要采用连续存储的方式,inode只记录文件的第一个block,后面需要多少个block。这种方法的缺点是容易留下大大小小的孔洞。新文件到来后,很难找到合适的空白块,空间就会浪费。这个方法好像不行,怎么办?既然inode中记录了文件的block号,为什么不扩容多记录几个block呢?本来在inode中只记录了一个块号,现在扩大一下,记录8个块号!而且这些块不需要是连续的。嗯,这是一个可行的办法!但是这只能代表8个block,而能记录的文件最大是8K(记住,一个block是1K),当前文件很容易超过这个限制。我应该怎么办?很简单,我们可以让其中一个块充当间接索引。这样一来,瞬间就有263个块(256-1个块)可用。这种索引称为一级间接索引。如果还不够,再做一个block做一级间接索引,或者二级间接索引(二级间接索引可以有256*256-1个block)。我们的文件系统,暂时只有一级间接索引。硬盘总共只有1024块,一个文件263块足够大了。再大也不行,就是这么任性,你用不用都行。好了,现在我们可以保存非常大的文件了,通过文件名和文件大小来准确读取!5但是我们要不断改进,我们想想这个文件系统有什么问题。比如inode数量不够用,我们怎么知道?我们是否需要查看inode位图,如果找不到,我们就知道它不够用了?同样,当块数不够时也是如此。如果有一个全局的地方记录这一切就好了,方便随时调整。比如freeinode的个数,block的个数,freeblock的个数,那我们就再占用一个block来存放这些数据!因为他们看起来好像是在用上帝的视角来描述这个文件系统,所以我们把它放在第一个块上,称之为超级块。目前的布局如下。我们不断追求卓越。现在,blockbitmap、inodebitmap、inodetable都占据了block1、block2、block3三个位置,如果inode数量多到inodetable或者inodebitmap需要占用多个block怎么办?或者,块数增加(硬盘本身变大,或者每个块变小),块位图需要占用更多的块。阻塞,我该怎么办?程序死了,如果你不告诉它哪个块是什么意思,它不会自己猜。很简单,就像超级区块中记录的信息一样,这些信息也是选择一个区块来记录的,不用怕。然后我们选择紧跟在超级块之后的1号块来记录这些信息,并称之为块描述符。当然,这些块号只是记录了起始块号,块位图、inode位图、inode表可以各自占据多个块。好吧,你完成了!6现在,让我们尝试存放另一批文件。向日葵宝典.txt数学期末复习资料.mp4女婿1.mp4女婿2.mp4女婿3.mp4女婿4.mp4低并发编程的秘诀。嗯?如果平摊开来,能不能有等级关系?比如向日葵宝典.txt数学期末复习资料.mp4佐女婿1.mp4女婿2.mp4女婿3.mp4女婿4.mp4低并发编程秘籍.pdf我们称葵花宝典.txt为普通文件,女婿为目录文件。如果要访问女婿1.mp4,完整的文件名应该写成女婿/女婿1.mp4。这个怎么做?那么我们又得把inode结构取出来了。这时候就需要一个属性来区分文件是普通文件还是目录文件。缺的补上,我们已经很熟悉了,多了一个4字节来表示文件类型。如果是普通文件,这个inode指向的数据块还是和之前一样,是文件本身的完整内容。但是如果是目录文件,这个inode指向的数据块就需要重新规划。这个数据块应该是什么样的?它可以是指向彼此相邻的不同inode的结构,例如这个。这样,先通过女婿的目录文件找到所在的数据块。然后根据这个数据块中有inode信息的结构,找到这个目录下的所有文件。完美的!7但是这样的话,大家想一想,如果要查看女婿目录下的所有文件(比如ll命令),并且显示文件名和文件类型,应该怎么办呢?做?你需要先把每个结构体指向的inode从inode表中取出,然后再取出文件名和文件类型,很浪费时间。而让用户看到一个目录下的所有文件是一个极其常见的操作。因此,最好将文件名、文件类型等常用信息放在数据块中的结构体中。同时,inode结构中的文件名似乎也没什么用。把这种变长的东西放在这个定长的结构里很烦人,早就想去掉了。并且可以为其他信息节省空间,比如文件所在块的数组,可以多几个。太好了,删除它!OK,大功告成,现在我们可以将文件分类到不同的目录中,在目录下创建目录,无限套娃!8现在的文件系统已经比较完善了,但是还是有点不适应。当我们访问一个目录时,我们可以很舒服的看到该目录下的文件,然后根据名称访问该目录下的文件或目录。整个过程都是套路。但是,最顶层目录,即根目录下的所有文件,仍然需要遍历所有的inode来获取。可以和上面的套路统一吗?答案很简单。我们规定inode表中的第0个inode,表示根目录,所有的访问都从这个根目录开始!好吧,这次没有了!最后让我们欣赏一下我们的文件系统架构。你不觉得这没什么特别的吗?不过这个狗屁,它叫文件系统后记,和linux上的经典文件系统ext2基本一样。下面是我画的ext2文件系统的结构图(字段部分只画了核心字段)。我猜你看不清楚。先说一下主要异同点:1.超级块前面是引导块,是PC联盟规定的硬盘1KB独占空间,任何文件系统都不能使用。2.ext2文件系统首先将整个硬盘分成了很多块组,但是如果只有一个块组,那和我们文件系统的整体结构是完全一样的,分别是超级块,块描述符,块位图,inodebitGraphs,inodetables,datablocks。3、ext2文件系统的inode表使用15块来定位文件,其中第13块为一级间接索引,14为二级间接索引,15为三级间接索引。4、ext2文件系统文件类型较多,常见的有块设备文件、字符设备文件、管道文件、socket文件等。5、ext2文件的超级块、块描述符、inode表system记录了更多的信息,但是核心和我们的文件系统是一样的,在后续的ext3、ext4中不断增加这些字段,以保持向前兼容。6、ext2文件系统的2号inode是根目录,而我们的系统是用0号inode作为根目录。如果您想了解ext2文件系统的全部细节,可以通过三种方式。1.看源码,linux1.0以后的源码都有ext2文件系统的实现,源码最准确。2.看官方文档,这里有pdf链接。https://www.nongnu.org/ext2-doc/ext2.pdf3。阅读优质博客,这里推荐一篇。http://docs.linuxtone.org/ebooks/C&CPP/c/ch29s02.html4。使用linux的mke2fs命令生成ext2文件系统的磁盘镜像,然后逐字节分析其格式,可以在公众号低并发编程回复ext2得到我的镜像分析文件。如果不难看源码和官方文档,当然我主要推荐这两个,因为毕竟是第一手资料。但是一般人可能做不到,有时候也没有必要,所以一些好的博客也可以看看。对于思路的引入,我觉得我的文章算是非常优质的一篇了。它会从设计者的角度带你理解文件系统为什么要这样设计。那些介绍细节的,连文件系统的格式和字段都写错的,千万别看,所以我在这里凭良心推荐一篇文章,也就是上面的第三种方法,大家可以放心大胆的,一个字一个字地吃。最后,也可以使用方法4自行导出文件系统镜像进行分析。本文转载自微信公众号《低并发编程》,可通过以下二维码关注。转载本文请联系低并发编程公众号。本网站已获得低并发编程许可。