操作系统——文件系统(5)文件的实现

    现在要去实现文件的这一层抽象,其基本过程:给出一个文件inode,给出一个字符流读写位置,根据inode中存放的索引信息找到文件读写位置所在的物理盘块号,利用盘块号调用bread。
    文件实现的代码从sys_write开始,根据inode->i_mode进行分支判断,如果是普通文件,就转到file_write(inode, file, buf, count)执行。
在这里插入图片描述

//sys_write()函数部分代码(普通文件分支)
int sys_write(int fd, const char* buf, int count)
{
	struct file *file = current->filp[fd];
	struct m_inode *inode = file->inode;
	if(S_ISREG(inode->imode))
		return file_write(inode, file, buf, count);
}

    根据上图,file_write要首先找到文件对应的字符流位置,该位置就是文件最近一次读写结束时停留的读写位置。这个位置记录在打开文件对应的file数据结构中,准确来说记录在数据结构的f_pos中。语句pos = filp->f_pos取出来的就是200。

//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;
	else pos = filp->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;
		while(c->0) *(p++) = get_fs_byte(buf++);
		brelse(bh);
	}
	filp->f_pos = pos;
}

    现在有了字符流的读写位置pos,接下来要根据pos和索引节点中的信息计算物理盘块号。函数create_block(inode, pos/BLOCK_SIZE)中会调用bamp完成这项工作,根据pos/BLOCK_SIZE获得逻辑块号去查找inode中的直接数据块、一阶或者二阶索引。

int bamp(m_inode *inode, int block, int create)
{
	if(block < 7)//inode中直接数据块能映射出盘块号
		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 < 256)//逻辑盘块号存放在一阶索引中
	{
		bh = bread(inode->i_dev, inode->i_zone[7]);
		......
	}
}
struct d_inode
{
	unsigned short i_mode;
	......
	unsigned short i_zone[9];
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值