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_operations
sb->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
中。
