blkdev.cpp

来自「类似Linux操作系统0.11版文件系统的文件系统设计和Windows下的操作程」· C++ 代码 · 共 124 行

CPP
124
字号
/*
* UNIX Like (UL)文件系统块设备驱动层
* 介于文件系统与硬件驱动层之间的模块
*/
#include "stdafx.h"
#include "UL_FileSys.h"
#include "BlkDev.h"

struct blk_dev_struct blk_dev[NR_BLK_DEV];

struct request wr_request[NR_REQUEST];

//// 锁定指定的缓冲区bh
void lock_buffer (struct buffer_head *bh)
{
	bh->b_lock = 1;
}

//// 解锁锁定的缓冲区。
void unlock_buffer (struct buffer_head *bh)
{
	if (!bh->b_lock)
		printk ("unlock_buffer: 企图解锁未被锁的缓冲区\n");
	bh->b_lock = 0;
}


//// 加入请求项。参数dev 指定块设备,req 是请求的结构信息。
void add_request (struct blk_dev_struct *dev, struct request *req)
{
	struct request *tmp;

	req->next = NULL;

	if (req->bh)
		req->bh->b_dirt = 0;	// 清缓冲区“脏”标志。
	
	// 如果dev 的当前请求(cur_request)子段为空,则表示目前该设备没有请求项,本次是第1 个
	// 请求项,因此可将块设备当前请求指针直接指向请求项,并立刻执行相应设备的请求函数。

	if (!(tmp = (dev->cur_request)))
	{
		dev->cur_request = req;
		(dev->request_fn) ();	// 执行设备请求函数,对于硬盘(3)是do_hd_request()。
		return;
	}
	panic ("add_request: 添加请求时当前设备请求结构指针不为空!\n");
}

//// 创建请求项并插入请求队列
void make_request (int major, int rw, struct buffer_head *bh)
{
	struct request *req;
	int rw_ahead;

	// 当指定的缓冲区正在使用,已被上锁时,就放弃预读/写请求。
	if (rw_ahead = (rw == READA || rw == WRITEA))
	{
		if (bh->b_lock)
			return;
		if (rw == READA)
			rw = READ;
		else
			rw = WRITE;
	}

	// 如果命令不是READ 或WRITE 则表示内核程序有错,显示出错信息并死机。
	if (rw != READ && rw != WRITE)
		panic ("make_request: 错误的块设备命令(R/W/RA/WA)\n");

	lock_buffer (bh);

	// 如果命令是写并且缓冲区数据不脏,或者命令是读并且缓冲区数据是更新过的,则不用添加
	// 这个请求。将缓冲区解锁并退出。
	if ((rw == WRITE && !bh->b_dirt) || (rw == READ && bh->b_uptodate))
	{
		unlock_buffer (bh);
		return;
	}

	req = 0 + wr_request;

	// 向空闲请求项中填写请求信息,并将其加入队列中
	req->dev = bh->b_dev;		// 设备号。
	req->cmd = rw;				// 命令(READ/WRITE)。
	req->errors = 0;			// 操作时产生的错误次数。
	req->sector = bh->b_blocknr << 1;	// 起始扇区。(1 块=2 扇区)
	req->nr_sectors = 2;		// 读写扇区数。
	req->buffer = bh->b_data;	// 数据缓冲区。
	req->bh = bh;				// 缓冲区头指针。
	req->next = NULL;			// 指向下一请求项。
	add_request (major + blk_dev, req);	// 将请求项加入队列中(blk_dev[major],req)。
}

//// 低层读写数据块函数。
// 该函数主要是在fs/buffer.c 中被调用。实际的读写操作是由设备的request_fn()函数完成。
void ll_rw_block (int rw, struct buffer_head *bh)
{
	unsigned int major;		// 主设备号(对于硬盘是3)。

	// 如果设备的主设备号不存在或者该设备的读写操作函数不存在,则显示出错信息,并返回。
	if ((major = MAJOR (bh->b_dev)) >= NR_BLK_DEV ||
		!(blk_dev[major].request_fn))
	{
		printk ("Trying to read nonexistent block-device\n\r");
		return;
	}
	make_request (major, rw, bh);	// 创建请求项并插入请求队列。
}

//// 块设备初始化函数
void blk_dev_init (void)
{
	int i;

	for (i = 0; i < NR_REQUEST; i++)
	{
		wr_request[i].dev = -1;
		wr_request[i].next = NULL;
	}
}


⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?