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

全部博文(137)

文章存档

2011年(10)

2010年(23)

2009年(104)

分类: LINUX

2009-08-18 23:58:03

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


#include <errno.h>
#include <fcntl.h>

#include <linux/sched.h>
#include <linux/kernel.h>
#include <asm/segment.h>

#define MIN(a,b) (((a)<(b))?(a):(b))// 取a,b 中的最小值。

#define MAX(a,b) (((a)>(b))?(a):(b))// 取a,b 中的最大值。

// 文件读函数 - 根据i 节点和文件结构,读设备数据

int file_read(struct m_inode * inode, struct file * filp, char * buf, int count)
{//由i 节点可以知道设备号,由filp 结构可以知道文件中当前读写指针位置。buf 指定用户态中缓冲区的位置,count 为需要读取的字节数

    int left,chars,nr;
    struct buffer_head * bh;

    if ((left=count)<=0)// 若需要读取的字节计数值小于等于零,则返回

        return 0;
    while (left) {
        if (nr = bmap(inode,(filp->f_pos)/BLOCK_SIZE)) {//根据i 节点信息取文件数据块block 在设备上对应的逻辑块号,(filp->f_pos)/BLOCK_SIZE)文件当前指针所在的数据块

            if (!(bh=bread(inode->i_dev,nr)))//从inode节点指定的设备上读取该nr逻辑块

                break;
        } else
            bh = NULL;
        nr = filp->f_pos % BLOCK_SIZE;//计算文件读写指针在数据块中的偏移值nr

        chars = MIN( BLOCK_SIZE-nr , left );//本次需要读的字节数

        filp->f_pos += chars;//更新文件当前位置

        left -= chars;//还有多少没有读的

        if (bh) {//读到逻辑号

            char * p = nr + bh->b_data;//则将p 指向读出数据块缓冲区中开始读取的位置

            while (chars-->0)//并且复制chars 字节到用户缓冲区buf 中

                put_fs_byte(*(p++),buf++);
            brelse(bh);
        } else {//没读到逻辑号

            while (chars-->0)//否则往用户缓冲区中填入chars 个0 值字节

                put_fs_byte(0,buf++);
        }
    }
    inode->i_atime = CURRENT_TIME;// 最后访问时间。

    return (count-left)?(count-left):-ERROR;
}
// 文件写函数 - 根据i 节点和文件结构信息,将用户数据写入指定文件中,(只是写入打开文件对应的高速缓冲区,何何进同步,由高速缓冲区管理程序负责)

int file_write(struct m_inode * inode, struct file * filp, char * buf, int count)
{//由i 节点可以知道设备号,由filp 结构可以知道文件中当前读写指针位置,buf 指定用户态中 缓冲区的位置,count 为需要写入的字节数

    off_t pos;
    int block,c;
    struct buffer_head * bh;
    char * p;
    int i=0;

/*
 * ok, append may not work when many processes are writing at the same time
 * but so what. That way leads to madness anyway.
 */

    if (filp->f_flags & O_APPEND)// 如果是要向文件后添加数据,

        pos = inode->i_size;//则将文件读写指针移到文件尾部。

    else
        pos = filp->f_pos;//否则就将在文件读写指针处写入

    while (i<count) {
        if (!(block = create_block(inode,pos/BLOCK_SIZE)))// 创建文件数据块pos/BLOCK_SIZE在设备上对应的逻辑块,并返回设备上对应的逻辑块号

            break;
        if (!(bh=bread(inode->i_dev,block)))//从inode节点指定的设备上读取该block逻辑块

            break;
        c = pos % BLOCK_SIZE;// 求出文件读写指针在数据块中的偏移值c

        p = c + bh->b_data;//将p 指向读出数据块缓冲区中开始读取的位置

        bh->b_dirt = 1;//置该缓冲区已修改标志

        c = BLOCK_SIZE-c;//从开始读写位置到块末共可写入c=(BLOCK_SIZE-c)个字节

        if (c > count-i) c = count-i;//若c 大于剩余还需写入的字节数(count-i),则此次只需再写入c=(count-i)即可

        pos += c;//更新文件当前指针

        if (pos > inode->i_size) {
            inode->i_size = pos;//修改文件大小

            inode->i_dirt = 1;//置修改标志

        }
        i += c;//更新子已写的字书节数

        while (c-->0)
            *(p++) = get_fs_byte(buf++);//从用户缓冲区buf 中复制c 个字节到高速缓冲区中p 指向开始的位置处

        brelse(bh);
    }
    inode->i_mtime = CURRENT_TIME;// 修改时间(自1970.1.1:0 算起,秒)。

    if (!(filp->f_flags & O_APPEND)) {// 如果此次操作不是在文件尾添加数据,

        filp->f_pos = pos;//则把文件读写指针调整到当前读写位置

        inode->i_ctime = CURRENT_TIME;// i 节点自身修改时间。

    }
    return (i?i:-1);
}

阅读(647) | 评论(0) | 转发(0) |
0

上一篇:block_dev.c

下一篇:pipe.c

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