图解文件系统

首先,不了解磁盘结构的建议去看我上篇博客,不清楚磁盘结构无法深刻理解文件系统

在我们安装操作系统时,很多时候会格式化磁盘并分区,比如分成C盘和D盘,分为100G和400G,但是操作系统直接管理100GB也是非常庞大的工作量,所以他会进行分组,假如将100GB每4GB分为25个组,那操作系统只要将每个组管理好,整块分区也就可以管理好了,这种思想在计算机中,叫做分治

大致结构如图:

一:块位图(block bitmap)

上篇博客我们说道,操作系统与磁盘每次是以块为单位进行IO,那操作系统如何知道哪些块是空着还是占用呢? 负责这件事情的就是文件系统,文件系统会创建一个块位图,块被占用就标记为1,空着就为0,(不了解位图结构的建议百度一下,很容易理解)) 快位图单独存放在一个块中,操作系统想进行存储时,就会去查看块位图,快速确定哪些块可用

二:inode 

文件 = 内容 + 属性,其中内容全部存放在data block中,那么文件属性,就会存放在inode中,每一个文件都会有一个inode,记录了除文件名以外的所有属性,且文件内容的data block编号,而inode本身会有一个编号,操作系统在找文件时,会去查找文件inode编号,找到inode后就可以迅速查找文件内容,而同样,如何确定inode有没有被占用呢,同样会有inode bitmap去确定inode是否被占用,在创建文件时,会去查找inode bitmap,将没有被占用的inode分配给文件使用,而所有inode的信息,比如inode位置,inode有没有被占用等信息,都存放在inode table中

三:组描述符(group descriptor table)

inode table是有存储上限的,如果说inode table不够用了,多出来的inode信息应该怎么办呢,答案是在其他块中存储,并且会将块位图,inode bitmap的信息都存下来,这就是组描述符

四:超级块(super block)

我们刚刚说文件系统将分区划分为一个个组,那操作系统如果想知道分区还有多少空间未被使用,或者已经使用多少,难道要一个个检测每个组的空间再相加吗,那未免也太麻烦了,所以整个文件系统的信息会存放在每个组的超级块中,可能你会疑问,每个组都有超级块,需要这么多块记录文件系统信息吗,答案是需要,因为万一有有一个超级块坏了,无所谓,把好的超级块覆盖旧的即可,但如果就一个,那坏了问题就比较大了,所以这是在进行备份,有时候文件系统损坏,windows会提醒你修复,实际上大多也是超级块损坏,操作系统会将损坏的进行覆盖

五:引导区(boot block)

安装操作系统时,引导程序会写在引导块里,并且如果你点击你的C盘或者D盘右键,你会发现每个盘符都可以进行格式化,并选择不同的文件系统,整块盘所有分区信息也存放在这里,现在常见的一般是MBR和GPT,MBR最多只支持4个主分区,如果还要更多就要添加逻辑分区,而GPT理论可创建无限分区,这块内容如果想了解可以在网上搜一下系统启动相关的知识,一般是BIOS搭配MBR,UEFI搭配GPT

---------------------------------------------------------------------------------------------------------------------------------

OK,文件系统每个块的信息大概了解后,我们来补充一些细节,比如,操作系统如何通过文件系统做增删呢?在inode中我提了一嘴,说inode中存放了对应文件的data block编号,那我们要知道的是,假如一个文件特别大,占用很多很多块,这就会产生很多data block编号,难道这些编号都要存储在inode中吗,那一个inode所占用的空间未免也太大了,有人可能会说,将文件进行连续存储,记录一下首地址,和偏移量不就能大大节省inode所占用空间了吗,事实上这样确实会减少inode空间,但是,假如你这样存放了一个4KB文件,又存放了一个5KB文件,假设将4KB进行删除,然后你又要存放一个5KB文件,明明在前面有一个4KB的空缺,但是由于你是要连续存储,就不能占用这块空间,必须在后面再找5KB进行存储,这样就形成了虽然有很多空缺的空间,但是又无法使用的情况,造成了空洞文件,所以这种做法是不可取的,那么文件系统是怎么做的呢?

首先 inode内部会存在一个数组,我们假设为 int block_number[16] ,里面用于存放block编号,当16个快要存满时,假如说要存第14个,那么文件系统首先会找一个空余的块,并将编号放到14的位置,但是这个块中并不存文件内容,而是再申请一个块,我们先称他为B块,第一次为A块,将B块中存放文件本身的内容,而将B块的编号放到A块中,操作系统在查找文件时,会从此inode中查到A块,又从A块找到B块,而如果A块存文件内容又存满了呢,那么同样,会在A块快满时再创建一个C块,将文件内容放到D块,并将D块的编号写到C块,依次类推,而一开始从inode快满时创建的A块去存放编号,这个是一级索引,再从A块中创建C块存放编号,这是二级索引,依次类推,这样在磁盘中就会有空洞文件的问题了,每一个块都可以派上用场,具体过程如图:

这是增,那么删呢,删就非常简单了,只需要将文件内容所对应的block bitmap中的1置位0,将inode bitmap对应的inode置位0,即可,表示block和inode是可被占用的,这就是他的删除,就好像什么呢,好像你偌大的房子,写了一个拆,就代表这是可被覆盖的,但文件内容本身依旧存在,这也是数据为什么能被恢复的主要原因.所以以后误删文件记住,啥也别做,万一将原本文件覆盖了,那就真的恢复不过来了

然后是目录,我们都知道目录也是文件,那么目录里存放什么呢,我在上面提到,文件属性除文件名以外存放在inode中,那么文件名呢,他就存放在目录中,目录会存放自己目录下的文件名和inode号,让他们一一对应,一个文件名对应一个inode号,形成互相映射的关系,毕竟文件名这种东西是面向用户去使用的,操作系统查找文件只需要inode号

最后梳理一下操作系统查找文件过程,当你输入find xx.txt时,操作系统首先会查看当前目录下是否有此文件,有的话会拿到文件对应的inode号,这里插一句,每个分区的inode号分布是不一样的,可能C盘是0 - 10000,而D盘是10000 - 200000,拿到inode号就能确定在哪个分区中,再确定在哪个组里,计算方式有点类似上篇博客写的磁盘LBA寻址,感兴趣的可以看看,找到在哪个组中后,看一下inode bitmap,是占用,再查看inode table,获取到inode位置信息,就可以获取到文件属性,接着就是上面说的从数组中获取data block编号,找到对应的文件内容,这样属性和内容就全部拿到了

一下午写了两篇,真累人,看来网文作者一天一两更不是在摸鱼

就写到这吧,以后还有什么细节再来进行补充

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值