1.理解硬件
1.1磁盘
- 机械磁盘是计算机中唯一的一个机械设备
- 磁盘—外设
- 慢
- 容量大,价格便宜
1.2磁盘的物理结构
1.3磁盘的存储结构
扇区:是磁盘存储数据的基本单位,512字节
,块设备
如何定位一个扇区??(CHS地址定位)
1.先确定要访问哪一个柱面(cylinder)
2.再定位磁头(header)
3.最后定位扇区(sector)
- 扇区是磁盘存储数据的基本单位,通常大小为
512字节
- 磁头数:磁盘片*2
- 磁道数:磁道是从盘片外圈往内圈编号,0磁道,1磁道,…,靠近主轴的同心圆用于停靠磁头,不存储数据
- 柱面数:等于磁面上磁道(同心圆)的个数
磁盘容量:每个扇区字节数 X 一个磁道扇区数 X 柱面数 X 磁头数
- 传动臂上的磁头是共进退的
1.4 磁盘的逻辑结构
1.4.1 理解过程
磁带上面可以存储数据,我们可以把磁带“拉直”,形成线性结构
于是,在逻辑上我们可以把磁盘想象成卷在一起的磁带,那么磁盘的逻辑存储结构我们也可以类似于:
这样,每一个扇区,就有了一个线性地址(就是数组下标),这种地址是LBA(线性地址)
1.4.2 真实过程
柱面是一个逻辑上的概念,是指所有磁面(磁盘片的正反两面)上相同编号的磁道组成的集合
所以,磁盘物理上分了很多面,但在我们看来,逻辑上,磁盘整体是由“柱面”卷起来的
所以,磁盘的真实情况:
磁道:
某一盘面的某一个磁道展开:
- 即:一维数组
柱面:
整个磁盘所有盘面的同一个磁道:
- 柱面上的每个磁道,扇区个数是一样的
- 即:二维数组
整盘:
- 即:多张二维数组(三维数组?)
所以,每一个扇区都有一个下标,我们叫做LBA地址,其实就是线性地址。那么怎么计算得到这个LBA地址呢??
1.5 CHS&&LBA地址
-
CHS转成LBA:
- 单个柱面的扇区总数=每磁道扇区数*磁头数
LBA=柱面号C * 单个柱面的扇区总数 + 磁头号H * 每磁道扇区数+扇区号S-1
- 扇区号通常是从1开始的,而LBA中,地址是从0开始的
- 柱面和磁道都是从0开始编号的
-
LBA转成CHS:
- 柱面号C=LBA / 单个柱面的扇区总数
- 磁头号H=(LBA % 单个柱面的扇区总数) / 每磁道扇区数
- 扇区号S=LBA % 每磁道扇区数 +1
从此以后,我们根本不关心CHS地址,而是直接使用LBA地址,磁盘内部自己转换。 所以:从现在开始,磁盘就是一个元素为扇区的一维数组,数组的下标就是每一个扇区的LBA地址。OS使用磁盘,就可以用一个数字访问磁盘扇区了
2. 引入文件系统
2.1 引入“块”概念
其实硬盘是典型的“块”设备,操作系统读取硬盘数据的时候,是不会一个个扇区地读取,这样效率太低,而是一次性连续读取多个扇区,即一次性读取一个“块”
一个“块”
的大小是由格式化的时候确定的,最常见的是4KB
,即连续八个扇区组成一个“块”。“块”是文件存取的最小单位
- 注意:
- 磁盘就是一个三维数组,我们把它看成一个“一维数组”,数组下标就是LBA,每个元素就是扇区
- 知道LBA:块号=LBA / 8
- 知道块号:LBA=块号*8+n(n是块内第几个扇区)
2.2 引入“分区”概念
柱面是分区的最小单位,可以利用参考柱面号的方式来进行分区,其本质就是设置每个区的起始柱面和结束柱面号
2.3 引入“inode”概念
文件=内容+属性
,使用ls -l
的时候除了看到文件名,还能看到文件元数据(属性)
$ ls -l
total 24
-rwxrwxr-x 1 tc tc 16696 Feb 19 19:51 a.out
-rw-rw-r-- 1 tc tc 79 Feb 19 19:51 code.c
包括:
- 模式
- 硬连接数
- 文件拥有者
- 所属组
- 大小
- 最后修改时间
- 文件名
文件数据都存储在“块”中,我们还必须找到一个地方存储文件的元信息(属性信息)。存储文件属性信息的区域就叫做inode(索引节点)
- 注意:
- linux下文件的存储是属性和内容分离存储的
- linux下,保存文件属性的集合叫
inode
,一个文件,一个inode
,inode
内有一个唯一的标识符,叫做inode号
- 文件名属性并未纳入到
inode
数据结构内部 inode
的大小一般是128字节
或者256- 任何文件的内容大小可以不同,但属性大小一定相同
3.ext2文件系统
3.1 初步了解
我们想要在硬盘上存储文件,必须先把硬盘格式化为某种格式的文件系统,才能存储文件。文件系统的目的就是组织和管理硬盘中的文件
linux系统中最常见的是ext2系列的文件系统。ext2文件系统将整个分区划分成若干个同样大小的块组(Block Group)。只要能管理一个分区就能管理所有分区,也就能管理所有磁盘文件
上图中启动块(Boot Block)的大小是确定的,为1KB,由PC标准规定,用来存储磁盘分区信息和启动信息,任何文件系统都不能修改启动块。启动块之后才是ext2文件系统的开始
3.2 Block Group内部组成
3.2.1 超级块(Super Block)
存放文件系统本身的结构信息,描述整个分区的文件系统信息。记录的信息主要有:block和inode
的总量,未使用的block
和inode
的数量,一个block
和inode
的大小,最近一次挂载的时间,最近一次写入数据的时间等其他文件系统的相关信息。Super Block
的信息被破坏,可以说整个文件系统结构就被破坏了。
- 超级块在每个块组的开头都有一份拷贝(第一个块组必须有,其他块组可以没有)。
- 一个文件系统的
Super block
会在多个block group
中进行备份,这些super block
区域的数据保持一致,以便在主超级块损坏时可以恢复文件系统 - 整个分区只有一个主超级块,用于管理整个文件系统
- 整个分区的超级块数量并不是由块组数量决定的
3.2.2 GDT
块组描述符表,描述块组属性信息,整个分区分成多少个块组就对应有多少个块组描述符。每个块组描述符存储一个块组的描述信息,如在这个块组中从哪里开始是inode Table
,从哪里开始是Data Blocks
,空闲的inode和数据块
还有多少个等等。
3.2.3 块位图 (Block Bitmap)
- 块位图中记录着Data Block 中哪个数据块已经被占用,哪个数据块没有被占用
3.2.4 inode位图(Inode Bitmap)
- 每个bit表示一个inode是否空闲可用
3.2.5 inode Table
- 存放文件属性,文件大小,文件所有者,最近修改时间等
- 当前分组所有inode属性的集合
- inode编号以分区为单位,整体划分,不可跨分区
3.2.6 Data Block
数据区:存放文件内容,也就是一个一个的block
- 对于
普通文件
,文件的数据存储在数据块中 - 对于
目录
,该目录下的所有文件名和目录名存储在所在目录的数据块中,除了文件名外,ls -l
命令看到的其他信息保存在该文件的inode中 - block号按照分区划分,不可跨分区
3.3 inode和datablock映射
- inode通过其内部的指针结构来定位存储文件数据的data block,这种映射方式通常有以下几种:
-
直接映射
- 描述:inode中直接包含指向data block的指针
- 优点:简单直接,访问速度快
- 缺点:如果文件很大,直接映射的指针数量有限,无法满足要求
-
一级间接映射
- 描述:inode中包含一个指针,指向一个“间接块”。这个间接块中存储了多个指向实际data block的指针
- 优点:可以支持更大的文件
- 缺点:访问数据时需要多一次间接访问(先找到间接块,再找到实际数据块)
-
二级间接映射
-
三级间接映射
-
- 知道文件的inode号,就能在指定分区中确定是哪一个分组,进而在哪一个分组中确定是哪一个inode。拿到inode文件属性和内容就全部都有了
$ touch abc
$ ls -i
263466 abc
3.4 目录与文件名
问题:
- 我们访问文件,都是用的文件名,没用过inode号啊??
- 目录是文件吗?
答案:
- 目录是文件
- 我们访问文件通常是通过文件名,而不是直接使用inode号。这是因为文件名是用户的友好接口,而inode号是文件系统内部用于管理文件的机制
- 文件名和indoe的关系:
- 文件名:是用户为文件或目录指定的标准符,用于方便用户识别和访问文件
- inode:是文件系统内部用于存储文件元数据的结构,每个文件或目录都有一个唯一的inode号
- 关系:文件名和inode通过“目录项”关联。目录本质上是一个特殊的文件,它存储了文件名到inode号的映射关系
- 当我们在文件系统中访问文件时,实际上是通过以下步骤完成的:
- 查找目录项:根据文件名在当前目录中查找对应的目录项
- 获取inode号:从目录项中提取inode号
- 访问inode:通过inode号找到对应的inode,获取文件的元数据和数据块指针
- 读取数据块:根据inode中的指针读取实际的数据块
所以,访问文件必须要知道当前工作目录,本质是必须打开当前工作目录文件,查看目录文件的内容!
tc@hcss-ecs-e1a1:~/113/linux/0220$ pwd
/home/tc/113/linux/0220
tc@hcss-ecs-e1a1:~/113/linux/0220$ ls -li
total 0
787578 -rw-rw-r-- 1 tc tc 0 Feb 20 11:41 abc
#比如:要访问abc,就必须打开0220(当前目录),然后才能获取abc对应的inode进而对文件进行访问
3.5 挂载分区
问题:inode不是不能跨分区吗??linux不是可以有多个分区吗?我怎么知道我在哪一个分区呢??
答案:
- inode不能跨分区:每个分区有独立的inode表,inode号仅在当前分区有效
- 确定文件所在分区:可以通过df , lsblk , findmnt或mount命令来查找文件所在的分区
一个结论:
- 分区写入文件系统,无法直接使用,需要和指定的目录关联,进行挂载才能使用
- 所以,可以根据访问目标文件的
“路径前缀”
准确判断我在哪一个分区