文件使用磁盘的实现
通过文件使用磁盘,代码如下
在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)
- 根据file还有count找到字符流的位置如(200-212)
- 根据inode映射表找到对应的盘块号
- 进行读写操作
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形成映射就可以了,可以看一下这两篇博客,你可以更清楚的认识文件视图