由于在下水平相当有限,不当之处,还望大家批评指正^_^
在Linux shell中执行mount命令,通常可以看到某个做了文件系统的磁盘分区或flash分区或内存文件系统做为所谓的根文件系统被mount到了挂载点/处。
实际上内核中最初始的根文件系统,并不是来自内核外部,他是由内核自己构建出来的。
为了说明这个过程,我们先说说mount的过程。
系统调用sys_mount是在fs/namespace.c中实现的,主要工作则由do_mount完成。
一个常规的mount操作大致包含两个动作:
(1)将一个文件系统加载到内核中
注意,这里仅仅是加载。
该动作是由vfs_kern_mount完成的。
每一个文件系统被加载到内核后,内核中都会产生如下几个结构:
一个struct mount结构
一个struct super_block结构
一个struct dentry结构,他是此文件系统的根目录的目录顶,名称为/。注意仅仅是此文件系统的根目录。
struct mount结构中有指针分别指向super_block结构和此文件系统的根目录顶结构。
super_block结构和此文件系统的根目录顶结构也有指针相互指向对方。
另外,struct mount结构中的mnt_devname记录了所mount的块设备文件。
(2)将上一步加载的文件系统,挂接到以/为起点的目录树中的某个位置处。
此工作由do_add_mount完成。
其实就是将此mount结构串接到某个已有的文件系统内的某个目录项上(类型需要为目录)。
实质性的操作函数如下:
void mnt_set_mountpoint(struct mount *mnt,struct mountpoint *mp,
struct mount *child_mnt)
{
mp->m_count++;
mnt_add_count(mnt, 1); /* essentially, that's mntget */
child_mnt->mnt_mountpoint = dget(mp->m_dentry);
child_mnt->mnt_parent = mnt;
child_mnt->mnt_mp = mp;
}
这里child_mnt为被挂载的文件系统的mount结构。
mp->m_dentry是挂载点路径中最后一个目录对应的目录项。
mnt为mp->m_dentry所在文件系统的mount结构。
另外,mp->m_dentry->d_flags还会被置上 DCACHE_MOUNTED标记,
这个动作完成后,外界就可以访问到这个文件系统了。
这个过程感觉挺复杂,在下对其代码实现理解得也很有限^_^
不过,可以通过open系统调用的实现,看到内核遍历路径的过程中,是如何转向被挂载的文件系统内部的。
下面列出了sys_open的函数调用链(从上到下),
其中最后的函数__lookup_mnt展示了由挂载点目录项查找被挂载的文件系统对应的str