linux0.12文件系统中,高速缓冲区的实现。
在linux0.12中,内核不会直接去操作磁盘文件系统中的各种结构以及文件数据等,内核会先将它们从磁盘中拷贝到内存中的高速缓冲区,然后去操作他们。高速缓冲区是文件系统访问块设备中数据的必经要道。(fs/buffer.c
)
高速缓冲区在物理内存中的分配
高速缓冲区在物理内存中的分配,以机器的物理内存大小为16MB举例,会从内核代码结束的位置end开始到物理内存4M处结束(但中间640K~1M不会使用,它们被用于显存和BIOS ROM)。
高速缓冲区占用的物理内存(物理内存分配图的黄色部分)在初始化过程中(buffer_init()
),内存低端会被初始化成缓冲头buffer_head
,内存高端为缓冲数据块(大小为1024B);
缓冲区的数据结构
缓冲头的数据结构:
struct buffer_head {
char * b_data; /* 指向缓冲数据块的指针 */
unsigned long b_blocknr; /* 块号 */
unsigned short b_dev; /* 数据源的设备号 */
unsigned char b_uptodate; /* 更新标志:表示数据是否已更新 */
unsigned char b_dirt; /* 修改标志:0未修改,1已修改 */
unsigned char b_count; /* 使用用户数 */
unsigned char b_lock; /* 缓冲区是否被锁定 0 - ok, 1 -locked */
struct task_struct * b_wait; /* 指向等待该缓冲区解锁的任务 */
/* 这四个指针用于缓冲区的管理 */
struct buffer_head * b_prev; /* hash队列上的前一块 */
struct buffer_head * b_next; /* hash队列上的后一块 */
struct buffer_head * b_prev_free; /* 空闲表上的前一块 */
struct buffer_head * b_next_free; /* 空闲表上的后一块 */
};
其中buffer_head
中的b_data
会指向对应的缓冲块;同时在初始化过程中,会初始化缓冲头中的四个重要的指针b_prev
、b_next
、b_prev_free
和b_next_free
。
所有缓冲头会通过b_prev_free
和b_next_free
被链接成一个双向链表结构,称为空闲链表free_list
。在系统的运行过程中,所有缓冲头始终都会在空闲链表上。
其中b_prev
、b_next
指针用于hash表中散列在同一项上多个缓冲块之间的双向链接,会暂时被初始化为NULL,即不处于任何一个hash表项中。
高速缓冲区的管理,实际上可以认为是在对缓冲头的管理。缓冲块即看作磁盘文件数据在内存中的拷贝。