1.理解硬件
1.1磁盘、服务器、机柜、机房
机械磁盘是计算机中唯一的一个机械设备
- 磁盘--- 外设
- 慢
- 容量大,价格便宜
1.1.1光盘
![]() |
![]() |
![]() |
1.1.2服务器
1.1.3机房
1.2磁盘的物理结构
1.3磁盘的存储结构
一个盘片又两个面
每个面都有一个磁头
磁头沿着盘面的半径移动
1.3.1 CHS地址定位
CHS(Cylinder Head Sector):柱面,磁头,扇区定位法:
- 确定哪一个磁头------找到在哪一个盘面
- 确定磁头位置---------找到在哪一个柱面
- 磁盘旋转---------------找到在哪一个磁道
项目 | 说明 |
---|---|
扇区(Sector) | 磁盘读写的最小单位,常为 512 字节 |
磁头数(Heads) | 每个盘片有上下两面,每面一个磁头 → 磁头数 = 盘片数 × 2 |
磁道数(Tracks) | 从盘片外圈向内编号(0 开始),最内圈用于停靠磁头,不存数据 |
柱面数(Cylinders) | 同一半径上的多面磁道构成一个柱面,柱面数 = 每面磁道数 |
每道扇区数 | 每条磁道被等分成若干扇区,每道的扇区数相同 |
圆盘数(Platters) | 磁盘中的物理盘片数量 |
磁盘容量 | 磁盘容量 = 磁头数 × 柱面数 × 每道扇区数 × 每扇区字节数 |
补充说明 | 磁头安装在传动臂上,共进退(即所有磁头同时定位到相同柱面) |
1.4磁盘的逻辑结构
1.4.1 理解过程
磁带上面可以存储数据,我们可以把磁带“拉直”,形成线性结构
那么磁盘本质上虽然是硬质的,但是逻辑上我们可以把磁盘想象成为卷在一起的磁带,那么磁盘的逻辑存储结构我们也可以类似于:
这样每一个扇区,就有了一个线性地址(其实就是数组下标),这种地址叫做LBA
1.4.2磁盘真实过程
每一个盘面上相同磁道构成柱面
某一盘面磁道展开:
某一盘面展开:
磁盘展开图:
1.4.3LBA地址定位
将磁盘转变为一维数组:
所以,每一个扇区都有一个下标,我们叫做LBA(Logical Block Address)地址,其实就是线性地址。所以怎么计算得到这个LBA地址呢?
LBA地址转成CHS地址,CHS如何转换成为LBA地址。谁做啊??磁盘自己来做!固件(硬件电路,伺服系统)
1.5 CHS&&LBA地址
1.5.1 CHS转LBA
- 磁头数*每磁道扇区数=柱面扇区数
- LBA=柱面扇区数*柱面号C+磁头号H*每磁道扇区数+扇区号S-1
- 扇区号S通常从1开始,柱面号和磁头号通常从0开始
- 总柱面,磁头数,扇区总数等信息开局由磁盘加载到内存
1.5.2 LBA转CHS
- C=LBA / 柱面扇区数(磁头数*每磁道扇区数)
- H=LBA % 柱面扇区数 / 每磁道扇区数
- S=LBA % 每磁道扇区数+1
2.文件系统
2.1块
其实硬盘是典型的“块”设备,操作系统读取硬盘数据的时候,其实是不会一个个扇区地读取,这样
效率太低,而是一次性连续读取多个扇区,即一次性读取一个”块”(block)。
硬盘的每个分区是被划分为一个个的”块”。一个”块”的大小是由格式化的时候确定的,并且不可
以更改,最常见的是4KB,即连续八个扇区组成一个 ”块”。”块”是文件存取的最小单位。
- 磁盘就是一个三维数组,我们把它看待成为一个"一维数组",数组下标就是LBA,每个元素都是扇区
- 每个扇区都有LBA,那么8个扇区一个块,每一个块的地址我们也能算出来。
- 知道LBA:块号 = LBA/8
- 知道块号:LAB=块号*8 + n. (n是块内第几个扇区)
2.2分区
其实磁盘是可以被分成多个分区(partition)的,以Windows观点来看,你可能会有一块磁盘并且将它分区成C,D,E盘。那个C,D,E就是分区。分区从实质上说就是对硬盘的一种格式化。但是Linux的设备都是以文件形式存在,那是怎么分区的呢?
柱面是分区的最小单位,我们可以利用参考柱面号码的方式来进行分区,其本质就是设置每个区的起始柱面和结束柱面号码。 此时我们可以将硬盘上的柱面(分区)进行平铺,将其想象成一个大的平面,如下图所示:
2.3节点
- Linux下文件的存储是属性和内容分离存储的
- Linux下,保存文件属性的集合叫做inode,一个文件,一个inode,inode内有一个唯一的标识符,叫做inode号
📌 再次注意:
- 文件名属性并未纳入到inode数据结构内部
- inode的大小一般是128字节或者256,我们后面统一128字节
- 任何文件的内容大小可以不同,但是属性大小一定是相同的
3.ext2文件系统
3.1 BLOCK GROUP
ext2文件系统会根据分区的大小划分为数个Block Group。而每个Block Group都有着相同的结构组
成。政府管理各区的例子
3.1.1 SuperBlock(超级块)
存放文件系统本身的结构信息,描述整个分区的文件系统信息。记录的信息主要有:bolck 和inode的总量,未使用的block和inode的数量,一个block和inode的大小,最近一次挂载的时间,最近一写入数据的时间,最近一次检验磁盘的时间等其他文件系统的相关信息。Super Block的信息被破坏,可以说整个文件系统结构就被破坏了
3.1.2 GDT(块组描述符)
块组描述符表,描述块组属性信息,整个分区分成多个块组就对应有多少个块组描述符。每个块组描述符存储一个块组 的描述信息,如在这个块组中从哪里开始是inode Table,从哪里开始是Data
Blocks,空闲的inode和数据块还有多少个等等。块组描述符在每个块组的开头都有一份拷贝。
/*
* 块组描述符(Block Group Descriptor)结构体
* 用于描述 ext2 文件系统中每个块组的元数据信息
*/
struct ext2_group_desc
{
__le32 bg_block_bitmap; /* 块位图所在的块号,用于管理该组的磁盘块分配情况 */
__le32 bg_inode_bitmap; /* inode位图所在的块号,用于管理该组的inode分配情况 */
__le32 bg_inode_table; /* inode表的起始块号,包含该组所有inode的详细信息 */
__le16 bg_free_blocks_count; /* 该组中未使用的块数量 */
__le16 bg_free_inodes_count; /* 该组中未使用的inode数量 */
__le16 bg_used_dirs_count; /* 该组中已使用的目录数量(目录inode数量) */
__le16 bg_pad; /* 保留字段,用于内存对齐 */
__le32 bg_reserved[3]; /* 保留字段,将来扩展使用 */
};
3.1.3 GlockBitmap(块位图)
Block Bitmap中记录着Data Block中哪个数据块已经被占用,哪个数据块没有被占用
3.1.4 inodeBitmap(inode位图)
每个bit表示一个inode是否空闲可用。
3.1.5 inodeTabke(节点表)
- 存放文件属性 如 文件大小,所有者,最近修改时间等
- 当前分组所有Inode属性的集合
- inode编号以分区为单位,整体划分,不可跨分区
3.1.6 Date Blocks(数据块)
- 数据区:存放文件内容,也就是一个一个的Block。根据不同的文件类型有以下几种情况:对于普通文件,文件的数据存储在数据块中。
- 对于目录,该目录下的所有文件名和目录名存储在所在目录的数据块中,除了文件名外,ls -l命令看到的其它信息保存在该文件的inode中。
- Block 号按照分区划分,不可跨分区
3.2 inode和blocks的映射关系
通过inode进行的实例:
touch text.c
ls -li
- 存储属性
- 通过inodeBitmap找到空闲的(inodeTabke)节点位置,例如此时的节点为236466,内核把文件信息记录其中。
- 存储数据
- 根据GlockBitmap(块位图)来找到空闲的数据磁盘,例如此时空闲的块为300,500,800
- 记录分配情况
- 内盘在inode中记录使用的块列表
- 添加文件名到目录
- 新的文件名text.c。linux如何在当前的目录中记录这个文件?内核将入口(263466,text.c)添加到目录文件。文件名和inode之间的对应关系将文件名和文件的内容及属性连接起来。
3.3目录与文件名与inode
- 目录也是文件,但是磁盘上没有目录的概念,只有文件属性+文件内容的概念。
- 目录的属性不用多说,内容保存的是:文件名和Inode号的映射关系
- 所以,访问文件,必须打开当前目录,根据文件名,获得对应的inode号,然后进行文件访问
- 所以,访问文件必须要知道当前工作目录,本质是必须能打开当前工作目录文件,查看目录文件的内容!
3.4路径解析与dentry
问题1:Linux磁盘中,存在真正的目录吗?
答案:不存在,只有文件。只保存文件属性+文件内容
问题2:访问任何文件,都要从/目录开始进行路径解析?
答案:原则上是,但是这样太慢,所以Linux会缓存历史路径结构
问题3:Linux目录的概念,怎么产生的?
答案:打开的文件是目录的话,由OS自己在内存中进行路径维护
Linux中,在内核中维护树状路径结构的内核结构体叫做: struct dentry
注意:
- 每个文件其实都要有对应的dentry结构,包括普通文件。这样所有被打开的文件,就可以在内存中形成整个树形结构
- 整个树形节点也同时会隶属于LRU(Least Recently Used,最近最少使用)结构中,进行节点淘汰
- 整个树形节点也同时会隶属于Hash,方便快速查找
- 更重要的是,这个树形结构,整体构成了Linux的路径缓存结构,打开访问任何文件,都在先在这棵树下根据路径进行查找,找到就返回属性inode和内容,没找到就从磁盘加载路径,添加dentry结构,缓存新路径
3.5挂载
注:请翻看课堂代码
我们已经能够根据inode号在指定分区找文件了,也已经能根据目录文件内容,找指定的inode了,在指定的分区内,我们可以为所欲为了。可是:
问题:inode不是不能跨分区吗?Linux不是可以有多个分区吗?我怎么知道我在哪一个分区???
dd if=/dev/zero of=./disk.img bs=1M count=5
mkfs.ext4 disk.img
mkdir /mnt/mydisk
4.软硬链接
4.1硬链接
硬链接并非单独的真实文件,他和原来的a.out 都是inode
- aba和a.out的链接状态完全相同,他们被称为指向文件的硬链接。内核记录了这个连接数,inode263466 的硬连接数为2。
- 我们在删除文件时干了两件事情:1.在目录中将对应的记录删除,2.将硬连接数-1,如果为0,则将对应的磁盘释放。
4.2软链接
软链接的本质就是windows的快捷方式,他是真实的单独文件因为他的inode和连接的文件相同。