【Linux】磁盘读写文件原理及文件系统基本概念介绍

前言:前面主要从进程的角度理解文件操作,这篇接着往下看,认识磁盘怎样保存和读写数据。


1.磁盘怎样读写数据

文件可以看作内容加属性。内容是我们写进去的文字、代码等数据,属性则包括文件大小、权限、所属用户等信息,它们都需要保存。

磁盘提供存放这些数据的空间,文件系统负责把它们组织起来,让我们能通过文件名和路径找到需要的文件。这里先从机械硬盘的结构看起。

1.1盘片、磁头、磁道与扇区

先看机械硬盘的实物结构:

中间的圆盘是盘片,主轴带动盘片旋转,旁边的磁头负责读写数据,磁头臂则带着磁头移动到不同位置。数据通过盘面上的磁性状态保存下来。

一块硬盘可以有多个盘片,盘片也可以使用上下两个盘面存储数据,每个使用中的盘面有对应的磁头。

为了描述数据的位置,还需要认识磁道和扇区:

  • 磁道:盘面上一圈圈同心圆形的轨迹。
  • 扇区:磁道进一步划分出的一段段存储区域。

绿绿的那个标记的是一个扇区。可以先找到数据在哪一圈,再找到它在这一圈的哪一段。

当然随着技术的发展肯定是会发生变换的,但是这里后面按一个扇区 512 字节来举例。

再把多个盘面放到一起看:

不同盘面上,半径相同的磁道合在一起,就构成了一个柱面。右图中上下对应的这些圆圈,看起来像一个圆柱的侧面,因此叫柱面。

1.2读写时磁盘怎样移动

比如想要读写一个扇区,磁头需要先到达相应的位置:

这个过程可以分成几个动作来理解:

  1. 找到磁道。 磁头臂移动,让磁头到达目标磁道,这个过程叫寻道;同时选择要访问的盘面所对应的磁头。
  2. 等待扇区。 盘片继续旋转,等待目标扇区转到磁头下方,这段等待就是旋转延迟。
  3. 读写数据。 位置合适后,磁头读取数据,或者把新数据写入相应区域。

图中的多个磁头由同组传动臂带着一起移动,也就是"共进退"。移动到某个位置后,各个磁头便对应同一柱面中的不同盘面。

机械硬盘的访问时间中,就包含了这些移动和等待。连续读写相邻的数据,通常可以减少反复寻道,所以比来回访问分散的位置更有利,这点的原因就像是我们之前的缓冲区存在的意义一样。

2.从 CHS 到 LBA

现在已经认识了柱面、磁头和扇区,只要给出这三个位置,就可以在传统磁盘模型中找到一个扇区。这种表示方法叫作 CHS。

字母 含义 解决的问题
C Cylinder,柱面 位于哪一个柱面
H Head,磁头 访问哪个盘面上的磁道
S Sector,扇区 位于这条磁道的哪一个扇区

也就是:确定柱面,再确定盘面,最后确定扇区。

2.1把扇区排成一条线

每次描述位置都用三个数字,理解起来比较直观。不过,对于使用磁盘的系统来说,还可以把这些扇区统一编号,用一个数字表示位置。

可以先借助磁带来理解:

磁带卷起来时是一圈圈的,拉开后就成了一条长带。磁盘的盘面虽然不会真的被拉直,但我们可以在理解时,把磁道里的扇区按顺序排开。

先看一个柱面:把不同盘面上的磁道分别展开,一行就是一条磁道,行里面的每一格就是一个扇区。

条磁道包含相同数量的扇区。一个柱面展开后,像一张二维表;整个磁盘又有多个柱面,就像有多张这样的表。

把这些表的每一行依次接起来,就可以得到一条连续的扇区序列:

从 0 开始给它们编号,每个扇区就有了自己的线性地址,这就是 LBA(Logical Block Address,逻辑块地址)。

可以把它理解成一个数组:数组元素是一个个逻辑扇区,下标就是 LBA。 图中标红的扇区,既可以用"哪个柱面、哪个盘面、哪个扇区"来描述,也可以直接用它在线性序列中的编号来描述。

2.2CHS 与 LBA 怎样换算

换算的思路和二维数组、三维数组计算元素位置很像:先数前面有多少完整的柱面,再数当前柱面中前面的磁道,最后数磁道内的位置,计算方式和位图的方式一样,但是因为哲理是三位所以会更复杂一些。

先约定几个字母:

符号 含义
H 总磁头数,也就是每个柱面中对应的磁道数量
T 每条磁道的扇区数量
c 当前柱面编号,从 0 开始
h 当前磁头编号,从 0 开始
s 当前磁道内的扇区编号,从 1 开始
L LBA 编号,从 0 开始

一个柱面包含 H × T 个扇区,所以公式是:

L = c × H × T + h × T + (s - 1)

其中三部分分别表示:

  • c × H × T:前面所有柱面占了多少个扇区。
  • h × T:当前柱面中,前面的磁道占了多少个扇区。
  • s - 1:当前磁道内,目标扇区前面还有多少个扇区。

