XFS解析(1) - 注册和mount
XFS文件系统的实现位于kernel仓库的 fs/xfs/目录下,本文基于kernel版本 3.10的代码,也就是CentOS 7.2版本的kernel。
module_init
module_init()的调用在fs/xfs/xfs_super.c文件中,模块初始化函数是init_xfs_fs()。
xfs_dir_startup
计算两个固定的文件名的hash值:.和..。
xfs_init_zones
初始化一些cache,这些cache用于保存不同类型的数据,都是用于后续文件系统操作的内存数据结构。
xfs_init_workqueues
初始化一个workqueue,名称是xfsalloc,用于回收内存。
xfs_mru_cache_init
初始化一个MRU(Most Recently Used) cache,包括初始化一个kmem zone用于存储xfs_mru_cache_elem_t,以及一个workqueue xfs_mru_cache。
xfs_filestream_init
初始化一个kmem zone,用于保存filestream的元素。
xfs_buf_init
初始化buf用的cache,包含一个kmem zone,以及一个workqueue xfslogd。
xfs_init_procfs
初始化几个procfs的文件,都位于目录/proc/fs/xfs目录下:
- fs/xfs/stat:对应函数
xfs_stat_proc_fops()。 - fs/xfs/xqmstat:对应函数
xqmstat_proc_fops()。 - fs/xfs/xqm:对应函数
xqm_proc_fops()。
xfs_sysctl_register
注册sysctl,对应的table是xfs_root_table。
xfs_qm_init
初始化quota相关的kmem zone。
register_filesystem
注册文件系统,参数是xfs_fs_type:
static struct file_system_type xfs_fs_type = {
.owner = THIS_MODULE,
.name = "xfs",
.mount = xfs_fs_mount,
.kill_sb = kill_block_super,
.fs_flags = FS_REQUIRES_DEV,
};文件系统的注册主要提供一个mount函数和一个kill_sb函数,分别用于文件系统的mount和umount。
xfs_fs_mount
这个函数会调用mount_bdev()函数,并且传递函数xfs_fs_fill_super()作为fill_super参数。mount_udev()是一个公共函数,挂载文件系统的统一入口,位于fs/super.c。
xfs_fs_fill_super
这个函数完成一个XFS文件系统的mount工作。函数的原型如下:
STATIC int xfs_fs_fill_super(struct super_block *sb, void *data, int silent);函数的主要工作如下:
- 分配一个
struct xfs_mount结构体,并且初始化字段。 - 调用
xfs_parseargs()解析参数并且设置mp中对应的字段。 - 设置
sb->s_blocksize等字段。 - 在superblock中设置操作对应的函数
sb->s_xattr = xfs_xattr_handlers:实现文件扩展属性的函数。sb->s_export_op = &xfs_export_operationssb->s_qcop = &xfs_quotactl_operations:实现配额的函数。sb->s_op = &xfs_super_operations:文件级别的操作。
- 调用
xfs_open_devices(),默认情况下我们只有data device。这个函数还会初始化buffer target,是一个xfs_buftarg_t指针,保存在mp->m_ddev_targp。 - 调用
xfs_init_mount_workqueue。这个函数初始化文件系统mount之后所需要的几个workqueue:- xfs-data
- xfs-conv
- xfs-cli
- xfs-reclaim
- xfs-log
- xfs-eofblocks
- 调用
xfs_icsb_init_counters()初始化计数器。 - 调用
xfs_readsb()从设备上读取superblock,并且保存到mp->m_sb中。 - 调用
xfs_finish_flags(),根据mount参数再初始化某些mp的字段。 - 调用
xfs_setup_devices(),根据superblock中的block size和sector size来设置buffer target。 - 调用
xfs_filestream_mount(),创建和filestream相关的MRU cache。 - 在执行mount操作之前,再设置某些superblock的字段。
- 调用
xfs_mountfs()。这个函数做了许多操作:- 根据superblock的内容继续初始化
mp。 xfs_initialize_perag(),初始化ag的内存表示。xfs_log_mount(),初始化journaling log,这里还包含recovery的处理逻辑。- 读取root inode,也就是文件系统的根目录,保存在
mp->m_rootip。 - 初始化quota相关的逻辑。
- 结束recovery操作。
- 保留一些空间用于特殊操作。
- 根据superblock的内容继续初始化
- 使用root inode创建一个dentry,保存在
sb->s_root中。
本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。