挂载的时机有两种
1. 注册文件系统之后就挂载
2. 在用户空间挂载
2.1 fstab中挂载
2.2 用户手动用mount 命令挂载
挂载流程变迁史
在内核空间的挂载直接用 kern_mount挂载
在用户空间的挂载 用 用户空间的 mount 函数 , mount 往下调用,陷入内核 ,SYSCALL_DEFINE5(mount
这些接口都没变,变的是 内部实现
老的文件系统中 仍然用 mount 成员 去 创建 super_block 成员
当前(5.11)内核中file_system_type 结构体 中的 mount 成员 即将被抛弃
但是目前依靠 "新挂载流程" 中 的 legacy_init_fs_context 兼容了 老的文件系统
老挂载流程
总结,老的流程分为两个步骤
1. 创建 vfsmount 结构体
1.1 申请 super_block
1.2 填充 super_block 的 s_root 成员
1.3 将 super_block 填充 vfsmount 结构体
2. 将 vfsmount 结构体 link 进 全局变量
主要过程 1.1 1.2 1.3 都是
file_system_type 的 mount 成员 调用 xxx_fill_super 做的
当前挂载流程
总结,老的流程分为两个步骤
1. 创建 vfsmount 结构体
1.1 申请 super_block
1.2 填充 super_block 的 s_root 成员
1.3 将 super_block 填充 vfsmount 结构体
2. 将 vfsmount 结构体 link 进 全局变量
主要过程 1.1 1.2 1.3
都是 file_system_type 的 init_fs_context 函数填充的
xxx_context_ops 中的 get_tree 成员 调用 xxx_fill_super 做的
- 针对 第一种挂载的 流程 以 最简单的tmpfs(tmpfs配置有三种) 为例
kern_mount
vfs_kern_mount
fs_context_for_mount
alloc_fs_context
init_fs_context = fc->fs_type->init_fs_context;/ramfs_init_fs_context
init_fs_context(fc);
fc->ops = &ramfs_context_ops;
vfs_parse_fs_string
parse_monolithic_mount_data
fc_mount
vfs_get_tree
error = fc->ops->get_tree(fc);
get_tree_nodev(fc, ramfs_fill_super);
vfs_get_super
--------------------------------------------------------------------------------过程1
err = fill_super(sb, fc);
inode = ramfs_get_inode(sb, NULL, S_IFDIR | fsi->mount_opts.mode, 0);
sb->s_root = d_make_root(inode);
--------------------------------------------------------------------------------
vfs_create_mount
--------------------------------------------------------------------------------过程2
mnt->mnt.mnt_sb = fc->root->d_sb;
mnt->mnt.mnt_root = dget(fc->root);
mnt->mnt_mountpoint = mnt->mnt.mnt_root;
mnt->mnt_parent = mnt;
list_add_tail(&mnt->mnt_instance, &mnt->mnt.mnt_sb->s_mounts);
--------------------------------------------------------------------------------
real_mount(mnt)->mnt_ns = MNT_NS_INTERNAL;
kern_mount
vfs_kern_mount
fs_context_for_mount
alloc_fs_context
init_fs_context = fc->fs_type->init_fs_context;
if (!init_fs_context) init_fs_context = legacy_init_fs_context;
init_fs_context(fc);
fc->ops = &legacy_fs_context_ops;
vfs_parse_fs_string
parse_monolithic_mount_data
fc_mount
vfs_get_tree
error = fc->ops->get_tree(fc);
--------------------------------------------------------------------------------过程1
fc->fs_type->mount(fc->fs_type, fc->sb_flags, fc->source, ctx->legacy_data);
xxx_fill_super
--------------------------------------------------------------------------------
vfs_create_mount
--------------------------------------------------------------------------------过程2
mnt->mnt.mnt_sb = fc->root->d_sb;
mnt->mnt.mnt_root = dget(fc->root);
mnt->mnt_mountpoint = mnt->mnt.mnt_root;
mnt->mnt_parent = mnt;
list_add_tail(&mnt->mnt_instance, &mnt->mnt.mnt_sb->s_mounts);
--------------------------------------------------------------------------------
SYSCALL_DEFINE5(mount
do_mount
path_mount
do_new_mount
fs_context_for_mount
alloc_fs_context
init_fs_context = fc->fs_type->init_fs_context;
init_fs_context(fc);
vfs_parse_fs_string
parse_monolithic_mount_data
vfs_get_tree
fc->ops->get_tree(fc);
get_tree_nodev(fc, xxx_fill_super);
vfs_get_super
--------------------------------------------------------------------------------过程1
err = fill_super(sb, fc);
inode = xxx_get_inode(sb, NULL, S_IFDIR | fsi->mount_opts.mode, 0);
sb->s_root = d_make_root(inode);
--------------------------------------------------------------------------------
do_new_mount_fc
vfs_create_mount
list_add_tail(&mnt->mnt_instance, &mnt->mnt.mnt_sb->s_mounts);
do_add_mount
graft_tree(newmnt, parent, mp);
attach_recursive_mnt
attach_mnt
--------------------------------------------------------------------------------过程2
mnt_set_mountpoint
child_mnt->mnt_mountpoint = mp->m_dentry;
child_mnt->mnt_parent = mnt;
child_mnt->mnt_mp = mp;
hlist_add_head(&child_mnt->mnt_mp_list, &mp->m_list);
__attach_mnt
hlist_add_head_rcu(&mnt->mnt_hash, m_hash(&parent->mnt, mnt->mnt_mountpoint));
list_add_tail(&mnt->mnt_child, &parent->mnt_mounts);
--------------------------------------------------------------------------------
SYSCALL_DEFINE5(mount
do_mount
path_mount
do_new_mount
fs_context_for_mount
alloc_fs_context
init_fs_context = fc->fs_type->init_fs_context;
if (!init_fs_context) init_fs_context = legacy_init_fs_context;
init_fs_context(fc);
fc->ops = &legacy_fs_context_ops;
vfs_parse_fs_string
parse_monolithic_mount_data
vfs_get_tree
--------------------------------------------------------------------------------过程1
fc->ops->get_tree(fc);/legacy_get_tree
fc->fs_type->mount(fc->fs_type, fc->sb_flags, fc->source, ctx->legacy_data);
xxx_fill_super
--------------------------------------------------------------------------------
do_new_mount_fc
vfs_create_mount
list_add_tail(&mnt->mnt_instance, &mnt->mnt.mnt_sb->s_mounts);
do_add_mount
graft_tree(newmnt, parent, mp);
attach_recursive_mnt
attach_mnt
--------------------------------------------------------------------------------过程2
mnt_set_mountpoint
child_mnt->mnt_mountpoint = mp->m_dentry;
child_mnt->mnt_parent = mnt;
child_mnt->mnt_mp = mp;
hlist_add_head(&child_mnt->mnt_mp_list, &mp->m_list);
__attach_mnt
hlist_add_head_rcu(&mnt->mnt_hash, m_hash(&parent->mnt, mnt->mnt_mountpoint));
list_add_tail(&mnt->mnt_child, &parent->mnt_mounts);
--------------------------------------------------------------------------------