第一层抽象:从扇区到磁盘块请求
对上层用户来说,通过直接操作柱面C,磁头H,扇区S来读写磁盘扇区显然太麻烦了,因此需要对扇区进行编址
0号扇区显然可以规定在0柱面,0磁头,0扇区,那么1号扇区呢?
磁盘读写分为三步:移动磁臂(也成为寻道),旋转磁盘,数据传输
- 移动磁臂通常花费10ms左右,即寻道时间为10ms
- 磁盘转速为每分钟7200转,它旋转半圈大约4ms
- 现在硬盘的传输速率都在每秒几十兆字节以上,以50MBps为例,传输一个扇区512个字节需要0.01ms,即传输时间为0.01ms
基于如图所示的编址结构,C、H、S扇区地址所对应的扇区号是
s
e
c
t
o
r
=
c
×
(
H
e
a
d
s
×
S
e
c
t
o
r
s
)
+
H
×
S
e
c
t
o
r
s
+
S
sector=c\times(Heads \times Sectors) + H\times Sectors + S
sector=c×(Heads×Sectors)+H×Sectors+S
其中sector是扇区号,sectors是每个磁道的扇区数,Heads是磁盘的磁头数量。再将这个公式简单变形就可以得到:
s
e
c
t
o
r
=
(
C
×
H
e
a
d
s
+
H
)
×
S
e
c
t
o
r
s
+
S
sector = (C \times Heads + H) \times Sectors +S
sector=(C×Heads+H)×Sectors+S
此时再根据扇区号sector来算出C、H、S就很容易了,即
S
=
s
e
c
t
o
r
%
S
e
c
t
o
r
s
S = sector \% Sectors
S=sector%Sectors
H
=
=
s
e
c
t
o
r
/
S
e
c
t
o
r
s
%
H
e
a
d
s
H = = sector /Sectors\% Heads
H==sector/Sectors%Heads
S
=
s
e
c
t
o
r
/
S
e
c
t
o
r
s
/
H
e
a
d
s
S = sector/ Sectors/Heads
S=sector/Sectors/Heads
实际上,多个连续的扇区就是一个磁盘块。引入磁盘块以后用户读写磁盘的基本单位就不再是扇区,而是磁盘块了。
第二层抽象:多进程产生的磁盘块的请求队列
经过第一层抽象以后,我们只要告诉操作系统系统读写的磁盘块就可以完成磁盘读写。而经过第二层抽象以后,磁盘读写会变成这个样子:想进行磁盘读写的进程首先建立一个磁盘请求数据结构,并在这个数据结构中填上要读写的盘块号,然后将这个数据结构放入磁盘请求队列中就完成了“磁盘读写”。剩下的工作交给操作系统完成,对用户完全透明。第二层的核心就是磁盘调度算法。
经过该层抽象以后,操作系统要处理磁盘读写完成如下工作:
- 从队列中选择一个磁盘请求
- 取出请求读写的盘块号
- 根据盘块号计算出C,H,S
- 用Out语句向磁盘控制器发出具体指令
磁盘调度算法
第三层抽象:从磁盘请求到高速缓存
整理一下到目前为止的磁盘处理过程:操作系统处理各个进程提出的磁盘请求,根据请求中的磁盘快好在磁盘上找到相应的磁盘扇区位置,讲这些扇区督导内核态内存中,然后由操作系统调用讲存放在内核太内存中的磁盘数据复制到用户态内存中,用户态程序操作用户态内存中的数据
高速缓存 是磁盘管理的又一层抽象,即操作系统将磁盘数据“变成”一系列位于 内核态内存 中的缓存内容。具体来说,从用户角度出发,磁盘读写变成了高速缓存读写,用户向高速缓存发出读写请求,如果用户请求的数据在高速缓存中,操作系统会直接将信息返回;如果不在,才发出磁盘请求去读写磁盘。
当用户发出一个磁盘读写请求时,操作系统会在高速缓存中查找这个磁盘块是否已经在高速缓存中,如果在就直接返回。所以高速缓存的关键是要提供一种基址来快速查找一个磁盘块数据是否在高速缓存中。
要根据一个关键词(盘块号)来快速查找这个关键字是否在一个表中,最通常使用的数据结构就是 散列表 ,所以高速缓存要以盘块号为关键字形成一个散列表来组织那些已载入的磁盘块数据——缓存块。
如果发现高速缓存中没有用户请求的磁盘块,此时应该去读写物理磁盘,这就要求在高速缓存中取出一个空闲缓存块,用来缓存从磁盘中读出的数据,而组织空闲缓存块通常使用的数据结构就是 空闲列表 。
因此设计磁盘高速缓存的核心就是要建立两个数据结构:用一个散列表组织有内容的缓存块,再用一个空闲列表组织那些空闲的缓存块,如图所示
第四层抽象:引出文件
操作系统在这一层抽象就是要将磁盘块抽象为一个字符流,经过抽象以后
- 用户看到并访问的是一个文件,是一个字符流。
- 从磁盘物理设备出发,磁盘中只有磁盘块,所以字符流最终还要存放在盘块上的
- 操作系统要将字符流读写映射为磁盘块的读写。
现在用户可以在这个字符流上随意滑动,随意处理,操作系统会根据一个映射表找打去哦和字符流位置对应的盘块号,操作系统完成从盘块号到字符流的映射。显然,实现文件抽象的关键在于建立字符流和盘块号之间的映射关系。最容易也最通常想到的存放方法是连续存放。
对于顺序存储结构,完成这个映射核心信息是文件名,起始块号,文件长度,这些信息可以用一个核心数据结构-文件控制块(FCB)来组织和保存
第五层抽象:将真个磁盘抽象成一个文件系统
操作系统中不可能只有一个文件,对一个文件到很多文件,首先要解决的就是如何组织多个文件最容易想到的组织方法就是将将很多个文件并列在一起,如图所示
如果一个磁盘上有几万个文件,并且将这几万个文件都并列在一起。如果这几万个文件用ls列出来,会是多么长的表。
文件目录树