码迷,mamicode.com
首页 > 系统相关 > 详细

linux文件系统调用(1)---mount

时间:2014-11-20 23:46:11      阅读:263      评论:0      收藏:0      [点我收藏+]

标签:lock_mount   graft_tree   mount   mount_hashtable   mountpoint_hashtable   

术语表:

struct mount挂载点

struct mountpoint挂载点节点

struct vfsmount挂载项

源文件系统用户将要挂载的文件系统

目的文件系统挂载源文件系统的文件系统


一、目的

        本文将介绍linux挂载文件系统的过程,从系统调用mount()函数开始解析,主要分为三个阶段:

        1、新建源文件系统;

        2、查找目的文件系统的挂载目录;

        3、将源文件系统挂载到目的文件系统的挂载目录;

       本文以linux 3.10版本为基础进行讲解。


二、函数调用关系

        mount系统调用的定义在fs/namespace.c文件中,具体的定义为:SYSCALL_DEFINE5(mount,char __user *, dev_name, char __user *, dir_name, char __user *,type, unsigned long, flags, void __user *, data)

        其中,dev_name定义了设备路径;di_name定义了挂载目录;type定义了文件系统类型;flagsdata定义了一些选项内容。我们重点关注前三个参数,后两个参数目前不关注。

        下图描述了主要的函数调用关系,linux挂载文件系统主要分为三个阶段:

        1vfs_kern_mount()负责创建源文件系统;

        2lock_mount()负责在目的文件系统中查找挂载目录;

        3graft_tree()负责将源文件系统挂载到目的文件系统的挂载目录上;


bubuko.com,布布扣


三、目的文件系统

       为了便于描述,我们假设当前系统已经挂载了ext2文件系统(即目的文件系统),tmp目录将是目的文件系统的挂载目录。

        下面我们将要把ext3文件系统挂载到ext2tmp挂载目录上,使用的命令是mount(/dev/sda1, /tmp,  ext3)(省略了flagsdata参数)。

bubuko.com,布布扣


四、新建源文件系统

        首先do_mount()->do_new_mount()->vfs_kern_mount()根据type参数指定的文件系统类型,新建一个ext3文件系统。其中需要重点关注的是,vfs_kern_mount()->moutn_fs()根据实际文件系统的超级块mount回调钩子函数,填充超级块和文件系统内容(为了简化,图中只给出了最简单的ext3文件系统,即只有根目录)。

bubuko.com,布布扣


五、查找挂载目录并创建挂载节点

        do_mount()->do_new_mount()->do_add_mount()->lock_mount()的功能是递归的查找最终的挂载目录,这里的代码比较难懂,所以下面将详细描述。
        linux允许挂载目录上挂载多个文件系统,后面挂载的文件系统将“覆盖”之前挂载的文件系统。例如,minix文件系统挂载到ext3文件系统的tmp挂载目录下,nfs文件系统挂载到minix文件系统的/挂载目录下,最终使用ls命令将只能看见nfs文件系统,而minix被nfs“覆盖”了。
        其中,tmp目录指向minix挂载点的红色虚线仅仅表示逻辑关系,实际并不存在这样的指向关系,linux使用<挂载点,挂载目录>二元组作为哈希因子构成哈希表mount_hashtable的表项,用来查找已经挂载的文件系统。例如,minix挂载到ext3的tmp目录,那么linux就根据<ext3, tmp>二元组构成哈希表项,并且将minix记录到<ext3, tmp>哈希表项的链表中。当需要查找ext3的tmp目录下挂载了哪个文件系统时,可以根据<ext3, tmp>二元组找到相应的哈希表项,然后找到对应的已挂载文件系统minix。
bubuko.com,布布扣

        有了以上基础后,我们再回过头来看lock_mount()的功能,lock_mount()首先根据当前的<ext3, tmp>二元组找到已挂载的minix文件系统,然后根据<minix, />二元组找到已挂载的nfs文件系统,当找到最后一个文件系统时,根据nfs的根目录调用new_mountpoint()创建挂载节点(因为minix和nfs挂载到同一个挂载目录tmp下,所以在挂载minxi时已经创建了挂载节点,所以实际上nfs共用了minix的挂载节点,只是将挂载节点的挂载次数统计加1)。
        下面回到第四节描述的情形继续讲述,因为当前文件系统中只存在ext2文件系统,因此lock_mount()将根据ext2的挂载目录tmp调用new_mountpoint()创建挂载节点,并且将挂载节点指向挂载目录tmp,挂载次数统计加1,最后将挂载节点加入到mountpoint_hashtable哈希表中(该哈希表使用挂载目录tmp作为哈希因子)。

bubuko.com,布布扣


六、挂载源文件系统

        do_mount()->do_new_mount()->do_add_mount()->graft_tree()负责把新建的源文件系统ext3挂载到挂载节点上。mnt_set_mountpoint()负责将源文件系统指向挂载节点,commit_tree()负责将源文件系统ext3加入到mount_hashtable哈希表中。(注:图中省略了目的文件系统和源文件系统之间的父子关系)

bubuko.com,布布扣


七、总结

        linux挂载文件系统主要分为三个阶段:创建源文件系统,查找目的文件系统的最终挂载目录并创建挂载节点,最后将源文件系统关联到挂载节点上。


版权声明:

        原创作品,如非商业性转载,请注明出处;如商业性转载出版,请与作者联系。


linux文件系统调用(1)---mount

标签:lock_mount   graft_tree   mount   mount_hashtable   mountpoint_hashtable   

原文地址:http://blog.csdn.net/luomoweilan/article/details/41324187

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!