由于open的系统调用会触发目录解析,所以下面关于目录解析代码实现的讨论从sys_open开始:
//sys_open()函数代码实现
int sys_open(const char* filename, int flag)
{
if((c = get_fs_byte(filename)) == '/')//如果路径名从“/”开始,就从根目录的inode开始
{
inode = current -> root;
filename++;
}
else if(c) inode = current->pwd;//从当前目录的inode开始
while(1)
{
if(!c) return inode;
find_entry(&inode, filename, namelen, &de);
int inr = de->inode;
inode = iget(inr);
}
}
void find_entry(struct m_inode **dir, char *name, struct dir_entry ** res_dir)//根据目录文件的inode读取目录项数组,逐个目录项进行匹配
{
int entries = (*dir)->i_size/(sizeof(struct dir_entry));
int block = (*dir)->i_zone[0];
*bh = bread((*dir)->i_dev, block);
struct dir_entry *de = bh->b_data;
while(i<entrises)
{
if(match(namelen, name, de))*res_dir = de;
de++;
i++;
}
}
在一号进程的init函数中要执行mount_root(),将根目录的inode读入到内存中,并且关联到1号进程的PCB中。
//mount_root()函数部分代码
void init(void){mount_root(); ......}
void mount_root(void)
{
mi = iget(ROOT_INO);
current->root = mi;
}
struct m_inode * iget(int nr)
{
struct super_block *sb = get_super();
block = 2+ sb->s_imap_blocks + sb->s_zmap_blocks + (nr - 1)/INODES_PER_BLOCK;
bh = bread(dev, block);
inode = bh->data[(nr - 1)%INODES_PER_BLOCK];
return &inode;
}