文件使用磁盘的实现--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. 操作系统如何使用显示器的
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
模拟Linux文件系统。在任一OS下,建立一个大文件,把它假象成一张盘,在其中实现一个简单的 模拟Linux文件系统 在现有机器硬盘上开辟20M的硬盘空间,作为设定的硬盘空间。 2. 编写一管理程序对此空间进行管理,以模拟Linux文件系统,具体要求如下: (1) 要求盘块大小1k 正规文件 (2) i 结点文件类型 目录文件 (共1byte) 块设备 管道文件 物理地址(索引表) 共有13个表项,每表项2byte 文件长度 4byte 。联结计数 1byte (3)0号块 超级块 栈长度50 空闲盘块的管理:成组链接 ( UNIX) 位示图法 (Linux) (4)每建一个目录,分配4个物理块 文件名 14byte (5)目录项信息 i 结点号 2byte (6)结构: 0#: 超级块 1#-20#号为 i 结点区 20#-30#号为根目录区 3. 该管理程序的功能要求如下: (1) 能够显示整个系统信息,源文件可以进行读写保护。目录名和文件名支持全路径名和相对路径名,路径名各分量间用“/”隔开。 (2) 改变目录:改变当前工作目录,目录不存在时给出出错信息。 (3) 显示目录:显示指定目录下或当前目录下的信息,包括文件名、物理地址、保护码、文件长度、子目录等(带/s参数的dir命令,显示所有子目录)。 (4) 创建目录:在指定路径或当前路径下创建指定目录。重名时给出错信息。 (5) 删除目录:删除指定目录下所有文件和子目录。要删目录不空时,要给出提示是否要删除。 (6) 建立文件(需给出文件名,文件长度)。 (7) 打开文件(显示文件所占的盘块)。 (8) 删除文件:删除指定文件,不存在时给出出错信息。 4. 程序的总体流程为: (1) 初始化文件目录; (2) 输出提示符,等待接受命令,分析键入的命令; (3) 对合法的命令,执行相应的处理程序,否则输出错误信息,继续等待新命令,直到键入EXIT退出为止。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值