linux进程空间、页缓存和虚拟文件系统图

        linux内核与实现中分别大致介绍了内核子系统的各个模块,并给出了该模块下重要的数据结构。但是,阅读过本书之后(感觉底层确实欠缺)发现只是对各个子系统分别有了一个大致的印象,单凭自己的理解难以将各个系统之间串联起来,尤其是每个内核子系统总是涉及较多的数据结构。趁着即将元旦假期,花点时间将内核中的虚拟文件系统、进程地址空间、页缓存以及内存映射之间的关系建立一个大致的框图。有关于各个子系统内部的结构体之间的关系,尤其是虚拟文件系统,请参考图中红色部分的博客地址。关于虚拟内存,逻辑地址、线性地址和物理地址之间的转换请参考途中蓝色部分的博客。

        下文中的图是根据《linux内核设计与实现》以及众多的博客画出,希望能对初步了解linux内核的同学有所帮助。


图 1 linux进程地址空间、虚拟文件系统以及页缓存之间的关系

对上图的说明和补充:

       由于空间有限,因此只画出了linux下虚拟文件系统、进程地址空间的部分结构体中的部分成员变量。

       1、每个模块都维护了一个X_op指针指向它所对应的操作对象X_operations;

       2、超级块(图中未画出,与一个文件系统相对应)维护了一个s_files指针指向了“已打开文件列表模块",即内核所有的打开文件的链表,这个链表信息是所有进程所共享的,便于进程之间打开文件时共享已经存在于系统物理内存中缓存信息;

       3、目录块操作和inode模块都维护了一个X_sb指针指向超级块,从而可以获得整个文件系统的元数据信息;

       4、目录项对象和inode对象各自维护了指向对方的指针,可以方便的找到对方的数据;

       5、已打开文件列表上每个file结构体实例维护了一个struct path,struct path中维护着指向vfsmount和dentry结构体的指针,从dentry指针中可以方便的查找到其对应的目录项,从而可以根据目录项找到对应的inode信息;

       6、已打开文件列表上每个file结构体示例维护了一个f_op指针,指向可以对这个文件进行操作的所有函数集合file_operations;

       7、indode结构体不仅有何其他模块关联的指针,重要的是它可以指向address_space模块,从而获得自身文件在内存中的缓存信息;

       8、address_space结构体内部维护了一个基数树,用于管理属于该address_space结构体的所有物理页结构---struct page,同时维护一个host指针指向inode来获得文件的元数据;

       9、内核使用task_struct来表示单个进程的描述符,其中包含一个进程的所有信息。task_struct结构体维护了一个files的指针(该指针和"一打开文件列表“上的表项是不同的指针)来指向结构体files_struct,files_struct中包含了文件描述符表和文件对象信息;

       10、file_struct中的文件描述符表其实是个file类型的指针列表(和"已打开文件列表"上的表项是相同的指针),可以支持动态扩展,每一个指针指向虚拟文件系统中文件列表模块的某一个已经打开的文件;

       11、过个进程可以同时指向一个打开文件对象(未见列表表项),例如父进程和子进程共享文件对象;

       12、一个进程可以多次打开同一个文件,生成不同的文件描述符,每个文件描述符指向不同的文件列表。但是由于是同一个文件,inode是唯一的,所以这些文件表项最终指向同一个inode。通过这样的方法实现文件共享;

        关于页缓冲、快缓冲以及系统读取文件与页缓冲和快缓冲之间的交互,将会在接下来的文章中介绍。

猜你喜欢

转载自blog.csdn.net/gdj0001/article/details/80135018