04. 文件系统的挂载

了解了文件系统后,也理解了他是如何进行路径解析找到对应文件的情况后,如果是本机的情况下,是可以很好地通过地址进行方法,但是,我们常常会使用U盘,使用移动硬盘,在我们使用的过程中,外部的系统是如何与我们的本地的文件系统产生关联的呢?我们是如何访问它们的呢,因为在本机的情况下我们都是使用文件路径进行访问的,外部的系统应该使用怎样的路径进行访问?

实际上,文件挂载就是解决文件系统的路径名问题

文件挂载命令与效果

首先将 udisk 挂载到 mnt

lqy@lqy:~/projects/tmp$ ls
mnt  udisk
lqy@lqy:~/projects/tmp$ sudo mount --bind udisk/ mnt/

当我们将udisk\挂载到mnt\之后,我们在mnt\中进行的操作实际上就是对udisk\的操作

lqy@lqy:~/projects/tmp$ touch mnt/hello1.c
lqy@lqy:~/projects/tmp$ sudo umount mnt/
lqy@lqy:~/projects/tmp$ tree
.
├── mnt
└── udisk
    └── hello.c

mnt中创建了文件实际上是在udisk\创建的文件,当解除挂载后,我们会看见原本的mnt\中是没有文件的

并且,如果一个路径原本有文件,但是之后成为挂载点后,他原本目录的文件是会被忽略的

lqy@lqy:~/projects/tmp$ touch mnt/hello1.c
lqy@lqy:~/projects/tmp$ tree
.
├── mnt
│   └── hello1.c
└── udisk
    └── hello.c

3 directories, 2 files
lqy@lqy:~/projects/tmp$ sudo mount --bind udisk/ mnt/
lqy@lqy:~/projects/tmp$ tree
.
├── mnt
│   └── hello.c
└── udisk
    └── hello.c

会发现在未挂载的情况下在mnt\下创建了一个hello1.c文件,当之后挂载后,会发现原本的文件没有了,只有挂载的文件系统中的文件

以上就是文件挂载的命令和效果,然后我们来主要理解一下挂载过程以及为什么会有这样的效果

理解挂载过程

正如之前所说的,挂载本质上就是解决文件系统的路径问题,要将文件系统和父系统产生联系,从而使用父系统的路径访问子系统。

整个过程是这样的,当我们挂载文件系统的时候,VFS会创建2个关键对象 vfsmountsuper_block 对象

  • 对于super_block我想我们都很熟悉,对于每一个文件系统在其格式化之后都会有super_block来管理整个硬件的状态,在挂载的时候,内核会将硬件的super_block信息存储在内核中,即存储在内存中
  • 另外,对于vfsmount对象,他描述了文件系统mount的所有信息
    • 父文件系统的挂载点:vfsmount->mnt_mountpoint = /mnt
    • 子文件系统的根目录:vfsmount->mnt_root = superblock->s_root

在初始化vfsmount对象后,会将该对象添加到VFSMOUNT hash table

好,以上就是一些基本的点,但是我想现在我们还是不太明白,所以我们来过一遍对应的文件路径解析来更清楚的理解一下对应所需要的数据以及流程

文件路径解析

首先所有的数据都是从父系统开始的,整个父系统的解析就和之前的路径解析是一样的,假设路径解析到了mnt/我们对应的挂载点,这个时候,他就会有不同:

  1. 当一个目录项成为了挂载点的情况下,我们会按照之前的逻辑寻找到对应路径的data block,然后查看目录项的时候,会发现他的目录项中dentry标记为DCACHE_MOUNTED,路径解析时对该目录的目录项屏蔽
  2. 他会计算此目录项的hash值,然后根据VFSMOUNT hash table查找到对应的vfsmount对象
  3. 根据vfsmount->mnt_root,找到子文件系统的根目录
  4. 按照一般的逻辑,查找子文件系统指定目录下的文件

整体的逻辑图类似于:

文件挂载逻辑解析

这也就是为什么原本挂载点的文件会被屏蔽,并且能找到子系统的文件

posted @ 2025-03-18 16:14  rustic-stream  阅读(34)  评论(0)    收藏  举报