前言
前2章分别介绍了VFS的基本数据结构和初始化流程。本章介绍VFS文件系统的使用。文件系统使用大多是从应用层系统调用开始的,下表是对文件系统系统调用的一个整理。
MOUNT
文件系统可以使用的前提是系统挂载(Mount)成功。初始化过程中,Linux会预先挂载一些支撑系统运行的特殊文件系统,例如,sysfs、rootfs、tmpfs等。本节先介绍初始化过程中Kernel对rootfs和sysfs文件系统的直接挂载,接着以一个典型的文件系统类型(待补充)介绍在用户空间态做挂载后内核的执行流程。
初始化过程中文件系统挂载
rootfs 挂载
前一篇文章中我们看到系统初始化过程中挂载了rootfs,即根文件系统(/)。这里我们看一下rootfs挂载的细节。
1 | static void __init init_mount_tree(void) |
这里以shmem_fill_super为例,会为rootfs分配shmem 类型超级块的私有结构并进行填充,同时分配Inode以及Dentry,用来构建所有文件系统树的根目录(即’/‘)
1 | int shmem_fill_super(struct super_block *sb, void *data, int silent) |
shmem_fill_super可以直接分配shmem_inode cache,是因为初始化流程init_rootfs()中,已经执行了如下shmem的初始化(参考Linux虚拟文件系统(2)– 初始化流程 )。
1 | shmem_init() |
sysfs挂载
1 | static struct file_system_type sysfs_fs_type = { |
以上过程在rootfs_init初始化过程中执行,主要为向系统中注册sysfs sysfs_mount主要做以下事情:
分配kernfs_kern_info
为sysfs分配superblock
调用kernfs_fill_super来填充超级块
用户空间态一般文件系统挂载
在用户空间态执行系统挂载的命令如下:
mount [-t vfstype] [-o options] device dir
其中-t参数表示您要挂载的文件系统类型,-o为可选参数,device代表您要挂载的设备(可以是一个设备文件,也可以一个二级制文件系统包), dir表示文件系统要挂载到的目录。 假设用户(注意必须是root组用户才有权限执行)在根目录/执行如下挂载命令
mount -t yaffs rawfs.bin ./test
系统会执行系统调用,从用户空间态切换到内核态,并执行mount命令对应的系统调用sys_mount。从sys_mount开始,调用执行如下:
1 | SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name, char __user *, type, unsigned long, flags, void __user *, data) |
因为上边的挂载命令是执行新的挂载,因此,这里执行到的是do_new_mount
1 | do_new_mount |
vfs_kern_mount的流程与rootfs挂载中执行类似。此处差异只在于yaffs的type->mount(type, flags, name, data)执行的是yaffs的do_mount函数,之后会开专门的章节介绍yaffs。