Linux的Ext系列文件系统
目录
1、理解硬件
1.1 磁盘&&服务器&&机柜&&机房
1.2 磁盘的物理结构
1.3 磁盘的存储结构
1.4 磁盘的逻辑结构
1.5 CHS && LBA(了解)
2、引入文件系统
2.1 引入"块"概念
2.2 引入"分区"概念
2.3 引入"inode"概念
3、Ext2文件系统
编辑
3.1 Data Blocks && inode Table
3.2 Block Bitmap && inode Bitmap
3.3 GDT && Super Bolck
3.4 目录
3.5 路径解析
3.6 挂载分区
4、软硬链接
4.1 软链接
4.2 硬链接
文件分为“内存级(被打开)”文件,“磁盘级(未打开)”文件。
本节主讲“磁盘级(未打开)”文件。
1、理解硬件
1.1 磁盘&&服务器&&机柜&&机房
机械磁盘(HDD),计算机中唯一的机械设备(其他部件为电子结构)。
属于外设(外部存储设备)。
速度慢,容量大,价格低。
多个磁盘是服务器的一部分。
多个服务器是机柜的一部分。
多个机柜是机房的一部分。
1.2 磁盘的物理结构
机械磁盘(HDD)的盘片写入数据本质上是“两态”的。
1.3 磁盘的存储结构
- 磁道(Track):同心圆环状的数据存储区域。从外圈向内圈编号,0磁道,1磁道...,最内圈的磁道不存储数据,用于磁头停靠。
- 柱面(Cylinder):所有盘片的相同半径的磁道组成的逻辑单元,如:第0柱面 = 所有盘片的第0磁道。柱面数 = 单个盘面的磁道数。
- 扇区(Sector):磁盘存储数据的基本单位,通常为512KB,块设备。
- 盘片(Platter):每个盘片有上下两个面,均可存储数据,每面对应一个磁头,共两个磁头。
磁盘容量 = 磁头数× 单个盘面的磁道数(柱面数)× 每道扇区数× 每扇区字节数。
如何定位一个扇区?通过CHS定址。
- 先定位柱面(Cylinder)
- 再定位磁头(Head)
- 最后定位扇区(Sector)
注意:
- 磁头在传动臂的带动下,共进退,但是不代表共写入(可以不写)。
- 柱面、磁道、磁头,编号从0开始。扇区,编号从1开始。
1.4 磁盘的逻辑结构
磁盘物理上由多个盘片(Platter)组成,但在逻辑视角下,整个磁盘可以看作是由“柱面”构成的卷状结构。类似于:
所以,磁盘的真实情况是:
磁道:
展开后,看作一维数组。
柱面:
展开后,看作二维数组。
整盘:
就是多个柱面,多个二维数组,看作三维数组,而无论多少维数组,都可以看作一维数组。
所以,每一个扇区都有唯一的下标,我们叫做 LBA(Logical Block Address) 地址,其实就是线性地址。
1.5 CHS && LBA(了解)
CHS -> LBA:
LBA = 柱面号C * (磁头数*每磁道扇区数) + 磁头号H * 每磁道扇区数 + 扇区号S - 1。
柱面、磁头,编号从0开始。扇区,编号从1开始。
CHS -> LBA:
- 柱面号C = LBA // (磁头数*每磁道扇区数)。
- 磁头号H=(LBA%(磁头数*每磁道扇区数))//每磁道扇区数。
- 扇区号S=(LBA%每磁道扇区数)+1。
- "//": 表示除取整。
现代操作系统和应用程序不再直接使用 CHS(柱面-磁头-扇区)地址,而是通过 LBA(Logical Block Address,逻辑块地址) 直接访问磁盘。磁盘控制器内部自动完成 LBA → 物理位置,就可以一个数字访问磁盘扇区了。
2、引入文件系统
2.1 引入"块"概念
OS 文件系统访问磁盘,不以扇区为单位(效率低),而是以“块”为单位(一般是连续的8个扇区,即4KB)。
- 文件系统的基本单位是块。
- 知道LBA:块号 = LBA / 8。
- 知道块号:LAB = 块号*8 + n.(n是块内第几个扇区)。
2.2 引入"分区"概念
块太多了,进行分区该管理。
2.3 引入"inode"概念
我们使用 ls -li 的时候看到的除了看到文件名,还能看到部分文件属性。
- Linux下文件的存储是属性和内容分离存储。
- Linux下,保存文件属性的集合为struct inode对象,一个文件,一个struct inode对象,struct inode对象内有一个唯一的标识符,叫做inode号。
3、Ext2文件系统
以Ext2文件系统为例,介绍文件系统。
-
MBR 是磁盘的“总控”结构,负责 启动引导 和 分区管理。
-
Boot Sector 是分区的“入口”,负责 加载该分区的操作系统。
3.1 Data Blocks && inode Table
- 文件 = 内容 + 属性。Linux中,文件的属性和内容 分开存储。
- 文件的内容放到Data Blocks里(基本单位是块,存储内容)。
- 文件的属性集合,本质是一个名为struct inode的结构体对象,大小一般为128字节,放在inode Table里。文件名是文件的属性,但是不放到struct inode对象中,因为大小不确定。一个块可以存储32个struct inode对象。
- Data Blocks的数据块号和inode Table的inode号,都跨组编号,但都不跨分区编号。所以在同一个分区内,数据块号和inode号都编号唯一。
struct inode和数据块的映射关系。
3.2 Block Bitmap && inode Bitmap
- Block Bitmap,数据块 位图,记录数据块是否被使用。
- inode Bitmap,struct inode 位图,记录struct inode是否被使用。
- 删除文件,对应的数据块号和inode号的位图,置为0,所以删除文件很快。
3.3 GDT && Super Bolck
- 描述组的属性的组描述符放到GDT(组描述符表)里。有多少个组,就有多少个组描述符。
- 整个分区的文件系统信息放到Super Block(超级块)里。因为比较重要,所以会在若干个组中进行备份。
3.4 目录
之前遗留了一个问题,文件名是文件属性,但是不放到struct inode中,因为大小不确定。放在哪里?
- 目录,也是文件,像文件一样存储。它的内容不是普通数据,而是 文件名 → inode 号 的映射表。
3.5 路径解析
如何读取文件?需要进行路径解析。
比如 /home/user/file.txt,文件系统会逐级查找目录项(文件名与其对应 inode 的映射关系)
- 先找
/
的 inode 号(通常是 inode 2)。 - 在
/
的数据块中找到 home 的 inode 号。 - 在 home 的数据块中找到 user 的 inode 号。
- 在 user 的数据块中找到 file.txt 的 inode 号。
有了 file.txt 的 inode 号,file.txt的文件属性和内容就都有了。
注意:
- 问题1:访问任何文件,都要从/目录开始进行路径解析?
- 答案:原则上是,但是这样太慢,所以Linux会缓存历史路径结构。使用struct dentry节点,形成一颗多叉树,使用Hash,快速查找,使用LRU机制,进行删除。文件也有struct dentry节点(里面有inode号)。
3.6 挂载分区
解析路径时,遇到"路径前缀"的挂载点(如 /mnt/data)会切换到该挂载点对应的文件系统(分区)。
例如:访问 /mnt/data/file.txt:
- 先解析 /mnt/data,发现它是一个挂载点,切换到挂载的分区,。
- 在该分区的文件系统中查找 file.txt 的 struct inode。
总结一下:
- 对于磁盘上的文件系统,给一个文件inode号,就能获得文件的属性和内容。
- 通过解析路径获得文件的inode号。
4、软硬链接
4.1 软链接
- 独立的文件,因为有独立的inode number。
- 内容是目标文件的路径。
- 用途:相当于Windows下的快捷方式。
4.2 硬链接
- 不是独立的文件,因为没有独立的inode号
- 本质是一组新的文件名和inode号的映射关系。
- 用途:备份文件速度快。
2 表示 硬链接数。
注意:
当前目录. 上级目录..,其实都是硬链接,但是不支持用户对目录的硬链接,因为容易形成路径环的问题。