Ext系列文件系统
目录
磁盘是利用磁记录技术存储数据的设备,断电后数据不丢失,是计算机最主要的持久化存储介质,由于内存是掉电易失存储介质,所以目前所有的普通文件都是在磁盘中存储的。
我们在基础I/O中主要讲到的是被打开的文件,他们属于内存文件;而那些没有打开的文件都存放在磁盘里,那这些文件又是怎样被我们找到的呢?
我们都知道文件是一个目录结构,而目录结构是树状的,可以通过路径(绝对和相对)来找到
1.磁盘的物理结构

只是看这个还不足以,我们需要观察磁盘的储存结构和逻辑结构来深入的了解磁盘
2.磁盘的储存结构

将磁盘抛开内部其实是这样的,中间有一个转轴,转轴上有1~5个盘片,每个盘片上下两面有读写磁头磁头在机械臂杆(转动臂)的作用下,共进退!由于存在不止一个磁头,所以磁盘在写入的时候是向柱面(不同盘片相同半径的磁道组成的圆柱)进行批量写入的

盘片可以看作以下结构:(我们将每个扇区拉直就可以看作成线型结构)

我们该如何定位一个扇区呢?可以通过C(磁道)H(磁头)S(扇区)地址定位

3.磁盘的逻辑结构
我们都知道磁盘的结构如下:

我们此时将柱面伸直,则可以看作成一层层二维数组

所以磁盘我们就可以看作许多二维数组结合在一起形成的三维数组,而我们又可以将二维数组一行行展开形成一维数组,所以磁盘的逻辑结构在我们看来实则全都是一维数组

所以每一个扇区都有一个下标,我们叫做LBA(线性)地址,那我们该如何得到LBA地址呢?
4.LBA&&CHS地址
CHS转化成LBA:

LBA转化成CHS:

关于两种寻址区别:CHS为物理定位,操作系统底层用;LBS为逻辑块地址,把所有扇区排成一维数组,操作系统只需给个"下标",更简单通用
二.引入文件系统
1.引入“块”的概念
OS文件系统访问磁盘不以扇区(一个扇区512字节)为单位,而是以块为单位的,一般为4KB(连续8个扇区,可调整),计算机下以块为基本单位进行读取等操作

知道LBA:块号 = LBA/8
知道块号:LAB=块号*8 + n(n是块内第⼏个扇区)
2.引入“分区”的概念
磁盘是可以分为许多个分区的,在windows中,磁盘的C盘,D盘,E盘等就可以看为分区,但在Linux眼中一切皆文件,那么它是如何分区的呢?
假设我们有800GB大小的磁盘,我们不可能一下子管理这800GB,难度太大了,我们可以把800GB划分为300,300,200(分区),所以我们可以把300GB管理好,再把管理的操作复制粘贴到300,200中,这样我们就借300GB管理了800GB空间,同理我们也可以把300GB划分为10个组(30GB),对这一个组管理好后,也相当于把300GB管理好了(分而治之)

3.引入“inode”概念
我们之前说过文件=内容+属性(inode),文件的属性大小都是一样的,而任何文件都要有自己的属性集合(后面会细讲)
注意:文件名不作为属性保存在inode中

Linux下,保存⽂件属性的集合叫做inode,⼀个⽂件有⼀个inode编号,我们可以通过ls-li来看各个文件的inode编号

inode和数据块是跨组编号的并且不能跨分区!!!
所以在同一分区中inode编号和块号是唯一的
三.ext2文件系统
1.块组的内部构成
在Linux下,文件的内容和属性是分开储存的,MBR为启动块,partition1,2为分的块组
我们在分好组后,每个组都有相同的组成结构,分别由超级块(Super Block)、块组描述符表(Group Descriptor Table)、块位图(Block Bitmap)、inode位图(inode Bitmap)、inode表(inode Table)以及数据表(Data Block)组成。

Data Blocks:用于存储文件内容,以4KB为基本单位的数据块进行存储,他占有最大的空间
inode Table:用于存放文件属性,每个文件的struct inode(大小都为128B,一个数据块能够存放32个文件的inode)
inode Bitemap/Block Bitmap:每个bit位记录着inode/Data Blocks哪个数据块被占用,哪块没被占用
GDT:类似虚表,描述分区中块组的属性信息,如在这个块组中从哪⾥开始是inode Table,从哪⾥开始是Data Blocks,空闲的inode和数据块还有多少个等等。
super Block:存放⽂件系统本⾝的结构信息,描述整个分区的⽂件系统信息。记录的信息主要有:bolck 和 inode的总量,未使用的block和inode的数量等,Super Block的信息被破坏,可以说整个⽂件系统结构就被破坏了,所以其他块组中也会存放super Block,用于备份这个关键这一信息
2.inode和Data Blocks的映射

