= 引文 =
上文中我们说到了file_system_type,以及一个文件系统是如何在内核中注册产生的。但是注册了一个文件系统并不代表这个文件系统被使用了,就像你注册了优快云帐号但是你不登陆就没有使用它。同理,你不挂载文件系统,这个文件系统在内核中就以一个file_system_type的形式存在,仅仅是存在这么一个type,并没有构建到全局文件系统树中。
回忆一下,注册file_system_type的时候我们主要提供两个成员给内核,一个是文件系统的名字,一个是mount这个文件系统的方法(其它参数也很重要,但重点就是这两个)。名字就是一个id,唯一标记一个文件系统,并方便内核在需要时根据它找到这个文件系统的file_system_type。mount方法在挂载这个文件系统时使用的,在需要挂载一个文件系统时通过name找到这个文件系统的file_system_type实例,然后使用这个实例中挂载的方法(mount函数),进行挂载。
当一个文件系统被挂载之后,一个文件系统实例就诞生并可以使用了。
= 使用mount系统调用 =
== 初探 ==
试想一下,我们如何挂载一个文件系统?常见的可能如下:
mount -t xfs /dev/sda1 /mnt -o ....
这应该是一个典型的mount命令的使用,其中包含了执行时几个重要参数——fstype, devname, mountpoint, options。我们经常使用,甚至可以说99%的人平时都是这样使用的,但是为了研究mount系统调用我们就应该研究mount系统调用函数,而不是mount命令,来看它的定义(man 2 mount):
int mount(const char *source, const char *target,
const char *filesystemtype, unsigned long mountflags,
const void *data);
从定义上看和mount命令需要的参数也差不多, source是要挂载的设备名,target是要挂载到哪,filesystemtype顾名思义就是文件系统类型名,以上都是字符串类型的参数,都可以直接写路径名或fsname。使用上述三个参数就一个可以完成一次简单的挂载操作。比如我们准备了一个/dev/sdc1的设备,和一个/mnt/testdir挂载点:
mkfs.xfs -f /dev/sdc1
mkdir /mnt/testdir
然后遍写mount_test_01.c程序:
#include <sys/mount.h>
#include <stdio.h>
int main(int argc, char *argv[]) {
if (mount("/dev/sdc1", "/mnt/testdir", "xfs", 0, NULL)) {
perror("mount failed");
}
return 0;
}
编译:
gcc -Wall -o mount_test_01 mount_test_01.c
执行:
./mount_test_01
如果没有返回错误,那么/dev/sdc1应该就应该挂载好了。来看一下挂载的结果:
findmnt /dev/sdc1
就能看到
TARGET SOURCE FSTYPE OPTIONS