回顾

前面我们说到了mount系统调用陷入内核后开始执行mount,到do_new_mount为止的内容。也解释了mount和vfsmount两个structure。现在我们继续从do_new_mount()的说起。由于我已经断更文件系统挂载系列的文章有一段时间了,所以导致当时写前三篇的时候还是4.17左右的内核,现在最新的linux版本已经是5.2了。但是由于最近上游开始设计新的mount API,我后面会将新的mount API设计,但是为了继续这个系列的文章,我决定选用最后一个4.X版本的内核,即4.20来续写后面的内容。等我把这个vfs mount系列的写完了,我会再切到最新的内核上将最新的mount变化。由于新的mount API目前还处于开发阶段,还有很多bug,我和David(new mount API的作者)聊了一下觉得现在写还为时过早,等差不多稳定的时候再写。现在让我们以v4.20为基准写这篇文章。

vfs_kern_mount

do_new_mount()的第一个步骤就是下面这句:

mnt = vfs_kern_mount(type, sb_flags, name, data);

我们前面提到了vfsmount是整个mount操作中很关键的数据结构,而这一步就是填充一个vfsmount。

struct 

vfs_kern_mount主要完成三件事:

1. alloc_vfsmnt创造一个新的struct mount结构

2. 在mount_fs函数里调用特定文件系统的mount回调函数构造一个root dentry,包含特定文件系统的super block信息

3. 用第二步得到的结果完成对struct mount的构造,返回vfsmnt结构。

那么可以看出mount_fs函数就是下一个要叙述的函数了。

mount_fs()

这个函数看似复杂,其实主要就做一件事,调用type->mount回调函数。我们前面说过这个回调函数是在每个文件系统类型注册到内核中时实现的一个mount函数,它的前身是get_sb()函数,都是为了完成针对特定文件系统特点的操作而个别实现的回调函数。

除了type->mount之外,还有很多安全检查地方,这里就先不多说了。来看一下mount_fs函数:

struct 

mount再往下就是每个文件系统自己实现的mount回调函数了,我们以xfs为例说明。在fs/xfs目录下可以找到xfs文件系统的实现代码。xfs_super.c中可以找到init_xfs_fs模块初始化函数,里面调用了我们最开始提到的register_filesystem(&xfs_fs_type)函数,参数xfs_fs_type就是xfs实现的file_system_type结构。我们前面已经讲述了xfs_fs_type的定义:

醉卧沙场:文件系统怎么让Linux内核认识自己​zhuanlan.zhihu.com

现在我们要着重说一下xfs_fs_mount()函数。

xfs_fs_mount()

xfs_fs_mount是xfs自己实现mount回调函数,其实现就是调用mount_bdev()函数,如下:

STATIC 

但是这里有一个需要注意的地方就是mount_bdev虽然是一个通用函数,但是其最后一个参数是一个函数指针,xfs传入xfs_fs_fill_super作为参数。xfs_fs_fill_super是xfs实现的一个只适用于xfs的函数,也就是这里还是需要一个每个文件系统各异的fill_super处理函数。下面将分别对mount_bdev和xfs_fs_fill_super两个函数进行分析。

mount_bdev()

mount_bdev是针对块设备挂载时使用的函数,此外还有mount_nodev, mount_single等函数,分别用于不同的挂载情况,这里以mount_bdev为例继续讲解。看一下mount_bdev的定义(fs/super.c中):

struct 

mount_bdev函数的主要逻辑就是这样的:

  • blkdev_get_by_path根据设备名得到block_device结构
  • sget得到已经存在或者新分配的super_block结构
  • 如果是已经存在的sb,就释放第一步得到的bdev结构
  • 如果是新的sb,就调用文件系统个别实现的fill_super函数继续处理新的sb,并创建根inode, dentry
  • 返回得到的s_root

可以看到fill_super函数将完成mount接下来重要的工作,我们来看一下xfs是如何做fill_super处理的。

xfs_fs_fill_super()

xfs_fs_fill_super是一个和xfs具体实现相关的函数,要想完全了解里面的实现需要对xfs进行细致的研究。由于本章节旨在贯通mount的基本过程,对于具体文件系统的特别实现并不做细致说明,以免过多的分支内容扰乱主线内容的说明。关于xfs的具体实现会在以后做研究说明。

先来看一下xfs_fs_fill_super的代码(fs/xfs/xfs_super.c),这是一个很长的函数,特别是当xfs支持到了V5,而且后续有增加了reflink, rmapbt等特性后就变得更长了:

STATIC 

xfs_fs_fill_super实际上已经涉及到很多xfs相关的具体ondisk知识,再往下还会有更具体的device、和内存等相关的知识。对于xfs文件系统是如何实现的,那将是很大篇幅的内容,在以后分析xfs时再做分析,本文就不再往深入多做赘余了,以免扰乱主线的逻辑。我觉得到此只要知道具体文件系统的fill_super函数根据自身的特点设置到mount结构返回给上层调用就可以了。

