mount --bind和硬连接的区别
硬链接无法链接目录,而软链接虽然可以链接目录,但在有些程序里对符号链接(软链接)的支持并不友好,这个时候,我们可以通过和mount --bind
命令来将两个目录连接起来。
新建两个目录a和b,可以发现两个目录的inode号是不同的:
root@generalai-cpu-0:~/test# mkdir a
root@generalai-cpu-0:~/test# mkdir b
root@generalai-cpu-0:~/test# ls -lid a b
774157 drwxr-xr-x 2 root root 4096 Jun 25 13:42 a
774159 drwxr-xr-x 2 root root 4096 Jun 25 13:42 b
将两个目录bind起来,会发现inode号全部变成了之前a的inode号了:
root@generalai-cpu-0:~/test# mount --bind a b
root@generalai-cpu-0:~/test# ls -lid a b
774157 drwxr-xr-x 2 root root 4096 Jun 25 13:42 a
774157 drwxr-xr-x 2 root root 4096 Jun 25 13:42 b
所以mount --bind
命令是将前一个目录挂载到后一个目录上,所有对后一个目录的访问起始都是对前一个目录的访问。
看起来,mount --bind
命令和硬连接很像,都是连接到同一个inode上面,只不过硬链接无法链接目录,而mount --bind
命令弥补了这个缺陷,所以很多人认为将这个命令理解位针对目录的硬链接,但是这种想法是大错特错的!!, 因为这两者的系统执行原理是不一样的。
当mount --bind
命令执行后,Linux将会把被挂载目录的目录项(也就是该目录文件的block,记录了下级目录的信息)屏蔽,在本例中也就是b的下级路径全部隐藏起来了(只是隐藏不是删除,数据都没有改变,只是访问不到了),同时,内核将挂载目录(本例为a)的目录项记录在内存里的一个s_root对象里。
在mount命令执行时,VFS会创建一个nfsmount对象,这个对象里包含了整个文件系统所有的mount信息,其中也包含本次mount中的信息,这个对象是一个HASH值对应表(HASH值通过对路径字符串的计算得来),表里就有a到b两个目录的HASH值对应关系。
命令执行完后,当访问b下的文件时,系统会告知b的目录项屏蔽掉了,自动转到内存了找VFS,通过vfsmount了解到b和a的对应关系,从而读去到a的inode,这样在b下读到的全市a目录下的文件。
由上述过程可知,mount --bind
和硬链接的主要区别有:
mount --bind
链接的两个目录的inode号不一样,只是被挂载目录的block屏蔽了,inode被重新在VFS中定向到了挂载目录的inode(被挂载目录的inode和block依然没变)- 两个目录的对应关系存在于内存里,一旦重启挂载关系就不存在了
