最近看到几篇介绍VFS的韩语文章,觉得里面的众多绘图清晰易懂,冒昧将其摘选出来,分享给大家,希望大家可以从更多的角度去理解和认识VFS的构成和原理。原文地址位于 https://m.blog.naver.com/eldkrpdla121/220706907723,对应PPT链接在Ch 12 Virtual File System (VFS)。
正文
VFS的基本接口大家应该都比较熟悉了,比如open(), read(), write(), 而要知道这些基本操作的内核实现,得首先了解下构成VFS子系统的基础数据结构。
superblock和inode都位于磁盘,它们分别是「文件系统」和「单个文件」的control block(称为"meta data"),同时inode还记录了文件在磁盘上的data block的分布(即"user data")。
【进程和文件】
当进程试图访问磁盘上的一个文件时(比如执行open系统调用),需要将该文件的磁盘inode中的一部分信息拷贝到内存中,这部分内容进而构成了内存中的"struct inode"结构体。
之后,通过这个内存中的inode对象,就可以获取到所需访问的文件的内容。
那如果有多个进程访问磁盘上的同一个文件呢?
这就引出了另一重要的结构体"struct file","inode"对应磁盘上的文件实体,是全局的,而"file"记录的是进程和文件之间的关联,比如访问文件的位置(即"offset"),因而是进程私有的。
有了这一关联,进程就可以通过file table,访问到文件的meta data,进而获取到文件的user data,实现对数据的读写等操作(比如read和write系统调用)。
在描述进程的"task_struct"结构体中,由"files"域指向其打开文件的文件描述符表,由"fs"域指向其执行操作所在的目录和文件系统挂载点等相关信息。
【快速访问】
假设现在一个进程要在"/a/b/c/d/"目录下新建一个名称为"e"的文件,那么路径查找的过程大致如下:
在VFS的概念里,「目录」被视作一种特殊的文件,也具有对应的inode对象。因而在整个查找过程中,需要将多达6个inode的内容拷贝到内存。
如果能将之前获取的“路径结果”信息暂存起来(以dentry cache的形式),将大大加快路径访问的速度。
【小结】
可见,在构成VFS基石的四个数据结构中,"superblock"和"inode"是本就驻留在磁盘上(使用时会将其部分信息拷贝到内存中),而"file"和"dentry"则是为了文件访问的需要,在内存中诞生的,并不对应磁盘上的任何实体。