前面博客讲解的是内存级文件管理,接下来介绍磁盘级文件管理
文件系统分为两部分
- 内存级文件系统 : OS加载进程 ,进程打开文件, OS为文件创建struct file 和文件描述符表 ,将进程与打开的文件相连, struct file 内还函数有指针表, 屏蔽了底层操作的差异,struct file中还有内核级文件缓冲区(提高效率)
- 磁盘级文件系统: 管理磁盘上的文件
磁盘结构
它通过磁性材料或闪存技术将数据持久化存储,即使在断电后数据也不会丢失
主要分为机械硬盘(HDD)和固态硬盘(SSD)
今天我们讲解机械硬盘
机械硬盘(HDD,Hard Disk Drive)
工作原理:
使用磁性材料涂覆的旋转盘片存储数据, 比如磁性南极代表1 ,磁性北极代表0(打比方)
通过磁头在盘片上移动来读写数据
定位扇区
CHS寻址模式
在硬盘的传统寻址模式中,数据是通过柱面(Cylinder)、磁头(Head)、扇区(Sector)的组合来寻址的,这种方式被称为CHS寻址(Cylinder-Head-Sector)
扇区: 磁盘存储数据的基本单位 ,512字节, 因此,磁盘是块设备
柱⾯上的每个磁道,扇区个数是⼀样的
注意: C H都是从0编码 ,S从1编码
真实过程 ⼀个细节:传动臂上的磁头是共进退的
LBA逻辑块寻址模式
LBA(Logical Block Addressing)逻辑块寻址模式。在 LBA 模式下,我们知道硬盘上的一个数据区域由它所在的磁头、柱面(也就是磁道)和扇区所唯一确定。
在LBA地址中,地址不再表示实际硬盘的实际物理地址(柱面、磁头和扇区)。LBA编址方式将 CHS这种三维寻址方式转变为一维的线性寻址,它把硬盘所有的物理扇区的C/H/S编号通过一定的规则转变为一线性的编号,系统效率得到大大提高,避免了烦琐的磁头/柱面/扇区的寻址方式。
在访问硬盘时,由硬盘控制器再这种逻辑地址转换为实际硬盘的物理地址。
OS只需要使⽤LBA就可以了!!LBA地址转成CHS地址,CHS如何转换成为LBA地址。谁做啊??磁盘 自己来做!固件(硬件电路,伺服系统)
LBA与C/H/S 之间的转换:
LBA =柱面号C*单个柱面的扇区总数 + 磁头号H*每个磁道扇区的数量+ 扇区号S-1
=柱面号*(磁头数*每个磁道扇区数)+磁头号H*每个磁道扇区的数量+ 扇区号S-1
柱面号C = LBA//(磁头数*每磁道扇区数) 就是单个柱面的扇区总数
磁头号H =(LBA% (磁头数* 每磁道扇区数)) // 每磁道扇区数
扇区号S =(LBA% 每磁道扇区数)+1
// 代表除法向下取整
所以:从此往后,在磁盘使用者看来,根本就不关心CHS地址,⽽是直接使⽤LBA地址,磁盘内部自己转换。所以: 从现在开始,磁盘就是⼀个 元素为扇区 的⼀维数组,数组的下标就是每⼀个扇区的LBA地址。OS使用磁盘,就可以⽤⼀个数字访问磁盘扇区了。
在磁盘如何管理文件
引入"块"概念
其实硬盘是典型的“块”设备,操作系统读取硬盘数据的时候,其实是不会⼀个个扇区地读取,这样 效率太低,⽽是⼀次性连续读取多个扇区,即⼀次性读取⼀个”块”(block)。
硬盘的每个分区是被划分为⼀个个的”块”。⼀个”块”的⼤⼩是由格式化的时候确定的,并且不可 以更改,最常⻅的是4KB,即连续⼋个扇区组成⼀个”块”。”块”是⽂件存取的最⼩单位。
注意:
- 磁盘就是⼀个三维数组,我们把它看待成为⼀个"一维数组",数组下标就是LBA,每个元素都是扇区
- 每个扇区都有LBA,那么8个扇区⼀个块,每⼀个块的地址我们也能算出来.
- 知道LBA:块号 = LBA / 8
- 知道块号:LAB=块号*8+n (n是块内第几个扇区 1<= n <=8)
引入"分区"概念
其实磁盘是可以被分成多个分区(partition)的,以Windows观点来看,你可能会有⼀块磁盘并且将 它分区成C,D,E盘。那个C,D,E就是分区。分区从实质上说就是对硬盘的⼀种格式化。但是Linux的设备 都是以文件形式存在,那是怎么分区的呢?
柱面是分区的最⼩单位,我们可以利⽤参考柱⾯号码的⽅式来进⾏分区,其本质就是设置每个区的起 始柱⾯和结束柱⾯号码。此时我们可以将硬盘上的柱⾯(分区)进⾏平铺,将其想象成⼀个⼤的平面,如下图所示:
柱面大小⼀致,扇区个位⼀致,那么其实只要知道每个分区的起始和结束柱⾯号,知道每 ⼀个柱面多少个扇区,那么该分区多⼤,其实和解释LBA是多少也就清楚了.
也就是OS管理磁盘,通过分治思想,将磁盘进行分区处理,但分出的区大小还有几百GB ,进一步对区分组 分成Block Group ,直接将每个组管理好即可.
- 文件 = 内容+属性
- 文件内容存储在(Block Group)组的 Data blocks中
- 文件属性也是数据 ,linux中 文件的属性数据(比如文件的创建者、文件的创建日期、文件的大小等等)以数据结构(inode)的方式 存储
- 一个文件一个inode ,inode大小有128字节 或者256字节, inode又存在 inodetable中
- ls -l -i 可以打印出文件详细信息 包括文件的inode值