虚拟文件系统(VFS)中的链表
看虚拟文件系统的次数估计已经是两位数了,每次都有新的收获,这里把VFS涉及到的链表串起来总结一下,主要就是四大对象之间的串连,由于把这些串连关系放到一个图中,逻辑结构太过复杂,可看性太差。另外虚拟文件系统中链接关系比较复杂,下面是对深入理解VFS机制比较重要的一些链表的介绍。
文件系统类型file_system_type链表
其中,file_systems全局变量定义在fs/filesystems.c中
static struct file_system_type *file_systems;
具有相同文件系统类型的超级块通过s_instances字段链接到文件系统类型的fs_supers字段
super_block相关链表
super_blocks在fs/super.c中声明并初始化
LIST_HEAD(super_blocks);
并在include/linux/fs.h加上外部定义声明
super_block中的s_inodes字段为该文件系统所有inode节点的头,inode节点通过i_sb_list链接。
super_block中的s_dirty字段为该文件系统所有脏inode节点的头,脏inode节点(有i_state字段标识)通过i_list字段相互链接。
super_block的s_files字段指向该文件系统所有文件对象链表的头,file结构通过f_list相互链接。
inode相关链表
所有的inode节点通过i_sb_list链接到超级块的s_inodes字段。
所有的inode节点通过i_hash链接到全局hash数组inode_hashtable。
脏的inode节点通过i_list链接到超级块的s_dirty字段。
正在使用的inode节点通过i_list链接到全局变量inode_in_use。
未使用的inode节点通过i_list链接到全局变量inode_unused。
inode_in_use, inode_unused, inode_table在fs/inode.c定义
LIST_HEAD(inode_in_use);
LIST_HEAD(inode_unused);
static struct hlist_head *inode_hashtable __read_mostly;
在vfs初始化时,会为inode_hashtable分配表项,表项数与内存大小有关
i_dentry字段指向指向该inode的目录项链表的第一个元素。
dentry相关链表
所有的dentry通过d_hash链接到dentry_hashtable数组(fs/dcache.c)。
未使用的dentry通过d_lru字段链接到全局变量dentry_unused。
static struct hlist_head *dentry_hashtable __read_mostly;
static LIST_HEAD(dentry_unused);
在vfs初始化时,会为的dentry_hashtable分配表项,表项数与内存大小有关,默认每兆字节内存包含256个元素。散列值通过目录项对象及文件名计算而得出。
dentry的d_subdirs字段指向子目录项的第一个元素,子目录项之间通过d_child相互链接。
dentry的d_parent字段指向目录项的父目录项,如果是FS的根,则指向自己。
dentry的d_alias链接指向同一索引节点的目录项到对应inode的i_dentry字段
file相关链表
跟打开文件对象相关的链表只有file结构f_list相互链接的所有文件对象,链接到超级块的f_files字段,已经在super_block相关链表一节做了说明。
vfsmount相关链表
vfsmount的mnt_hash将挂载的文件系统分组链接到mount_hashtable散列表。
散列值由父文件系统vfsmount描述符地址和安装点目录项对象的地址计算而得。
对于每一个已安装文件系统,所有安装的子文件系统形成一个双向循环链表。每个链表的头存放在已安装文件系统的mnt_mounts字段,子文件系统通过mnt_child相互链接。
对于每个命名空间,所有属于此命名空间的已安装文件系统描述符形成一个双向循环链表。namespace的list结构存放链表的头,vfsmount描述符的mnt_list包含相邻元素的指针。