前言
在 linux 中常见的文件系统 有很多, 如下
基于磁盘的文件系统, ext2, ext3, ext4, xfs, btrfs, jfs, ntfs
内存文件系统, procfs, sysfs, tmpfs, squashfs, debugfs
闪存文件系统, ubifs, jffs2, yaffs
文件系统这一套体系在 linux 有一层 vfs 抽象, 用户程序不用关心 底层文件系统的具体实现, 用户只用操作 open/read/write/ioctl/close 的相关 系统调用, 这一层系统调用 会操作 vfs 来处理响应的业务
vfs 会有上面各种文件系统对应的 读写 相关服务, 进而 将操作下沉到 具体的文件系统
我们这里 来看一下 rootfs 文件系统, 这是一个 基于 内存的文件系统, 读写的都是 基于内存页
如何分配inode ?
在创建该文件的时候, rootfs 会创建对应的 inode, 并将改 inode 添加到 父级节点
创建 inode 操作来自于, 父级目录的 i_op->create, rootfs 中对应于 ramfs_get_inode
这里主要是基于 rootfs 的 super_block 新建 inode, 初始化 i_no, i_mapping, i_op, i_fop 什么的
i_fop 为 ramfs_file_operations
/xx 是在哪里创建的 ?
这个创建取决于实际的业务, 业务/内核 代码向 rootfs 中写出具体的数据到具体的文件
那么执行 该代码的时候 就会创建对应的文件
如何分配存储空间 ?
存储空间是来自于 pagecache
如果没有空闲的 pagecache, 申请新的 物理页
如何读写数据 ?
a_ops->write_begin 会回去 maping, pos 对应的物理页, 如果不存在 则从 pagecache 进行申请
然后 iov_iter_copy_from_user_atomic 的实现是将 用户空间待写出的数据 写出到给定的 物理页
copy_page_to_iter 即为读取的操作, 将物理页的数据拷贝到 buf 中
如何根据 path 获取到上下文的数据?
上面在 i_op->create 中创建了 inode, 但是并没有提到将 inode 注册到 dir 中或者怎么怎么样
那么 读取文件的时候怎么关联找到这个 inode 呢?
该文件对应的dentry 在 i_op->lookup 的时候, 将 dentry 翻到了 dcache_hashtable 中
然后 之后才是走的上面的 i_op->create 来创建文件对应的 inode, 然后将 dentry 关联上 inode
然后 在之后 读取该文件的时候, lookup_fast 的时候去 dcache_hashtable 中查询对应的 dentry 的信息
进而拿到 inode, 以及 inode 相关附加信息
进而是根据 inode, 以及上下文, 封装 file 对象
完