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);

函数的主要工作如下:

  1. 分配一个struct xfs_mount结构体,并且初始化字段。
  2. 调用xfs_parseargs()解析参数并且设置mp中对应的字段。
  3. 设置sb->s_blocksize等字段。
  4. 在superblock中设置操作对应的函数
    1. sb->s_xattr = xfs_xattr_handlers:实现文件扩展属性的函数。
    2. sb->s_export_op = &xfs_export_operations
    3. sb->s_qcop = &xfs_quotactl_operations:实现配额的函数。
    4. sb->s_op = &xfs_super_operations:文件级别的操作。
  5. 调用xfs_open_devices(),默认情况下我们只有data device。这个函数还会初始化buffer target,是一个xfs_buftarg_t指针,保存在mp->m_ddev_targp
  6. 调用xfs_init_mount_workqueue。这个函数初始化文件系统mount之后所需要的几个workqueue:
    1. xfs-data
    2. xfs-conv
    3. xfs-cli
    4. xfs-reclaim
    5. xfs-log
    6. xfs-eofblocks
  7. 调用xfs_icsb_init_counters()初始化计数器。
  8. 调用xfs_readsb()从设备上读取superblock,并且保存到mp->m_sb中。
  9. 调用xfs_finish_flags(),根据mount参数再初始化某些mp的字段。
  10. 调用xfs_setup_devices(),根据superblock中的block size和sector size来设置buffer target。
  11. 调用xfs_filestream_mount(),创建和filestream相关的MRU cache。
  12. 在执行mount操作之前,再设置某些superblock的字段。
  13. 调用xfs_mountfs()。这个函数做了许多操作:
    1. 根据superblock的内容继续初始化mp
    2. xfs_initialize_perag(),初始化ag的内存表示。
    3. xfs_log_mount(),初始化journaling log,这里还包含recovery的处理逻辑。
    4. 读取root inode,也就是文件系统的根目录,保存在mp->m_rootip
    5. 初始化quota相关的逻辑。
    6. 结束recovery操作。
    7. 保留一些空间用于特殊操作。
  14. 使用root inode创建一个dentry,保存在sb->s_root中。

知识共享许可协议本作品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。