/*
* buffer.c 程序用于对高速缓冲区(池)进行操作和管理。高速缓冲
* 区位于内核代码和主内存区之间。
*
* |---|---|------------------|---------------------|-------------------|
* | | | * * * | buffer | |
* |---|---|------------------|---------------------|-------------------|
* | /|/
* |------------------------------------|
* /|/
* buffer_head (list)
*/
/*
* linux/fs/buffer.c
*
* (C) 1991 Linus Torvalds
*/
/*
* 'buffer.c' implements the buffer-cache functions. Race-conditions have
* been avoided by NEVER letting a interrupt change a buffer (except for the
* data, of course), but instead letting the caller do it. NOTE! As interrupts
* can wake up a caller, some cli-sti sequences are needed to check for
* sleep-on-calls. These should be extremely quick, though (I hope).
*/
/*
* NOTE! There is one discordant note here: checking floppies for
* disk change. This is where it fits best, I think, as it should
* invalidate changed floppy-disk-caches.
*/
#include <stdarg.h>
#include <linux/config.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <asm/system.h>
#include <asm/io.h>
extern int end; // 由连接程序ld 生成的表明程序末端的变量,代表的是一个内存地址
struct buffer_head * start_buffer = (struct buffer_head *) &end;
struct buffer_head * hash_table[NR_HASH];
static struct buffer_head * free_list;
static struct task_struct * buffer_wait = NULL;
int NR_BUFFERS = 0;
/*等待指定缓冲区解锁 */
static inline void wait_on_buffer(struct buffer_head * bh)
{
cli();
while (bh->b_lock)
sleep_on(&bh->b_wait);
sti();
}
/* 同步设备(存储介质)和内存高速缓冲中数据 */
int sys_sync(void)
{
int i;
struct buffer_head * bh;
/*
* sync_inodes的主要作用是把inode_table中的inode与磁盘上的一致起来。若
* 这样笼统的理解,但是这里牵涉到系统高速缓冲区。由此,同步操作实际被分
* 成了两个阶段:
* 1. 数据结构信息与高速缓冲区中的缓冲块同步问题,由相关程序独立负责;
* 2. 高速缓冲区中数据块与磁盘对应块的同步问题,由缓冲管理程序负责。
* sync_inodes不会直接与磁盘打交道,它只能前进到缓冲区这一步.
*
* inode ------- 高速缓冲buffer --------- 硬盘
*
*/
/* 将i 节点写入高速缓冲 */
sync_inodes(); /* write out inodes into buffers */
bh = start_buffer;
for (i=0 ; i<NR_BUFFERS ; i++,bh++)
{
wait_on_buffer(bh); // 等待缓冲区解锁
if (bh->b_dirt)
ll_rw_block(WRITE,bh); // 产生写设备块请求
}
return 0;
}
/* 高速缓冲与硬盘上数据的同步 */
int sync_dev(int dev)
{
int i;
struct buffer_head * bh;
/* 高速缓冲buffer -- 存储介质 */
bh = start_buffer;
for (i=0 ; i<NR_BUFFERS ; i++,bh++)
{
if (bh->b_dev != dev) // look for the dev
continue;
wait_on_buffer(bh);
if (bh->b_dev == dev && bh->b_dirt)
ll_rw_block(WRITE,bh);
}
/* 数据结构inode -- 高速缓冲 */
sync_inodes(); // 将i 节点数据写入高速缓冲
/* 高速缓冲buffer -- 存储介质 */
bh = start_buffer;
for (i=0 ; i<NR_BUFFERS ; i++,bh++)
{
if (bh->b_dev !