Linux内核源码分析--文件系统(三、buffer.c)

本文详细分析了Linux内核中文件系统的缓存操作,包括同步缓存、清缓存函数sys_sync和sync_dev的工作原理,以及缓存块的查找和管理。重点介绍了hash链表在查找缓存块中的作用,getblk函数如何获取干净的缓存块,以及bread和bread_page函数如何从设备读取数据到缓存。文章探讨了缓存效率和权重设计,并鼓励读者交流学习。
摘要由CSDN通过智能技术生成

        前面已经大概的分析了下高速缓存区相关知识,这里再来分析下几个重要的函数;

        1、清缓存:把缓存区数据和设备进行同步

        sys_sync(void)函数:首先把i节点从内存中写入到缓存块中( 把i节点写入缓存块函数:sync_inodes(void),从内存inode_table[]  i节点数组中扫描修改过的i节点,然后根据i节点号把所处的整块逻辑块都读取到缓存块中,接着把内存中修改过的i节点存放到缓存块相应位置);扫描缓存区中所有缓存头结构,如果已经修改过就发出设备写请求,就会把修改过的缓存块写入到设备磁盘块中;

        sync_dev(int dev)函数是对指定的块设备进行数据同步,而上面的是对所有缓存区进行数据同步,因为两个清缓存函数类似,所以就挑一个具有代表性的分析下:

//对指定设备进行高速缓存区数据和设备上数据进行同步
//这里采用先让修改的缓存数据和设备块数据同步,
//然后把i节点写入到高速缓存区中,最后再次让缓存区和设备块数据同步。
//这样做是,第一次同步,可以把脏块同步干净,然后把i节点写入高速缓存区中,
//这时候同步i节点就变的简单了。最后同步i节点和因为i节点写入而变脏的块
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);//调用写请求函数
	}
	sync_inodes();//把内存中改变过的i节点写入到缓存区中
	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);
	}
	return 0;
}


        2、缓存块插入到双链表/hash链表中,从双链表/hash链表中删除缓存块

        static inline void remove_from_queues(struct buffer_head * bh);从链表中删除缓存块,这没有什么技巧,都是些简单的链表操作;重点看下插入链表,先调整双链表,这里把插入的缓存块放到链表最后,所以会有:越靠近free_list指针的缓存头就越久没有使用(到时候查找空闲缓存头时就更有效率);然后再调整下hash链表,这个hash链表不是一一映射的,而是hash链表(或者说hash数组表),可以查看下:http://blog.csdn.net/yuzhihui_no1/article/details/43677663

//将指定缓冲区插入空闲链表尾并放入hash队列中
static inline void insert_into_queues(struct buffer_head * bh)
{
/* put at end of free list;  放到空闲链表尾部&#
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值