OK6410A 开发板 (八) 110 linux-5.11 OK6410A 从流程去熟悉文件系统1-挂载

挂载的时机有两种
	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;
						//static const struct fs_context_operations ramfs_context_ops = {
						//	.get_tree   = ramfs_get_tree,
		
		vfs_parse_fs_string
		
		parse_monolithic_mount_data
	
		fc_mount
			vfs_get_tree
				error = fc->ops->get_tree(fc);//即 ramfs_get_tree
					get_tree_nodev(fc, ramfs_fill_super);
						vfs_get_super
--------------------------------------------------------------------------------过程1
							err = fill_super(sb, fc);//即ramfs_fill_super
								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;
						//const struct fs_context_operations legacy_fs_context_ops = {
						//	.get_tree       = legacy_get_tree,
	
		vfs_parse_fs_string
		
		parse_monolithic_mount_data
	
		fc_mount
			vfs_get_tree
				error = fc->ops->get_tree(fc);//即 legacy_get_tree
--------------------------------------------------------------------------------过程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); // 即 xxx_get_tree
						get_tree_nodev(fc, xxx_fill_super);
							vfs_get_super
--------------------------------------------------------------------------------过程1
								err = fill_super(sb, fc);//即xxx_fill_super
									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);//建立 mount 与 mountpoint 和 它的父mount的关系
							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);//建立 mount 与 mountpoint 和 它的父mount的关系
							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);
--------------------------------------------------------------------------------
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值