Chinaunix首页 | 论坛 | 博客
  • 博客访问: 163385
  • 博文数量: 35
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 294
  • 用 户 组: 普通用户
  • 注册时间: 2013-08-11 14:55
个人简介

努力奋斗的骚年!

文章分类

全部博文(35)

文章存档

2014年(19)

2013年(16)

分类: LINUX

2014-04-18 14:08:12

/*
 * linux/fs/block_dev.c
 *
 * (C) 1991 Linus Torvalds
 */


#include <errno.h>

#include <linux/sched.h>
#include <linux/kernel.h>
#include <asm/segment.h>
#include <asm/system.h>
//是以“块”为单位读写的

int block_write(int dev, long * pos, char * buf, int count)// 数据块写函数 - 从高速缓冲区向指定设备(块设备,如硬盘)从给定偏移处写入指定长度字节数据

{//参数:dev - 设备号;pos - 设备文件中偏移量指针;buf - 用户地址空间中缓冲区地址,count - 要传送的字节数

//
*pos (32bit) 的组成是 低10位是。这是因为 BLOCK_SIZE=1024=0x400 所以 BLOCK_SIZE-1=1023=0x3FF,所以
 int offset = *pos & (BLOCK_SIZE-1);
所以offset = *pos & 0x3FF, 相当于取 *pos的低10位。

而*pos的高 22 位则是块序号
int block = *pos >> BLOCK_SIZE_BITS; 就是将 *pos右移10位,那么就只剩高22位了,所以说高22位是块序号,低10位是在块内的.

    int block = *pos >> BLOCK_SIZE_BITS;//pos 所在文件数据块号

    int offset = *pos & (BLOCK_SIZE-1);//pos在数据块中的偏移值

    int chars;
    int written = 0;
    struct buffer_head * bh;       //缓冲区头数据结构
    register char * p;            //register修饰符暗示编译程序相应的变量将被频繁地使用,如果可能的话,应将其保存在CPU的寄存器中,以加快其存储速度。

    while (count>0) {// 针对要写入的字节数count,循环执行以下操作,直到全部写入

        chars = BLOCK_SIZE - offset;// 计算在该块中可写入的字节数。

        if (chars > count)//如果需要写入的字节数填不满一块

            chars=count;
        if (chars == BLOCK_SIZE)//如果正好要写1 块数据,则直接申请1 块高速缓冲块

            bh = getblk(dev,block);
        else//否则需要读入将被写入的数据块,并预读下两块数据块,然后将块号递增1

            bh = breada(dev,block,block+1,block+2,-1);
        block++;
        if (!bh)// 如果缓冲块操作失败,则返回已写字节数,如果没有写入任何字节,则返回出错号

            return written?written:-EIO;
        p = offset + bh->b_data;//在这一块中指定要写入的位置

        offset = 0;//写数据是按块写入的,如果要写入 的数据大于1块,则第2次循环从下一块的开始写入,所以offset置0

        *pos += chars;//更新文件的当前指针,它的值直接反映到被调用函数sys_write中来,pos变量是按“址”传递参数的

        written += chars;//记录写的个数

        count -= chars;//更新还有多少数据没有写 

        while (chars-->0)//写入数据

            *(p++) = get_fs_byte(buf++);
        bh->b_dirt = 1;// 置该缓冲区块已修改标志

        brelse(bh);//并释放该缓冲区

    }
    return written;
}

int block_read(int dev, unsigned long * pos, char * buf, int count)// 数据块读函数 - 从指定设备和位置读入指定字节数的数据到高速缓冲中

{
    int block = *pos >> BLOCK_SIZE_BITS;//pos 所在文件数据块号,记住这种方法

    int offset = *pos & (BLOCK_SIZE-1);//pos在数据块中的偏移值,记住这种方法

    int chars;
    int read = 0;
    struct buffer_head * bh;
    register char * p;

    while (count>0) {
        chars = BLOCK_SIZE-offset;// 计算在该块中要读出的的字节数。

        if (chars > count)//如果需要读出的字节数不满一块,则只需读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;
}
阅读(1567) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~