免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 867 | 回复: 0
打印 上一主题 下一主题

[内核入门] sys_mount() [复制链接]

论坛徽章:
13
15-16赛季CBA联赛之八一
日期:2016-07-08 21:00:1415-16赛季CBA联赛之同曦
日期:2017-02-15 14:26:1515-16赛季CBA联赛之佛山
日期:2017-02-20 14:19:2615-16赛季CBA联赛之青岛
日期:2017-05-07 16:49:1115-16赛季CBA联赛之广夏
日期:2017-07-30 09:13:1215-16赛季CBA联赛之广东
日期:2018-07-05 22:34:3615-16赛季CBA联赛之江苏
日期:2018-09-03 12:10:2115-16赛季CBA联赛之上海
日期:2018-09-25 03:49:2215-16赛季CBA联赛之广东
日期:2018-09-25 04:09:12
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2016-10-25 14:38 |只看该作者 |倒序浏览
    /*
     * 内核中跟挂载相关的三个函数:sys_mount()、mount_root()、kem_mount()
     * 其中用户态可以使用的mount()系统调用,底层调用的是sys_mount()函数:主要就是将参数从用户空间拷到内核空间,然后调用do_mount()函数
     *
     * dev_name: 要挂载的设备(比如光盘、硬盘)
     * dir_name:  要挂载到的目录(比如/mnt/xxx)
     * type:         挂载设备的文件类型(比如iso9660、ext2)
     * flags:         挂载模式:只读,等
     * data:         sys_mount()是VFS(框架)的接口,最终会调用一些具体文件系统的驱动接口,data由不同驱动自行解释
    */
   

    /*
     * 所谓挂载,就是用一个vfsmount结构,建立目标目录dentry与设备根目录dentry的"等价"关系,下次访问目标目录时,就是访问到挂载设备的根目录
     * 所以该函数主要做3件事(先不用关心do_remount()、do_loopback(),后面再分析):
     * ① 找到目标目录dentry(path_init()、path_walk(),详见:http://www.xxx.html
     * ② 找到挂载设备dentry(get_sb_bdev(),参数dev_name此时只是设备路径,而不是设备中的文件系统路径)
     * ③ 分配vfsmount结构建立连接
    */
   

    /*
     * 可以看出,该函数纯粹通过设备名称找对应的文件系统类型信息,所以设备名称是有规范的,比如硬盘为hda1等
     * file_system_type结构中最关键的是read_super函数指针,它指向相应文件系统驱动程序提供的超级块读取函数
     *
     * 内核直接支持的文件系统(即直接编译到内核的文件驱动),以及通过ko文件动态安装到内核的文件驱动,都会注册到file_systems数组
     * 从页该函数的过程也自然容易理解了(依赖“设备驱动”的知识,暂不深入分析):
     * ① 先从file_system找一遍,找到了则返回
     * ② 如果步骤①没返回,则找一下是否有相关的驱动,有的话自动安装并再次查找(可以看出ko文件除了用insmod手动安装,内核也可能在运行时自动安装)
    */
   

    /*
     * FS_NOMOUNT:不支持挂载的文件系统(比如一些虚拟文件系统)
     * FS_REQUIRES_DEV:需要物理基础的设备(大部分属于这种,比如ext2、minix、ufs、iso9660等)
     * FS_SINGLE:有些文件系统在内存中的超级块,是按类型建立的(比如一些虚拟文件设备,同一类型多个设备内存中只会出现一个超级块)
     *
     * 除以上情况,一般也是虚拟文件系统,暂时只关心FS_REQUIRES_DEV的情况,从而对get_sb_bdev()进行分析(其实就是do_mount()需要做的第②件事,通过挂载设备的超级块,找到该设备中文件系统的根目录dentry):
     * VFS系统的很多结构,都是基于各种具体驱动相关结构的抽象,主要体现在这些结构中的一些函数指针指向不同,以及在具体操作函数中对这些抽象结构的函数指针设置不同
     * get_sb_bdev()函数一般会执行到blkdev_get()→read_super()这个分支,由VFS进入具体的驱动函数,"打开"、读入超级块,同时又在具体的驱动接口中,将VFS层传入的抽象结构中的函数指针,设置为该驱动模块中的函数
    */
   

   

   

    经过稍微漫长的过程,终于把挂载设备的超级块读进来了,该设备上文件系统的根目录dentry也自然可以获取到,只不过分析过程中,遇到即将进入具体驱动程序的时候,我们就撤退了,因为文件系统的种类非常多,而且不影响对挂载总体过程的理解,可以根据自己的需要,选择一种或几种文件系统,比如ext2,将驱动中具体的接口,与VFS抽象接口对应起来,并完整的走一遍。

    /*
     * 通过这个函数,可以理解一下vfsmount其它成员的作用,以及系统中所有设备之间的关系图
    */
   


    总结:挂载的基本道理其实非常简单,就是用一个vfsmount结构,将挂载设备的根目录dentry与挂载目录dentry关联进来,而且内核抽象出了VFS层,让我们可以先清醒的理解完框架,再清醒的攻破各个更具体的环节。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP