- 多层组件统一完成进行读写文件的任务
- 系统调用 sys_open, sys_read 等
- 进程维护打开的文件数据结构, 系统维护所有打开的文件数据结构
- Linux 提供统一的虚拟文件系统接口; 例如 inode, directory entry, mount, 以及对应操作 inode operations等, 因此可以同时支持数十种不同的文件系统
- vfs 通过设备 I/O 层在通过块设备驱动程序访问硬盘文件系统
- 通过缓存层加快块设备读写
- 通过解析系统调用了解内核架构
- 挂载文件系统 mount
- 注册文件系统 register_filesystem 后才能挂载
- 调用链 mount->do_mount->do_new_mount→vfs_kern_mount
- 首先创建 struct mount
- 其中 mnt_parent 指向父 fs 的 mount; mnt_parentpoint 指向父 fs 的 dentry
- 用 dentry 表示目录, 并和目录的 inode 关联
- mnt_root 指向当前 fs 根目录的 dentry; 还有 vfsmount 指向挂载树 root 和超级块
- 调用 mount_fs 进行挂载
- 调用 ext4_fs_type→mount(ext4_mount), 读取超级块到内存
- 文件和文件夹都有一个 dentry, 用于与 inode 关联, 每个挂载的文件系统都由一个 mount 描述; 每个打开的文件都由 file 结构描述, 其指向 dentry 和 mount.
- 二层文件系统根目录有两个 dentry, 一个表示挂载点, 另一个是上层 fs 的目录.
- 打开文件 sys_open
- 先获取一个未使用的 fd, 其中 task_struct.files.fd_array[] 中每一项指向打开文件的 struct file, 其中 fd 作为下标. 默认 0→stdin, 1→stdout, 2→stderr
- 调用 do_sys_open->do_flip_open
- 先初始化 nameidata, 解析文件路径名; 接着调用 path_openat
- 生成 struct file 结构; 初始化 nameidata, 准备查找
- link_path_walk 根据路径名逐层查找
- do_last 获取文件 inode, 初始化 file
- 查找路径最后一部分对应的 dentry
- Linux 通过目录项高速缓存 dentry cache(dentry) 提高效率. 由两个数据结构组成
- 哈希表: dentry_hashtable; 引用变为 0 后加入 lru 链表; dentry 没找到则从 slub 分配; 无法分配则从 lru 中获取; 文件删除释放 dentry;
- 未使用的 dentry lru 链表; 再次被引用返回哈希表; dentry 过期返回给 slub 分配器
- do_last 先从缓存查找 dentry, 若没找到在从文件系统中找并创建 dentry, 再赋给 nameidata 的 path.dentry; 最后调用 vfs_open 真正打开文件
- vfs_open 会调用 f_op->open 即 ext4_file_open, 还将文件信息存入 struct file 中.
- 许多结构体中都有自己对应的 operation 结构, 方便调用对应的函数进行处理
展开