返回后得到了mount结构我们就可以进行最后一步,把mount结构加入的全局文件系统树中了。


更多内容请参阅:

醉卧沙场:README - 专栏文章总索引

mount挂载时 no such device_mount系统调用(vfs_kern_mount-gt;mount_fs-gt;fill_super)相关推荐

  1. linux mount挂载大小,Linux中mount挂载问题小结

    vfat文件编码方式 fat32文件名分为两种,短文件名和长文件名,两种文件名在磁盘上的存储方式是不同的,长文件名在目录项中特殊的标记,短文件名也就是8.3格式,对于包含中文的任何文件来说都不可能是短 ...

  2. [mount]linux 挂载时 mount: wrong fs type, bad option, bad superblock on /dev/sdb

    原因:挂载时未格式化,使用的文件系统格式不对 解决方案:格式化 sudo mkfs -t ext4 /dev/sdb 再挂载 sudo mount /dev/sdb /xxx/ 用df -h检查,发现 ...

  3. ubuntu中mount挂载文件时出现WARNING:device write-protected,mounted read-only的问题

    ubuntu中mount挂载文件时出现WARNING:device write-protected,mounted read-only的问题 解决办法: 需要挂载的文件夹,以及 挂载到的文件夹 都要全 ...

  4. linux mount挂载设备(u盘,光盘,iso等 )使用说明

    对于新手学习,mount 命令,一定会有很多疑问.其实我想疑问来源更多的是对linux系统本身特殊性了解问题. linux是基于文件系统,所有的设备都会对应于:/dev/下面的设备.如: [cheng ...

  5. Linux系统中的mount挂载命令及参数详解

    mount.cifs(8) System Administration mount.cifs(8)名称mount.cifs - 挂载通用网际文件系统(Common Internet File Syst ...

  6. linux mount挂载设备(U盘,光盘,iso等)使用说明

    对于新手学习,mount 命令,一定会有很多疑问.其实我想疑问来源更多的是对linux系统本身特殊性了解问题. linux是基于文件系统,所有的设备都会对应于:/dev/下面的设备.如: [cheng ...

  7. mount 挂载目录

    常用命令 挂载WIN共享目录: mkdir /root/cne --若该目录下有别的文件,加载后,这些文件会被隐藏,直到删除挂载,这些文件才可被访问. chmod 777 /root/cne --授权 ...

  8. 十、Linux文件系统基本操作(mount挂载,umount卸载)

    回顾:七.八.九.十为磁盘及文件系统管理 七.Linux磁盘基本概念(MBR.Partition Table): 八.分区(fdisk磁盘管理)(fdisk创建分区): 九.格式化(文件系统创建)的基 ...

  9. windows系统作为客户端时,linux中本地yum源挂载时,如何同时挂载DVD1和DVD2?

    这里以CentOS6.5为例.他的镜像有两个DVD1和DVD2.DVD1中是系统和主要的安装包,DVD2中是剩下的安装包 当挂载时如果要同时挂载DVD1和DVD2.需要这样做: 1)在虚拟机的设置中选 ...

最新文章

  1. download WM6.5.3 SDK
  2. 特殊字符与语义化标签
  3. mvc ajax提交多选,javascript – 如何使用Jquery AJAX调用MVC Action然后在MVC中提交表单?...
  4. ASP.NET MVC SignalR(1):背景
  5. python读word文档doc公文标题_python – 从word doc中提取标题文本
  6. 利用FormData对象实现AJAX文件上传功能及后端实现
  7. C# 设计模式 - 单例模式 演示
  8. Node.js抓取网页信息(cheerio网络爬虫)
  9. 拼图java监听器,Android 简单的实现滑块拼图验证码功能
  10. java添加主类包_java – Maven bundle插件 – 如何添加主类
  11. 器件基础知识——电阻
  12. java谜题读书笔记_《java深度历险》读书笔记(一)
  13. Strom整合Hbase
  14. c语言 'max' : undeclared identifier,c语言中undeclared identifier是什么意思?
  15. 什么认证在云计算行业内的含金量最大?考试费用贵不贵?
  16. android代码精华 各路大神写的代码精华,大家一起分享
  17. ZYNQMP_XAZU3EG_VxWorks7 添加USB2.0 USB3.0
  18. SkyForm CMP(云管理平台)v4.0
  19. swift——一些有用的小Tips
  20. ConvNeXt网络详解

热门文章

  1. UITableViewCell自适应高度
  2. nagios流量监控报警
  3. CentOS各版本更换国内源,一条指令搞定,超简单!
  4. ASP.NET CORE 使用Consul实现服务治理与健康检查(2)——源码篇
  5. leetcode 移动零
  6. 【Markdown】新手快速入门基础教程
  7. 【C语言】创建一个函数,并调用比较三个数的大小
  8. C#开发笔记之11-如何用C#过滤连续相同的字符串?
  9. C#LeetCode刷题之#190-颠倒二进制位(Reverse Bits)
  10. 打开windows批处理大门