b_uptodate 和b_dirt在刚开始接触的时候容易混淆,在此浅析一下。
b_uptodate 是针对读数据的,是数据更新标志。读硬盘上的文件一般是先把文件内容读到内存缓冲区,然后
再把这个缓冲区的数据复制到要求的位置。如果现在需要读文件,且这个文件的数据已经在缓冲区了,那么
我们就检查b_uptodate,如果为1,表示数据已经更新了,不需要从文件中重新读,直接把这个缓冲区的
头指针返回就可以了。
b_dirt主要针对写数据的, 是数据脏标志,表示缓存区的数据已经被修改。同样,我们需要向硬盘等外设写
数据的话,也是先把内存上的某一缓冲区和硬盘上的某一块绑定起来,然后把数据写入这个内存缓冲区。
内存上的数据并不是马上写入硬盘上,而是在适当的时候才写入。什么时候?一种是定期同步,一定时间写入
一次;另一种是缓冲区不够用的了,也会把缓冲区的数据写入硬盘。这两种同时起作用。缓冲区的很多内存块
都和硬盘上的内存某一块建立了对应,在写之前就要先检查 b_dirt,如果为1,表示这个缓冲区的数据已经更改
了,要重新写入硬盘。如果为0,表示缓冲区的数据和硬盘上的数据是一样的,一样的我们就没必要再重新写
一遍了。
缓冲区头数据结构
struct buffer_head
{
char *b_data; /* pointer to data block (1024 bytes) *///指针。
unsigned long b_blocknr; /* block number */// 块号。
unsigned short b_dev; /* device (0 = free) */// 数据源的设备号。
unsigned char b_uptodate; // 更新标志:表示数据是否已更新。
unsigned char b_dirt; /* 0-clean,1-dirty *///修改标志:0 未修改,1 已修改.
unsigned char b_count; /* users using this block */// 使用的用户数。
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; // 空闲表上下一块。
};