日期:2014-05-16 浏览次数:20893 次
进程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