【kernel】文件系统
如何打开一个文件
首先贴出整体的流程:
compat_sys_openat
|-->do_sys_open
|-->do_filp_open
|-->do_filp_open
|-->path_openat
|-->path_init # nd初始化。
|-->link_path_walk # 真实寻找。
| |-->for(;;) {
| | |-->may_lookup # 查询文件权限是否允许访。
| | |-->hash = init_name_hash(); # 算出该文件名的哈希值,和文件名长度。
| | |-->## 判断文件名是否使用了"."或者"..",来标明文件类型type ##
| | |-->d_hash # 查询是否有哈希表存在。
| | |-->walk_component # 依据刚刚识别的类型,做单次搜索。
| | | |-->handle_dots # "." 和 ".." 文件名处理。
| | | |-->do_lookup # 其他文件的搜索。
| | | | |-->__d_lookup_rcu # 不带rcu搜寻。
| | | | |-->__d_lookup # 带rcu,可能引起阻塞搜寻。
| | | | |-->d_alloc_and_lookup # 上两步搜不到,就要通过硬盘文件系统搜寻。
| | | |-->should_follow_link # 查看是否可以继续链接文件,前面提到过,对链接次数有限制。
| | |-->nested_symlink # 限制递归调用不能超过8次,符号链接不能超过40次。
| | |-->can_lookup # 判断是否可以继续查找,可以则继续。
| | |-->terminate_walk(nd); # 查找完成操作,包括解RCU锁。
| |-->}
|-->do_last # 查找完成,做打开文件操作
首先梳理清楚几个概念:
超级块、page cache、目录项、目录、文件索引inode
文件在磁盘中存储的几种模式、
对于磁盘空闲空间管理的几种方式、
文件的链接
超级块(superblock)
SuperBlock是文件系统最开始的Block,用来存储文件系统的大小,空的块,填满的块和各自总数等文件系统关键信息,每个文件系统都会只有一个SuperBlock。但是随着硬盘容量的不断扩大且磁盘分区有限,这就出现了区块群组 (block group),每个区块群组就相当于一个独立的文件系统,都有一个SuperBlock,这就是我们重装系统时创建的逻辑分区,逻辑分区中可以再分区就是通过这种方式实现的
以ext2文件系统为例,文件包括文件内容和文件属性,分别放在Block和inode中。ext2文件系统除SuperBlock外,又被分为inode table区 和 Block area区
超级块存在于磁盘文件系统中,当挂载磁盘文件系统的时候,将超级块加载到内存中用以注册这个文件系统
索引节点(index node)(inode)
索引节点在磁盘上,是文件的唯一访问标识,只有在访问到对应的文件时,inode才会被加载到内存中
目录项(dentry)
dentry是内存当中内核态的一个数据结构,用来管理不同文件之间的层级关系以及路径等,相当于磁盘实际文件目录在内存中的缓存
这里值得一提的是,上述提到存放在磁盘中的数据结构,在加载在内存的VFS中也实现了,因为VFS也是一个文件系统,只不过是逻辑意义上的,存放在内存而非磁盘的。
具体文件系统中不存在专门的目录结构。也就是说这个结构只存在于只存在于RAM中,不会存在于磁盘中。但是文件之间关系,在文件系统中是存在的,只是没有专用的结构,使用的和普通的文件一样,都是inode,只是内容不一样。dentry的存在价值是它能提高文件搜索的效率。