0 回顾
- 回顾了在磁盘上是怎么抽象成目录的
- 让目录真的能落实到磁盘
1 目录解析
1.1 open
- open就是根据FCB最后形成一条链,把一个文件对应的inode读进来,放在FCB的file数组里面,再和PCB里面的数组接起来,返回fd,fd就是FCB数组的下标
- 核心就是读入inode,读入inode核心就是在磁盘上找到inode
- 所以可以想象到,整个open的核心就是找到inode
- 核心完之后再read,write,fd,inode发出去读写就行
- open的内核实现就是sys_open
- 下方的open_namei,根据名字就可以看出来,就是为了解析这个路径
- 然后根据filename,把里面的inode拿出来,写到&inode当中进行存储,这和之前讲的知识都是一样的
- 所以接下来的代码就是要形成这个量
- 继续往下解析
1.2 get_dir
- 首先传递的肯定是路径名
- 如果路径名只是一个
/
,那么就代表从根目录开始,看current->root
就是根目录的FCB - 为什么根目录的FCB直接就是找
current->root
? - 首先主磁盘肯定会mount上去,根目录直接shell进去,其他进程都是shell进程的fork,所以其他进程自然会拷贝,所以
current->root
肯定都会一直有,这样省的每次读FCB第0号位置 - 不是长成这样就从当前目录开始
inr
表示目录项中的索引节点号,也就是编号iget
就是读下一层目录,这样下一层的inode就有了while(1)
一直循环,直到整个目录解析完成
1.3 根目录
init()
及其下方的代码就是挂载硬盘- 挂载这个硬盘就会
mount_root()
,把根目录也挂载进来 - 根目录怎么挂载进来呢?就是调用
iget
,iget()
就是得到root_ino
根目录所对应的inode编号 - 根据inode编号就可以把根目录读进来
- 一旦把根目录读进来,也就是把根目录的FCB读进来,也就是inode
- 读进来inode再赋值给root,剩下的通过fork继承
- 每个进程FCB的root就都是根目录的FCB也就是inode
mi = iget(ROOT_DEV, ROOT_INO);
current->root = mi;
1.4 iget
- read_inode
- 首先是get_super
- 要想找到某一项,就得换算出前面有多长,参考之前的内容,比如说盘块号要知道起始盘块号,再相加
- 一旦知道盘块号,就可以读磁盘了,读磁盘一定要知道盘块号
- 为了知道长度就得知道i节点位图以及盘块位图(超级块)有多长,所以必须get_super
block = 2 + sb->s_imap_blocks + sb->s_zmap_blocks + (inode->i_num - 1) / INODES_PER_BLOCK;
- 为什么加2呢?因为引导块占一块超级块占一块
- 所以从2开始,往下走
- s_imap_blocks就是inode的位图的block
- 加上s_zmap_blocks就是盘块位图,就从引导块到盘块位图全部加上了
- inode->i_num就是你要读的那个盘块号
- 这样就算出来了当前的盘块号
1.5 find_entry
- 找到目录项
- 这就是读目录,找到var旁边的那个数字编号
- 根据inode一项一项读进来
- 首先找到直接索引块,这个数据块去读
- 读完以后把bh->b_data给取出来
- 然后挨个的去匹配,去看能不能匹配成var
- 能匹配上直接返回,不能匹配就继续循环
- 一旦匹配完成目录项就有了
- 目录项有了就能找到inode编号,编号有了就用iget去读出inode,然后不断循环就行
1.6 while(i<entries)
- 扫描全部的目录项,再去匹配var
- 所以还要看bmap
- 有的项可能在直接索引项上,有的可能在一阶/二阶间接索引上,所以循环不断扫描
- 现在就知道目录怎么解析了
2 总结
- 完结撒花,感谢自己一路坚持过来没有放弃,感谢李治军老师这么优秀的课程,勿在浮沙筑高台,与君共勉!