- 高速缓冲模块的位置是在文件子系统与(块)设备驱动程序之间。
3.1 缓冲头部
- 一个缓冲区由两部分组成:一个含有磁盘上的数据的存储器数组及一个用来标示该缓冲区的缓冲头部。
- 缓冲区是磁盘块在主存中的拷贝,是临时的唯一映射关系。
- 缓冲头部包含了一个设备号字段和一个块号字段。缓冲头部还包含一个指向该缓冲区的数据数组的指针,该数组大小至少有磁盘块那么大(512字节?)。缓冲头部还包含状态字节,状态字节是如下条件的组合:
- 缓冲区当前为上锁(忙)。
- 缓冲区包含有效。
- 该缓冲区处于延迟写。
- 内核正在从磁盘往缓冲区读数据,或正在把缓冲区的内容写到磁盘上。
- 一个进程当前正在等待该缓冲区变为空闲。
3.2 缓冲池的结构
- 内核对缓冲池使用最近最少使用算法。
- 内核维护一个缓冲区的空闲表。
- 缓冲池按照散列队列组织。
- 空闲表是散列队列里的空闲缓冲区的链表。所以空闲表可以看做散列队列的子集。
- 每个缓冲区都是磁盘块在内存的映射,总是存在于一个散列队列中。但是不一定处于空闲表中。
3.3 缓冲区的检索
- 读写磁盘块的算法使用算法getblk来对缓冲池中的缓冲区进行分配。
- 在算法getblk中内核把一个缓冲区分配给磁盘块时可能出现的五种典型情况:
- 该块在散列队列,并且缓冲区空闲。
- 该块不在散列队列,因此,从空闲表中分配一个缓冲区。
- 该块不在散列队列,并且,在空闲表中找到标记为延迟写的缓冲区。内核必须把该缓冲区写到磁盘上,并分配另一个缓冲区。
- 该块不在散列队列,并且,空闲表已空。
- 该块在散列队列,但它的缓冲区当前为忙。
3.4 读磁盘块与写磁盘块
- 同步同bread
- 预先读breada (同步读第一块,异步读第二块)
- 同步写bwrite
- 延迟写:标记缓冲区为延迟写,放到空闲表头部
3.5 高速缓冲的优点和缺点
- 优点
- 缓冲区的使用提供了统一的磁盘存取方法。
- 内核实现数据对齐,方便了用户进程。
- 减少访盘次数,提高系统吞吐量。
- 有助于确保文件系统的完整性。因为缓冲区是磁盘块的一一映射,避免了进程同时访问同一磁盘块导致的错误。
- 缺点
- 用户进程无法知道数据什么时候真正写到磁盘上了。
- 增加了用户态和内核态的数据拷贝过程。读写磁盘时,需要在内核的缓冲区和用户缓冲区之间拷贝一次。