struct inode中存在一个数组__le32 i_block[EXT2_N_BLOCKS];/* Pointers to blocks */EXT2_N_BLOCKS =15,用来进行inode与block的映射的
这15个inode中,前12个是直接索引用于直接存放数据块的编号,一级索引不保存数据块编号,保存的是新的数据块的地址(一个数据块4KB)用于存放数据块的编号,可新增1024个编号(一个编号int大小4字节);如果还是不够就启用二级索引保存的是数据块的二级指针,可新增1024*1024个编号,以此类推
3.目录和文件名
我们可以通过文件的inode,就能找到文件的所有内容
那我们不论在Linux还是Windows都是用的文件名来找到文件啊!,而文件名不属于inode中,那么文件名保存在哪里呢?
在我们访问文件时其实默认是通过路径进行访问了,而目录也是有它自己的inode,也就是说目录也是一个文件,那么它的文件内容是什么呢?是文件名和inode的映射关系,所以文件名保存在所属目录的数据内容中!!

所以在同一个目录中,文件名不能出现重复
在磁盘眼中,没有路径这个概念,保存的数据只有inode和数据内容
所以文件名->inode->进行文件查找
3.1.路径解析
所以找Linux下的任何文件,都必须从根目录(\)开始,进行路径解析来找到相应的文件

ls code.c相当于ls 当前路径/code.c,我们的路径可以看作是进程提供的

3.2.路径缓存
那么我在找这个文件时,要获取上一个路径的inode,上个路径要获取上上个路径的inode,这样做是不是效率太低了,所以OS在进行路径解析的时候会把我们历史访问的所有目录(路径)形成一个多叉树(struct dentry),进行保存

3.3挂载分区
上面我们讲了inode和数据块是跨组编号的并且不能跨分区,同一分区的inode编号和块号是唯一的,那如果我有一个文件的inode,那我该如何分辨这是哪个分区的呢?
我们在创建一个文件时,这个文件一定是在一个路径下,而这个文件也一定是在某个分区中,而这个分区一定是在这个路径中(我们可以将分区看作成一个大文件),这样我们通过在该文件中挂载分区,我们可以通过该文件的前缀根据最近原则则可以判断出这个文件在哪个分区下

所以我们如何挂载文件呢?
在我们云服务器中,我们的磁盘在文件中称为:/dev/vda,由于我们的云服务器只有一个50GB的空间,称为/dev/vda1,这个空间是没办法进入的,所以我们需要将这个分区和一个特定的目录进行关联,通过进入这个目录来进入这个分区(如果我我们有多个分区,则需要挂载到不同目录的中,通过进入不同目录来进入不同的分区)
首先,我们要模拟一个大的磁盘块(disk.img)当做一个分区

然后再格式化我们的分区(分配块组的信息)

然后我们再将这个分区挂载到我们创建的dir目录中(最后一行),mounted on表示挂载的路径,其中我们云服务的分区/dev/vda1挂载到了根目录中

挂载完成后进入这个目录也就相当于进入这个分区,然后我们就可以使用我们的分区啦!!

如果我们要分区退出这个挂载,只需要下面这个操作即可

我们不用这个分区rm删除即可
3.4.文件系统总结
所以我们在fopen没有指定路径情况下时候操作系统会给我们添加cwd,然后根据路径找到这个文件,如果需要就会通过struct编程树把文件所对应的路径节点全部打开,找到对应的文件名和对应关系,然后找到文件的inode,根据inode找到文件的属性和内容,在内核中创建struct file、struct inode、文件缓冲区等等,然后把文件的属性、inode属性进行填充,把文件属性加载到内存,文件内容加载到缓冲区里,然后把struct file对象所对应的地址在文件描述符表中进行分配给用户返回文件描述符,所以往后我们拿着文件描述符就可以找到该文件的任何信息(struct file对象,路径,inode,缓冲区)了

四.软硬链接
1.软链接
我们创建一个内容为空的test.c的软链接test-soft(由后者指向前者)

此时我们在test.c里写入信息,然后再打开test.c的软链接,发现信息也被写到了这个软链接中,软连接的内容就是目标文件的路径

软链接是一个独立的文件,因为他有独立的inode;在我们想使用路径比较长的文件时,每次打他的路径会比较麻烦;我们可以使用软链接来代替,在Windows中常用作快捷方式
2.硬链接
我们创建一个test.c的硬链接test-hard
![]()

此时我们发现test-hard和test.c对应的inode值是一样的;硬链接本质不是一个独立的文件,他没有自己的inode;硬链接本质是一个新的文件名和目标文件inode number的映射关系!(所以我们看到了test.c前面的数字由1变为了2,说明有两个文件名指向这个文件,表示硬链接数)
硬链接的作用:1.给文件进行备份 2..和..本质也是当前目录和上级目录的硬链接(因为我的dir目录没有创建新目录所以只有.指向dir故硬链接数为2)
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐

所有评论(0)