Chinaunix首页 | 论坛 | 博客
  • 博客访问: 585565
  • 博文数量: 137
  • 博客积分: 4040
  • 博客等级: 上校
  • 技术积分: 1584
  • 用 户 组: 普通用户
  • 注册时间: 2009-01-08 13:05
文章分类

全部博文(137)

文章存档

2011年(10)

2010年(23)

2009年(104)

分类: LINUX

2009-08-18 23:08:15

/*
 * 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 - 要传送的字节数

    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;

    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;
}

阅读(1040) | 评论(0) | 转发(1) |
0

上一篇:file_table.c

下一篇:file_dev.c

给主人留下些什么吧!~~