对文件系统,我们一般的操作主要有:1.初始化vfs,准备好相关资源进行后续操作;2.mount,挂载文件系统,挂载后文件系统有了路径,才可以进行后续的其他操作;3.open,打开文件,open参数可以带O_CREATE,创建文件后打开,打开文件后,才可以进行后续的读写等操作;4.read,write,读写文件;5.删除文件
这些是基本的文件操作。
1.start_kernel
初始化过程中,对dentry、inode、superblock的缓存哈希表进行初始化。
并调用init_rootfs对根文件系统进行初始。
2.register_filesystem
每个子文件系统初始化时,调用register_filesystem函数,将该文件系统挂到全局变量file_systems上。
3.mount
a)解析传入的路径名称,获取路径对应的dentry和inode;安装目录一级一级解析,解析过程中会使用到每一级的dentry和inode,如果没有在缓存中,会调用子文件系统的接口读取。
b)判断mount类型,进行不同的操作,一般是进行do_new_mount,以下只介绍这种
c)根据传入的文件系统类型,从file_systems全局变量中获取对应的元素。其中包含了子文件系统的mount函数指针
d)分配mount结构体的空间
e)调用子文件系统的mount函数,ext4文件系统的话是调用mount_bdev函数,并传了一个ext4_fill_super函数的指针,mount_bdev函数中会获取到对应的块设备,并调用fill_super读取super_block,以及进行其他一些操作。fill_super函数对不同的文件系统是各自实现的,因此可能会有一些其他的不同操作。
f)将处理完毕的mount结构体挂到全局变量mount_hashtable上,将挂载路径对应的dentry挂在全局变量mountpoint_hashtable上
4.open
a)从当前进程的结构体中,获取一个未使用的fd,fd对应一个struct file结构体
b)解析路径,找到要打开文件的上一级目录对应的dentry和inode
c)在缓存中查找文件是否已打开,已代开就只需要将file结构体的相关内容进行赋值,指针指到已打开文件对应的inode和dentry即可
d)没有打开则调用子文件系统的lookup函数,查找父目录下有没有需要打开的文件,有则读取上来,并对file结构体进行复制
e)如果还没有创建文件,且带了O_CREATE的flag,则调用子文件系统的create函数进行文件创建,创建完成后对file结构体进行赋值