日期:2014-05-16 浏览次数:21121 次
进程A是一个写盘进程,目的是往hello1.txt文件中写入str[]中的字符“ABCED”,代码如下:
void FunA();
void main()
{
...
FunA();
...
}
void FunA()
{
char str1[]="ABCDE";
int i,j;
int fd = open("/mnt/user/user1/user2/hello1.txt",O_RDWR,0644);
for(i=0;i<100000;i++)
{
write(fd,str1,strlen(str1));
}
close(fd);
}void FunB();
void main()
{
...
FunB();
...
}
void FunB()
{
char str1[]="ABCDE";
int i,j;
int fd = open("/mnt/user/user1/user2/hello2.txt",O_RDWR,0644);
for(i=0;i<100000;i++)
{
write(fd,str1,strlen(str1));
}
close(fd);
}
void FunC();
void main()
{
...
FunC();
...
}
void FunC()
{
char buffer[20000];
int i,j;
int fd = open("/mnt/user/user1/user2/hello3.txt",O_RDWR,0644);
read(fd,buffer,sizeof(buffer));
close(fd);
}
首先进程A开始执行,刚开始的流程是申请缓冲块,往缓冲块写入数据。后来缓冲区中已经没有空闲且不脏的缓冲块,只有空闲且脏的缓冲块。这就意味着,接下来要强行将缓冲区中的数据同步到硬盘,以便在缓冲区中空出更多的空间。请看getblk函数。
代码路径:fs/buffer.c
#define BADNESS(bh) (((bh)->b_dirt<<1)+(bh)->b_lock)
struct buffer_head * getblk(int dev,int block)
{
struct buffer_head * tmp, * bh;
repeat:
if ((bh = get_hash_table(dev,block)))
return bh;
tmp = free_list;
do {
if (tmp->b_count)
continue;
if (!bh || BADNESS(tmp)<BADNESS(bh)) {
bh = tmp;
if (!BADNESS(tmp))
break;
}
/* and repeat until we find something good */
} while ((tmp = tmp->b_next_free) != free_list);
if (!bh) {//bh为空,说明所有的缓冲块b_count都不为0
sleep_on(&buffer_wait);//等待
goto repeat;//重新选择
}
wait_on_buffer(bh);//找到了b_count为0的缓冲块,如果b_lock为1,则等待
if (bh->b_count)
goto repeat;
while (bh->b_dirt) {//b_dirt为1,说明目前只有空闲且b_dirt为1的缓冲块了
sync_dev(bh->b_dev);//立即同步
wait_on_buffer(bh);
if (bh->b_count)
goto repeat;
}
...
} 代码路径:fs/buffer.c
int sync_dev(int dev)
{
int i;
struct buffer_head * bh;
bh = start_buffer;
for (i=0 ; i<NR_BUFFERS ; i++,bh++) {
if (bh->b_dev != dev)
continue;
wait_on_buffer(bh);
if (bh->b_dev == dev && bh->b_dirt)//只要设备号符合是脏的,就同步
ll_rw_block(WRITE,bh);
}
...
} 代码路径:kernel/blk_drv/ll_rw_block.c
void ll_rw_block(int rw, struct buffer_head * bh)
{
unsigned int major;
if ((major=MAJOR(bh->b_dev)) >= NR_BLK_DEV ||
!(blk_dev[major].request_fn)) {
printk("Trying to re