linux内核之虚拟文件系统

虚拟文件系统

虚拟文件系统(VFS)作为内核的子系统,为用户空间程序提供了文件和文件系统的相关接口。总的来说,其作用就是提供一套标准化的通用接口给上层使用,而下层可以是不同的文件系统,VFS可以看作是一个抽象的中间层。

文件系统抽象层

VFS抽象层之所以能够衔接各种各样的文件系统,是因为它定义了所有文件系统都支持的、基本的、概念上的接口和数据结构。同时,实际的文件系统也将自身的操作在形式上与VFS的定义保持一致。通俗点说就是VFS提供基本的接口和数据结构,实际文件系统去实现具体的细节。所以在VFS和内核的其他部分来看,所有文件系统都是相同的(比如说,它们都支持文件和目录的概念,都有打开、读取、关闭的操作)。

在这里插入图片描述

例如,用户空间对写文件的操作,如下:
在这里插入图片描述

Unix文件系统

Unix使用了四种和文件系统相关的抽象概念:文件、目录项、索引节点和安装点(mount point)。

Unix中文件通过目录组织起来,目录可以容纳多个文件,目录也可以包含其他目录。在Unix中,目录也属于普通文件,它列出了包含在其中的所有文件,可以对目录执行和文件相同的操作。

inode:文件的相关信息和文件本身内容这两个概念在Unix中被区分开了。文件的相关信息,例如访问权限、大小、创建时间等,被称为文件的元数据,被存储在单独的数据结构中,该结构被称为索引节点(inode)。

超级块:文件系统控制信息存放在超级块中,超级块是一种包含文件系统信息的数据结构。

VFS对象

VFS采用面向对象的设计思路,使用一组数据结构来表示通用的文件对象。这些数据结构类似于对象(因为使用c语言实现,但是c语言中没有对象这个概念,因此用结构体表示),其中包含了数据以及操作这些数据的函数指针,而这些操作函数由具体的文件系统实现

VFS中四个主要对象
  • 超级块对象,代表一个具体的已安装文件系统
    该对象用于存储特定文件系统的控制信息。各种文件系统都必须实现超级块对象。在文件系统安装时,文件系统会调用相关函数从磁盘中读取超级块信息,并将其填充到内存的超级块对象中。

  • 索引节点对象,具体的文件
    包括了文件或目录的全部信息。如果实际的文件系统中没有索引节点这一概念(例如有些文件系统将文件信息和文件内容放在一起),文件系统也必须从中提供这些信息初始化到内存中的索引节点来供VFS使用。
    一个索引节点代表文件系统中的一个文件,索引节点只有当文件被访问是才会在内存中被创建。

  • 目录项对象,路径的组成部分
    VFS把目录也当作文件对待,但是VFS经常需要执行目录相关的操作,为了方便,引入了目录项的概念。在路径中,每一个部分都是目录项对象,VFS在执行目录操作时,会现场创建目录项对象。
    注意,目录项没有对应的磁盘结构,而是VFS根据路径名现场创建它(一个目录项对应一个索引节点)。目录项涉及到目录项缓存,是一个比较关键的点,需要查资料掌握。

  • 文件对象,由进程打开的文件
    文件对象是已打开文件在内存中的表示,由系统调用open创建,close系统调用撤销。文件对象中包含了访问文件时的一些信息,例如,文件的访问模式、当前的偏移等。

注意,VFS采用的是面向对象的思想,各种不同类型文件系统,都需要实现VFS提供的回调函数来满足VFS需要实现的目的(每种VFS对象中都有一个操作函数表)。例如,上述的四个对象结构中都包含了大量的操作函数(需要实际文件系统实现)。

和文件系统相关的数据结构

file_systerm_type

用来描述特定的文件系统类型,因为linux支持众多文件系统,因此内核必须由一个特殊的结构来描述每种文件系统的功能和行为(也就是说,每种文件系统都必须实现该结构)。具体结构如下:
在这里插入图片描述

vfsmount

当文件系统被安装时,会有一个vfsmount结构体在安装点被创建。该结构体用来代表文件系统的安装点。具体结构如下:
在这里插入图片描述

和进程相关的数据结构

系统中每个进程都有自己的一组打开的文件,像根文件系统、当前工作目录、安装点等。有三个数据结构将VFS层和系统的进程紧密联系在一起。它们分别是:file_struct、fs_struct和namespace结构体。

file_struct

该结构体定义在<linux/fdtable.h>文件中。由进程描述符中的files字段指向,所有与单个进程相关的文件信息(打开的文件以及文件描述符)都包含在其中,其结构如下:
在这里插入图片描述

fs_struct

该结构体由进程描述符的fs域指向,它包含当前进程的工作目录根目录。定义在文件<linux/fs_struct.h>中,其结构如下:
在这里插入图片描述

mmt_namespace

该结构体定义在文件<linux/mmt_namespace.h>中,由进程描述符中的mmt_namespace域指向。2.4内核版本以后,单进程命名空间被加入到内核中,它使得每一个进程在系统中都看到唯一安装的文件系统(不仅是唯一的根目录,而且是唯一的文件系统层次结构)。其结构如下:
在这里插入图片描述

对多数进程来说,他们使用的file_struct和fs_struct结构都是唯一的,但是对于那些使用CLONE_FILE或CLONE_FS创建的进程,父子进程会共享这两个结构,并通过引入计数来控制。

注:声明一下,关于linux内核分析我都是概要的记录一下(记录自己认为每个模块中重要的地方),其作用是在心中有一个大概的轮廓,具体的细节还需到各个模块代码中深入研究。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值