1. 文件系统
文件系统是操作系统用于明确存储设备(常见的是磁盘,也有基于NAND Flash的固态硬盘)或分区上的文件的方法和数据结构,即在存储设备上组织文件的方法。
1.1 基本组成
索引节点(inode):用来记录文件的元信息,比如inode编号、文件大小、访问权限、创建时间、修改时间、数据在磁盘的位置等等。索引节点是文件的唯一标识,它们之间一一对应,也同样都会被存储在硬盘中,所以索引节点同样占用磁盘空间。
目录项(dentry):用来记录文件的名字、索引节点指针以及与其他目录项的层级关联关系。多个目录项关联起来,就会形成目录结构,但它与索引节点不同的是,目录项是由内核维护的一个数据结构,不存放于磁盘,而是缓存在内存。
数据块(data block):是文件系统读写的最小单位,用于存储文件的数据。不同的文件系统数据块大小可能不同,例如Linux中的逻辑块大小通常为4KB。
1.2 主要功能
管理和调度文件的存储空间:负责为文件分配和回收磁盘空间,提高磁盘空间的利用率。
提供文件的逻辑结构、物理结构和存储方法:定义了文件在磁盘上的存储方式和组织形式,如链式存储、索引存储等。
实现文件从标识到实际地址的映射:通过索引节点和目录项等数据结构,将用户使用的文件名转换为磁盘上的实际存储地址。
实现文件的控制操作和存取操作:提供对文件的创建、删除、读取、写入等操作的支持。
实现文件信息的共享并提供可靠的文件保密和保护措施:支持多个用户或进程对文件的共享访问,并通过访问权限等机制保护文件的安全性和保密性。
提供文件的安全措施:如文件的加密、备份与恢复等功能,保障文件数据的完整性和可用性。
这一节,我们主要认识文件系统的硬件部分,即磁盘(或硬盘)。
2. 磁盘
2.1 磁盘的分类
机械硬盘(HDD):机械硬盘是传统的磁盘存储设备,由盘片、磁头、电机、控制电路等部件组成。数据存储在盘片的磁性涂层上,磁头通过在盘片表面移动来读写数据。机械硬盘的优点是容量大、价格相对较低,适合对读写速度要求不高的大容量存储场景。
固态硬盘(SSD):固态硬盘采用闪存芯片作为存储介质,通过电子信号来存储和读取数据,不需要机械部件。固态硬盘的优点是读写速度快、抗震性强、功耗低、噪音小,适合对读写速度要求较高的场景,如系统盘、游戏盘等。
2.2 机械硬盘的存储结构
磁盘的数据就存储在圆型的磁片上,磁头可以在摇头臂的驱动下,随着盘片的高速旋转,访问到盘片表面的任意位置。
盘片的表面被分为多个存储单元,这些单元被成为扇区。
扇区:是磁盘存储数据的基本单位,每个扇区可存储512字节。
这意味着,每次对磁盘的数据进行读写都必须将一个扇区的512个字节一起加载到内存中。
通常来说,一块磁盘上有多组盘片与磁头(一个盘片对应两个面、两个磁头)。这些盘片绕着主轴进行同步的高速旋转,磁头在同一个机械臂杆的驱动下进行同步运动。
也就是说这些磁头在竖直方向上连成一条线,指向各自盘面的对应扇区。随着盘片的高速旋转,与磁道一同形成了一个柱面,如图所示。
磁盘容量 = 磁头数 × 磁道(柱面)数 × 每道扇区数 × 每扇区字节数(512)。
2.3 CHS地址定位
操作系统要访问一个文件,就需要知道该文件在哪一个扇区(或哪几个)。
那么,如何定位一个扇区呢?
- 定位扇区所在柱面(Cylinder)。
- 选择有效磁头(Header)。
- 定位扇区(Sector)。
三个参数 "Cylinder-Header-Sector" 共同构成了 "CHS地址"。
操作系统只要知道所需访问文件对应的 CHS地址 ,即可通过驱动程序完成访问。
CHS模式支持的硬盘容量有限,因为系统用8bit来存储磁头地址,用10bit来存储柱面地址,用6bit来存储扇区地址,而一个扇区共有512Byte,这样使用CHS寻址一块硬盘最大容量为256 * 1024 * 63 * 512B = 8064 MB(1MB = 1048576B)(若按1MB=1000000B来算就是8.4GB)。
2.4 LBA地址定位
我们可以将一个磁道看作一个一维数组,将一个柱面看作二维数组(在同一柱面上的每一个磁道作为二维数组的一行),那么磁盘就可以看作一个三维数组。
我们知道,无论是二维数组还是三维数组,从存储空间上来看都是一维数组首尾相接的结果。
我们按照这样的思路就可以将磁盘的存储空间映射为一维数组。
将这个磁盘抽象成的数组的下标作为扇区的地址,我们就得到了 "LBA地址"(Logical Block Address) ,即线性地址。
同样的,使用 LBA地址,操作系统就能很好的定位到扇区。只要在硬件层面上实现 "LBA地址 到 CHS地址" 的转换。
2.5 CHS 与 LBA地址的相互转换
CHS 转换为 LBA
LBA = 柱面号C * (磁头数 * 每磁道扇区数) + 磁头号H * 每磁道扇区数 + 扇区号S - 1
- 扇区通常是从1开始编号的,而柱面和磁道都是从0开始编号的。
- 在LBA中,地址是从0开始的。
- 总柱面,磁道个数,扇区总数等信息,在磁盘内部会自动维护,上层开机的时候,会获取到这些参数。
LBA 转换为 CHS
柱⾯号C = LBA / (单个柱⾯的扇区总数 = 磁头数 * 每磁道扇区数)
磁头号H = (LBA % 单个柱⾯的扇区总数) / 每磁道扇区数
扇区号S = (LBA % 每磁道扇区数) + 1
从现在开始,我们主要关注LBA 地址,将磁盘看作一个一维数组,而不再关心其底层细节了(交由硬件自动处理)。