最后减 1,是因为这里的 CHS 扇区编号从 1 开始,而 LBA 从 0 开始。

例如,按上面的线性图取 4 个磁头、每条磁道 4 个扇区。要找柱面 1、磁头 1、扇区 2,对应的 LBA 就是:

L = 1 × 4 × 4 + 1 × 4 + (2 - 1) = 21

反过来,知道 LBA,也可以通过除法和取余找回 CHS:

要求的编号 计算方式
柱面 c L ÷ (H × T),取整数部分
磁头 h 先求 L % (H × T),再除以 T,取整数部分
扇区 s L % T + 1

这样做就可以实现硬件与软件之间的解耦。

3.文件系统管理方式

LBA 让我们能找到某个扇区,但文件可能很大,也有自己的属性和名字。要把这些数据安排好,还需要继续认识块、分区和 inode。

3.1从扇区到块

文件系统组织和分配空间时,通常以**块(block)**为单位。一个文件系统块可以包含多个连续的扇区。

用前面一个扇区 512 字节的例子,如果块大小取 4KB,也就是 4096 字节,那么一个块就包含:

4096 ÷ 512 = 8 个扇区

先把扇区连续编号,再每 8 个分成一组,这一组就是一个块。这样,组织文件空间时,就可以按块来安排。

如果把这段空间的起点看作 0,那么:

  • 扇区编号除以 8,取整数部分,就能知道它属于哪个块。
  • 块号乘以 8,就是这个块的起始扇区编号。
  • 再加上块内的偏移 0~7,就能找到块中的某个扇区。

例如,块 3 对应这一段空间中的 24~31 号扇区。换成整块磁盘上的地址时,还要加上这段空间本身的起始扇区号。

3.2把磁盘划分成分区

一块磁盘的空间可以划分为多个分区,每个分区占据其中的一段逻辑范围。

例如,把一块磁盘的容量按 300GB、300GB、200GB 分成三部分,就是一种分区安排。磁盘还是同一块,只是这些空间被分别管理了。

只要记录各自从哪里开始、占多大范围,就能确定这些分区在磁盘上的位置。

分区和格式化还需要区分一下:

操作 做什么
分区 在磁盘上划出不同的空间范围
格式化 在选定的空间中建立文件系统所需的管理结构

可以理解成先划出几块场地,再在每块场地里安排东西怎样存放、怎样登记。划出范围后,还需要文件系统继续组织其中的文件。

3.3用 inode 保存文件信息

文件内容可以放进数据块,但权限、大小、所属用户等属性,又放在哪里?

我们平时使用 ls -l,看到的是文件的权限、所有者、大小、修改时间等信息。程序要获得这些信息,并不需要先把文件正文全部读出来。

它可以记录这个文件的相关属性:

信息 作用
文件类型和权限 说明它是什么类型,允许怎样访问
所有者和所属组 说明文件属于谁
文件大小和相关时间 记录内容大小、访问与修改等信息
数据位置信息 用来找到保存文件内容的数据块

文件有自己的 inode,inode 也有对应的编号,叫作 inode 号。在同一个文件系统中,可以通过这个编号区分不同的 inode。

我机器上的例子:

ls -li 比平时的详细列表多了最左边这一列,框出的数字就是 inode 号。

文件名没有保存在 inode 中。 关于这点我放在下一篇文章里再讨论吧,我也不想把一篇文章搞得太长。

其实可以在内核中看到 inode的定义结构体:

磁盘提供存储空间,文件系统把这些空间组织成可以保存、查找和使用的文件。 关于系统如何组织文件系统这点下一篇文章里再做讨论先这样吧。


完

相关推荐
东城居士1 小时前
理解Linux RTC驱动
linux·嵌入式系统
Elastic 中国社区官方博客1 小时前
使用 OpenTelemetry 在 Elastic 中实现 Claude 平台的人工智能 agent 可观测性
大数据·运维·服务器·人工智能·elasticsearch·信息可视化·全文检索
hzxxxz1 小时前
3个模块搭稳一条自动化链路:定时任务、幂等与对账
运维·自动化
蘑菇小白1 小时前
Linux多线程开发
linux·开发语言·线程
Ruiery1 小时前
Linux 6.6内核内存管理深度解析(十):KSM 同页合并 — 内容去重,把 N 份相同内存合并成 1 份
linux·运维·服务器
Huangjin007_2 小时前
【Linux 系统篇(三十三)】通信(三):System V 共享内存详解
linux·运维·服务器
叼烟扛炮2 小时前
Linux 学习笔记(三十八):从实模式到分页——处理器内存管理的发展史
linux·运维·服务器
2401_868534782 小时前
论智慧医院网络建设
服务器·网络
润滑卫士2 小时前
油液水分在线传感器技术对比:电容法、电阻法与微波法的测量原理与适用性
运维
Decay__2 小时前
附-01 · MySQL 压测与容量规划 —— sysbench 基准测试、容量评估与参数基线
运维·数据库·sql·mysql·架构