Linux基础IO拓展篇—详解文件系统
理解文件系统
在Linux基础IO篇中,我们站在用户的视角对文件进行了理解,主要是针对被打开的文件,那么有没有没有被打开的文件呢?当然有!今天我们换个视角,来站在系统的角度侧重于磁盘级别的文件是如何被存储以及管理的
要了解磁盘文件,我们先来了解一下磁盘
磁盘文件
内存是一种掉电且易失存储的介质
磁盘是一种永久性存储介质,类似的还有SSD,U盘,flash卡,光盘,磁带,都是永久性存储介质
磁盘是一个外设,并且是我们计算机内部中唯一的一个机械设备,因此,其速度非常缓慢,所以操作系统一定会有一些提速方式来提高用户体验感。
磁盘基本知识
参考以下博文:
[磁盘的结构](5 分钟图解 磁盘的结构(盘片、磁道、扇区、柱面)_磁道和扇区_一剑何风情的博客-CSDN博客)
硬盘基本知识
了解完基本结构后,我们再来思考,数据存在磁盘的哪里呢?
- 磁盘的盘面由一些磁性物质组成,可以用这些磁性物质来记录二进制数据
由于磁盘的磁道被分为一个个扇区,每个扇区就是一个“磁盘块‘,并且各个扇区的数据量是相同的(一般是512字节),因此越里面的扇区,其中二进制数据就越密集,越往外则相反。
如何在磁盘中读写数据?
- 需要把”磁头“移动到想要读/写的扇区所在的磁道,磁盘会在音圈马达的带动下转起来,让目标扇区从磁头下划过,才能完成对扇区的读/写操作。
磁盘的物理寻址方式?—CHS寻址方式
-
我们可以用柱面号,盘面号,扇区号来定义任意一个”磁盘块“。这个块号就可以转换成地址的形式
-
根据此地址,我们就能读取一个”磁盘块“
-
先根据”“柱面号”移动磁臂,让磁头指向指定柱面
-
再根据“盘面号”激活指定盘面对应的磁头
-
最后根据“扇区号”,在磁盘旋转时,指定的扇区会从磁头下面划过,这样就成功找到地址并完成读/写
文件元
文件由文件内容和文件属性构成,其中文件属性正是描述此文件的一些基本信息,比如文件名,大小以及创建时间,文件的属性由被称为元信息,也叫文件元数据:
当我们使用命令ls -l 显示的信息正是文件的属性—文件元信息:每行包含七列,其中有:
- 模式
- 硬链接数
- 文件所有者
- 组
- 大小
- 最后修改时间
- 文件名
文件元还能通过命令stat来读取更详细的信息:
文件内容与文件属性在磁盘中是分开存储的,其中保存文件元信息的结构为inode,称之为文件的编号,这个编号在所有的文件中是唯一且每个文件都有:
使用命令:ls -i 就可以查看每个文件对应的inode编号:
在详细介绍inode之前,我们先来了解一下文件结构
文件系统
前面我们提到过,数据是存储在磁盘的盘面上的,而想要进行文件的读/写操作则通过CHS寻址法来找到对应的“磁盘块”。
那这种寻址法究竟是如何做到的呢,整个文件系统又是如何运作起来的呢?
我们不妨可以这样想象一下,磁盘是圆的,但我们可以将其向磁带一样抽象成线性结构,也就是将原本是圆形的磁盘拉成直带:
经过这样一个抽象的过程,我们可以将磁盘的管理,想象成对这个数组结构的管理,而CHS寻址方式,就是通过一系列操作,将数组下标转化成对应的柱面号,盘面号以及扇区号,这样一来,想要访问一个扇区,只需要知道数组下标即可
- 将数据存储到磁盘,也就是将数据存储到数组
- 找到磁盘特定的扇区位置,就变成了找到数组的特定位置
- 对磁盘的管理也变成了对数组的管理
在我们的电脑中,有分为C盘和D盘,这又是什么意思呢?难道指的是哪个盘号吗?当然不是!磁盘会根据用户使用情况,进行磁盘分区,因此磁盘也叫块设备,分区的单位为扇区,也就是说,若磁盘上一共分了100个扇区,那么会根据用户的情况,将这100个盘区进行划分管理,比如C盘占有80个扇区,而D区占有20个扇区,这就是磁盘分区,
这样一来,对磁盘的管理,又变成了对每个分区的管理,而每个分区都会初始化,也就是磁盘格式化,会对每个分区又进行细分管理,这就相当于磁盘是一个国家,而扇区相当于国家占有的面积的划分单位,国家又细分成省份,各个省份的占地面积都不同,也就是分到的扇区大小各异,而省份又会被分为各个市,也就是分区也是要被分出来管理的,但每个分区的管理框架都一样,只是填入的信息不同:
这是Linux ext2文件系统,上图为磁盘文件系统图(内核内存映像肯定有所不同),磁盘是典型的块设备,硬盘分区会被划分为一个个的block(框架)。一个block的大小是由格式化的时候确定的,并且不可以更改。例如mke2fs的-b选项可以设定block大小为1024、2048或4096字节。而上图中启动块(Boot Block)的大小是确定的,
Block Group:ext2文件系统会根据分区的大小划分为数个Block Group。而每个Block Group都有着相同的结构组成。
超级块(Super Block):存放文件系统本身的结构信息。记录的信息主要有:bolck 和 inode的总量,未使用的block和inode的数量,一个block和inode的大小,最近一次挂载的时间,最近一次写入数据的时间,最近一次检验磁盘的时间等其他文件系统的相关信息。Super Block的信息被破坏,可以说整个文件系统结构就被破坏了
GDT,Group Descriptor Table:块组描述符,描述块组属性信息
块位图(Block Bitmap):Block Bitmap中记录着Data Block中哪个数据块已经被占用,哪个数据块没有被占用
inode位图(inode Bitmap):每个bit表示一个inode是否空闲可用。
i节点表(inode Table):存放文件属性 如 文件大小,所有者,最近修改时间等
数据区(Data blocks):存放文件内容
- Super Block
Super Block是需要被备份的,因为磁盘有可能会出现物理上的数据丢失,其里面记录的整个文件分区的属性集合就会随之丢失,因此在每一个分区中都会有Super Block的备份,并且因为记录的都是整个分区的属性集合,因此看起来会很冗余,但也大大加强了对文件系统属性信息的保护。
- Data block
数据块是多个4KB(扇区*8)大小的集合,保存的都是特定文件的内容
为什么不以扇区大小为单位?
-
虽然磁盘的基本单位是扇区(512字节),但是操作系统(文件系统)和磁盘进行IO的基本单位是4KB,因此磁盘又被称为块设备,如果以512字节为单位进行IO会导致多次的IO,进而导致效率的降低。还有一个原因就是如果操作系统和磁盘使用一样的大小,如果换了磁盘使得磁盘大小变化,那么操作系统的源代码也得跟着变化,所以这样做有利于软硬件之间的解耦合。
-
inodeTable
前面我们提到过,Linux下文件内容与文件属性在磁盘中是分开存储的,其中保存文件元信息的结构为inode,称之为文件的编号,这个编号在所有的文件中是唯一且每个文件都有。
inode本质究竟是什么?
inode是一个大小为128字节的空间,保存的是对应文件的属性,inodeTable其实就是所有文件的inode空间的集合,由于每个文件都对应自己的属性,且inodeTable块组内存在着所有文件的inode空间与文件一一对应,因此这些空间是需要被标识且具有唯一性,也就是每一个inode空间都要对应一个inode编号,这样才能将文件对应的文件属性与inode联系起来并将文件属性保存在inode内。
一般而言,一个文件一个inode,一个inode编号,文件内容就在datablock中申请空间并写进去
- Blockbitmap
blockbitmap利用位图的思想用来判断datablock有没有被占用,假设有100个datablock,就有100个比特位,每个比特位和特定的block是一一对应的,若比特位被置为1则表示该block被占用
- inodebitmap
同理blockmap,inodebitmap也是利用了位图的思想,不过是用来判读inode空间有没有被占用
- Group descriptor table
块组描述符,用来描述块组大小,已用空间,inode个数,被占用inode个数,剩余inode个数,datablock个数等到信息
一个文件只有对应一个inode编号,那只能有一个datablock吗?
肯定不是的!因为inode是描述文件属性的,文件的属性当然只能是特定的,因此只对应一个inode空间,在inode空间会存放该文件对应在数据块中申请的内容空间的位置,以此来找到对应的文件内容:
struct inode
{
//文件大小
//文件inode编号
//其他属性
//存放文件内容的数据块的位置
int blocks[SIZE];
};
创建一个文件,系统做了什么?又是如何将文件内容与属性分开存放的?
主要有四个操作:
-
存储属性
内核先遍历inodebitmap,找到一个空闲的i节点(这里是263466)并将此比特位置为1。然后在inodeTable中,找到此inode对应的inode空间,内核把文件信息记录到其中。
-
存储数据
该文件需要存储在三个磁盘块,内核找到了三个空闲块:300,500,800。将内核缓冲区的第一块数据
复制到300,下一块复制到500,以此类推。
-
记录分配情况
文件内容按顺序300,500,800存放。内核在inode上的磁盘分布区记录了上述块列表。也就是将块编号填入了inode中
-
添加文件名到目录
新的文件名abc。linux如何在当前的目录中记录这个文件?内核将入口(263466,abc)添加到目录文
件。文件名和inode之间的对应关系将文件名和文件的内容及属性连接起来。
理解创建文件名的最后一步:添加文件名到目录:
- 目录本身也是文件,有自己的datablock,其datablock中存储的是目录存放的文件的文件名与inode间的映射关系,因此创建文件最后一步,就是要把文件名与inode的映射关系通过写到磁盘上目录对应的datablock中,因此同一目录下文件名不能重复也就是因为inode是唯一的。这也能解释为什么创建文件要有写权限,访问文件名需要有r权限,因为创建文件就是对目录文件的datablock进行写入的过程!访问文件名则需要到目录文件的datablock读的过程!
为什么删除文件比创建文件快?
- 因为删除文件只需要将inodebitmap中对应的inode编号和blockbitmap对应的数据块位置 置为0->无效化。而inodeTable中对应的inode空间和datablock中的内容是不做处理的,因为不需要,他们是可以被覆盖写的,所以删除文件速度快,顺便说一下,如果误操作删除了文件,短时间内是可以恢复的,只要不进行创建文件等操作将被删除的inode号申请走了并进行了覆盖,在下一次被覆盖之前,都可以恢复。
以上就是文件系统的全部内容,如果有帮助的话,你的三连是我学习的最大动力!如果有不正确的内容,欢迎批评指正!!
软硬链接
是不做处理的,因为不需要,他们是可以被覆盖写的,所以删除文件速度快,顺便说一下,如果误操作删除了文件,短时间内是可以恢复的,只要不进行创建文件等操作将被删除的inode号申请走了并进行了覆盖,在下一次被覆盖之前,都可以恢复。
以上就是文件系统的全部内容,如果有帮助的话,你的三连是我学习的最大动力!如果有不正确的内容,欢迎批评指正!!