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

        block_dev.c程序是块设备文件数据访问操作程序,里面涉及到对块设备文件的读写函数。

  

代码分析:

       由于是块设备的读写操作,所以每一次都是以块为单位(1024)进行操作;pos是文件的位置光标,用pos可以得到文件现在所处在哪块逻辑块上,并且在该逻辑块上偏移了多少。再根据块的大小  可以得到该逻辑块还剩下多少空间。最后跟需要写入的字符数比较,如果该逻辑块剩下的空间足够存放需要写入的字符,则读取该逻辑块到缓存区,然后进行数据的写入;否则,先填满逻辑块剩下的空间,然后再读取下一个逻辑块; 

        技术分享


block_write()

        int block_write(int dev, long * pos, char * buf, int count)函数,把用户空间buf中count个字符从pos位置开始写入到dev设备上;
        功能:在dev设备上pos处开始把用户空间buf中的count个字符 写入到设备上
        参数:dev   设备号;pos  文件光标;buf  用户空间;count 字符数;
        实现:
       1、根据pos得到现在文件的光标位置所在的逻辑块号,和在该逻辑块上的偏移量;
       2、计数该逻辑块剩下的空间是否能够存放count个字符;
       3、映射得到逻辑块,并且把字符写入到缓存区中;
       4、设置一些属性变量

//数据块写函数  向指定设备从给定偏移处写入指定长度的数据
//设备号   pos 设备文件中偏移量指针  buf 用户空间中缓存区地址 count 要写入的数据长度
int block_write(int dev, long * pos, char * buf, int count)
{
	int block = *pos >> BLOCK_SIZE_BITS;// 相当于整除1024,得到第几个逻辑块
	int offset = *pos & (BLOCK_SIZE-1); // 开始写入的逻辑块位置
	int chars;
	int written = 0;
	struct buffer_head * bh;
	register char * p; //寄存器变量

	while (count>0) {
		chars = BLOCK_SIZE - offset;//得到开始写入的逻辑块中有多少空白位置
		if (chars > count)//如果该块剩下的位置能够满足写入字数要求
			chars=count;
		if (chars == BLOCK_SIZE)
			bh = getblk(dev,block);//如果是一块逻辑块,则用这个函数获取
		else
			bh = breada(dev,block,block+1,block+2,-1);//预读取2块逻辑块
		block++;
		if (!bh)
			return written?written:-EIO;
		p = offset + bh->b_data;//指向开始写入数据的缓存区
		offset = 0;//完成一个逻辑块的写入
		*pos += chars;//整个的文件偏移量要往后推
		written += chars;//统计下写入的字数
		count -= chars;//统计下还要写入多少个字数
		while (chars-->0)//这里就开始写入了
			*(p++) = get_fs_byte(buf++);
		bh->b_dirt = 1;
		brelse(bh);
	}
	return written;
}


block_read()

        int block_read(int dev, unsigned long * pos, char * buf, int count)函数,从dev设备上pos位置处开始读取count个字符到用户空间buf内;
        功能:从dev设备上pos开始处读取count个字符到用户空间buf内;
        参数:dev   设备号;pos  文件光标;buf  用户空间;count 字符数;
        实现:
                    其实读取字符的原理和写入是一样的;

//读取数据块函数  从指定设备和位置处读入指定长度的数据到用户空间(用户缓存区)
//dev 设备号;pos 文件整个偏移量;buf 用户空间;count 读取的数字个数;
int block_read(int dev, unsigned long * pos, char * buf, int count)
{
	int block = *pos >> BLOCK_SIZE_BITS;
	int offset = *pos & (BLOCK_SIZE-1);
	int chars;
	int read = 0;
	struct buffer_head * bh;
	register char * p;

	while (count>0) {
		chars = BLOCK_SIZE-offset;
		if (chars > count)
			chars = count;
		if (!(bh = breada(dev,block,block+1,block+2,-1)))
			return read?read:-EIO;
		block++;
		p = offset + bh->b_data;
		offset = 0;
		*pos += chars;
		read += chars;
		count -= chars;
		while (chars-->0)
			put_fs_byte(*(p++),buf++);
		brelse(bh);
	}
	return read;
}

        转载请注明作者和原文出处,原文地址:http://blog.csdn.net/yuzhihui_no1/article/details/44649549

        若有不正确之处,望大家指正,共同学习!谢谢!!!


郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。