前言
在上一篇文件描述符详解中谈论的都是打开的文件,但是在我们的系统中不仅有打开的文件还有许多未打开的文件,那么这些未打开的文件又该如何理解呢?阅读完本篇文章相信你会得到答案。
如果觉得文章内容对你有所帮助的话,可以给博主一键三连哦!!!
博主水平有限,如果内容有错或者有不足的地方,还望指出,谢谢!!!
背景知识
认识磁盘的结构
磁盘结构主要包括:盘片、磁头、音圈马达、主轴马达、控制电机等部分。
- 盘片:是磁盘存储数据的核心部件,通常由玻璃或铝制成,并涂有一层磁性材料。这些盘片两面都可以用于数据存储。
- 磁头:是用于读写磁盘数据的部件,每个盘片上下两面各有一个磁头。磁头悬浮在盘片表面非常微小的距离内,避免与盘片接触。
- 主轴马达:位于盘片的中心,负责驱动盘片以恒定的速度旋转。
磁盘的存储结构
在每一个磁盘的盘片上划分了一个个同心圆,这一个个同心圆称为磁道,在磁道上又进一步划分了扇区,磁道是由一个个扇区组成的,所以扇区是磁盘存储数据的基本单位。一般扇区的大小是512字节。
在读写数据时,首先需要将磁头移动到想要读写的扇区所在磁道上,然后通过主轴带动磁盘转动,直到对应的扇区经过磁头,才能完成对扇区的读写操作。
文件系统
磁盘的物理结构是圆形的,可以把上面的磁道抽象成一个拉直以后的一维数组并且这个数组非常的大,而这个扇区将数组划分为了一个个区域(每个扇区能存储一定数量的数据),想要访问一个扇区,只要知道数组的下标即可。
而这一个个扇区内就包含了一个文件系统
Linux ext2文件系统,上图为磁盘为文件系统图(内核内存映像肯定有所不同),磁盘是典型的块设备,磁盘分区被划分一个个的Block。一个Block的大小是由格式化的时候确定的,并且不可以更改。这样一层一层的划分多个区域就好比一个国家太大了不好管理,那么就需要将一个国家划分为一个个省去管理,但是一个省又太大了,再划分为一个个市去管理,市又划分为一个个县…… 这样划分的目的也就是为了方便管理。
- Block group:ext2文件系统会根据分区的大小划分为数个Block group。而每个Block group都有着相同的结构组成。
- Super Block:存放文件系统本身的属性信息。记录的信息主要有:Block和 inode的总量,未使用的Block和inode的数量,一个Block和inode的大小,最进一次挂载的时间,最近一次写入数据的时间,最近检验磁盘的时间等其他文件系统的相关系统,每个Block group中可能都会有Super Block用于在异常情况下对数据进行恢复。Super Block的信息被破坏,可以说整个文件系统就被破坏了。
- Group Descriptor Table:块组描述符,描述块组属性信息
- Block Bitmap:用了位图的思想,Block Bitmap中记录着Data Block中哪个数据块已经被占用,哪个数据块没有被占用。
- inode Bitmap:每一个比特位表示一个inode是否空闲可用
- inode Table:存放文件属性,如文件大小、所有者、最近修改时间等
- Data blocks:存放文件内容
每个文件都有一个inode的编号,并且每个inode编号都是不一样的,所以inode编号可以用来标识一个唯一的文件。
我们都知道在一个目录下是可以保存多个文件的,并且一个目录下的文件都必须是不重名的,所以在一个目录下文件具有唯一性,根据Linux下一切皆文件,那么目录也是一个文件,是文件就有自己的inode和data Blocks,只不过目录的data Blocks中存的就是目录下的文件名和inode的映射关系。因为同一个目录下文件唯一,inode的值也是唯一的,所以文件名和inode可以互为key值。
所以我们在Linux下创建一个目录时要有x权限(执行权限),目录要求要有w权限(写权限)才能在目录下创建文件(要将文件名和inode的映射关系写入目录的data blocks中),目录具有r权限(读权限)那么你在使用ls -l命令时才能显示该目录下的文件名和属性(从data Blocks中读取相应的文件信息)。
有了上面的知识,那么我们就可以来回答一下下面的问题了
创建文件时,系统做了什么?
首先找到一个分区,在分区中找到一个块组(Block group),在块组中的inode Bitmap中找到一个空闲的inode,找到之后将文件的属性写入inode Table中,将Data blocks中的内容清空(因为刚创建的文件内容为空),然后再Block Bitmap中将对应的Data blocks置为1,最后再将文件名和inode编号写入当前目录中,这样就完成了一个文件的创建。
删除文件时,系统做了什么?
根据用户提供的文件名,到目录中的data Blocks中找到对应的文件名和inode的映射关系,知道了inode再到inode Bitmap和Block Bitmap中将对应的比特位由1置为0,然后再到目录的将文件名和inode的映射关系删除,此时就完成了删除文件的操作。 删除文件时不需要将Data blocks清空,只要将次区域标定为无效即可。所以你经常会看到拷贝一个文件要比删除文件花的时间更多。
那么删除的文件也是可以恢复的,只要你还能找到这个文件的inode就能将文件的数据进行恢复(前提是这个inode编号还没有被使用并且inode Bitmap和Block Bitmap中没有被重复占用)。
查看文件时,系统做了什么?
在目录中找到文件名和inode的对应关系,拿到inode之后,通过inode到inode Table中拿到文件的属性,然后再通过Block Bitmap拿到Data blocks中的内容