linux0.12内核剖析 - 文件系统(三)

 

linux0.12文件系统中,高速缓冲区的实现。

在linux0.12中,内核不会直接去操作磁盘文件系统中的各种结构以及文件数据等,内核会先将它们从磁盘中拷贝到内存中的高速缓冲区,然后去操作他们。高速缓冲区是文件系统访问块设备中数据的必经要道。(fs/buffer.c

高速缓冲区在物理内存中的分配

高速缓冲区在物理内存中的分配,以机器的物理内存大小为16MB举例,会从内核代码结束的位置end开始到物理内存4M处结束(但中间640K~1M不会使用,它们被用于显存和BIOS ROM)。

physical_memory

高速缓冲区占用的物理内存(物理内存分配图的黄色部分)在初始化过程中(buffer_init()),内存低端会被初始化成缓冲头buffer_head,内存高端为缓冲数据块(大小为1024B);

buffer_init

缓冲区的数据结构

缓冲头的数据结构:

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_prevb_nextb_prev_freeb_next_free

所有缓冲头会通过b_prev_freeb_next_free被链接成一个双向链表结构,称为空闲链表free_list在系统的运行过程中,所有缓冲头始终都会在空闲链表上

其中b_prevb_next指针用于hash表中散列在同一项上多个缓冲块之间的双向链接,会暂时被初始化为NULL,即不处于任何一个hash表项中。

buffer_stru

高速缓冲区的管理,实际上可以认为是在对缓冲头的管理。缓冲块即看作磁盘文件数据在内存中的拷贝。