文件使用磁盘的实现--OS

文件使用磁盘的实现

通过文件使用磁盘,代码如下

在fs/read_write.c中
int sys_write(int fd, const char *buf, int count)
//fd为文件索引,buf为缓冲区,count表示要处理的字符串长度
{
    struct file *file = current->filp[fd];
    struct m_inode *inode = file->inode;
    if(S_ISREG(inode->i_mode))
        return file_write(inode, file, buf, count);
}

我们理一下file_write的工作过程

file_write(inode, file, buf, count)

  1. 根据file还有count找到字符流的位置如(200-212)
  2. 根据inode映射表找到对应的盘块号
  3. 进行读写操作

file_write的实现

int file_write(struct m_inode *inode, struct file *filp, char *buf, int count)
{
    off_t pos;
    if(filp->f_flags&O_APPEND)
        pos = inode->i_size  
        //i_size是文件的大小,当文件为写操作时,读写指针就在末尾处
    else
        pos = filp->f_pos  //f_pos是文件的读写指针,指向上一次读写的位置
    while(i<count)
    {
        block=create_block(inode, pos/BLOCK_SIZE); //计算出盘块号
        bh=bread(inode->i_dev, block); //磁盘读
        int c=pos%BLOCK_SIZE;
        char *p=c+bh->b_data;
        bh->b_dirt=1;
        c=BLOCK_SIZE-c;
        pos+=c;  //修改pos的位置
        ...
        while(c-->0)
            *(p++) = get_fs_byte(buf++);
        brelse(bh);
    }
    filp->f_pos=pos;
}

create_block算盘块,文件抽象的核心

while(i<count)
{
    block = create_block(inode, pos/BLOCK_SIZE);
    bh=bread(inode->i_dev, block);
}
int _bmap(m_inode *inode, int block, int create)
{
    if(block<7)
    {
        if(create&&!inode->i_zone[block])
        {
            inode->i_zone[block]=new_block(inode->i_dev);\
            inode->i_ctime=CURRENT_TIME;
            inode->i_dirt=1;
            return inode->i_zone[block];
        }
        
    }
    block-=7;
    if(block<512)
    //一个盘块大小为1k,一个盘块号大小为2个字节,所以一共有512个block
    {
        bh=bread(inode->i_dev,inode->i_zone[7]);
        return (bh->b_data)[block];
    }
    ...
}
struct d_inode{
    unsigned short i_zone[9];
    //(0-6):直接数据块,(7):一重间接,(8):二重间接
}

上面基本就完成了磁盘的读写工作了

m_inode,设备文件的inode

struct m_inode{
    unsigned short i_mode; //文件的类型和属性
    ...
    unsigned short i_zone[9];  //指向文件内容数据块
    struct task_struct *i_wait;
    unsigned char i_lock;
    unsigned char i_dirt;
    ...
}
int sys_open(const char* filename, int flag)
{
    if(S_ISCHR(inode->i_mode))//字符设备
    {
        if(MAJOR(inode->i_zone[0])==4) //设备文件
            current->tty=MINOR(inode->i_zone[0]);
    }
}
#define MAJOR(a)(((unsigned)(a))>>8) //取高字节
#define MINOR(a)((a)&0xff) //取低字节

通过inode可以形成文件视图,如果使用不同的设备,只要使用inode形成映射就可以了,可以看一下这两篇博客,你可以更清楚的认识文件视图

  1. CPU如何读取键盘传过来的数据
  2. 操作系统如何使用显示器的

猜你喜欢

转载自blog.csdn.net/jump_into_zehe/article/details/106202695