Skip to content

文件管理

文件管理是操作系统进行持久化管理的整一套链路。包括从对底层磁盘等外部存储设备的管理,到对于提供给上层用户的文件接口。在用户打开了一个文件,并写入数据的过程中,涉及了多个子系统的配合。

其中包括:

应用层

在应用层,用户态程序以进程为单位来维护进程本身所使用的资源。用户程序需要使用一个文件的时候,会先打开文件,此时操作系统,为进程建立一个可以用来访问文件的抽象 struct File 结构,并返回一个 int 类型的文件描述符,其实就是 file 结构在进程结构体里面存放的数组索引,之后进程通过文件描述符来访问文件资源。

系统调用

用户程序调用 open、read、write 等文件操作系列的系统调用,进入内核态来管理文件。内核根据文件描述符查找对应 struct file,调用虚拟文件系统(VFS)的相应 struct file_operations 接口中的处理请求。例如:

  • open:创建或查找文件,分配文件描述符。
  • write:通过 VFS 将数据写入底层设备。
  • close:释放文件描述符和相关资源。 文件相关的系统调用确保用户态程序与内核安全交互,同时屏蔽底层复杂性,提供了统一的文件访问接口。

VFS

Linux 继承了 Unix 系统的经典哲学——一切皆文件的思想。虚拟文件系统(Virtual File System,VFS)是 Linux 内核中的一个重要抽象层,它为不同的文件系统提供了统一的接口,使得应用程序可以用相同的方式访问不同类型的文件系统。

注意区分虚拟文件系统和文件系统,虚拟文件系统是 Linux 的管理文件的子系统,而文件系统是一种通用的协议。

在 VFS 层,对上提供 dentry 对象用于构造一个虚拟的运行时文件树结构,对下使用 inode 结构封装来自于各个结构的物理数据源。

协议层

协议层是用于屏蔽底层的设备抽象层中的两种设备模型的差异的,字符设备、块设备,其中字符设备较为简单,而块设备有更加复杂的抽象机制。

字符设备块设备
vfs 直接和驱动交互通过文件系统协议和块设备子系统操作硬盘,将硬盘中的文件元数据映射成一个 inode 的后端数据源,供 inode 来调用操作

文件系统

文件系统是一种协议,规定了如何在磁盘上组织和存储数据。因为,磁盘是块设备,可以看作是一个具有固定大小的字节数组。而我们打开一个磁盘看到的却是一个树形的文件目录结构,如何在一个字节数组上去存储一个树形的文件目录结构,就是文件系统干的事情。文件系统是一个相较于独立的模块,可以在操作系统中独立安装和卸载,并同时存在不同的文件系统。

  • 文件系统是跨操作系统的,一个操作系统只要能够实现一个文件系统就可以,从一个使用某种文件系统组织数据的磁盘中获取数据
  • 同一个系统管理的不同的磁盘也可以使用不同文件系统来管理
  • 文件系统与磁盘驱动之间没有直接关联,文件系统描述的是字节数据的组织形式,而磁盘驱动负责从磁盘读写字节数据块;但是文件系统往往需要间接调用驱动来帮它读写数据,操作硬件。
  • 磁盘在挂载到虚拟文件系统前需要格式化,格式化过程就是建立文件系统的过程。

块设备子系统

块设备子系统是用于直接操作磁盘驱动完成 IO 读写的模块,它为 Linux 上的各种文件系统提供了一个 bio 机制,让不同的文件系统不必关心驱动的接口,只需关注磁盘文件的组织逻辑,方便了文件系统的安装和拆卸。

设备层

设备管理层负责设备的初步抽象和驱动程序封装。向上暴露驱动程序对象,上层模块只需调用驱动封装好的接口即可完成自己的业务逻辑。

目前主要是三种设备,抽象出了三种不同的驱动,而 VFS 只对接字符设备和块设备,网络设备走的是 socket API。

对于字符设备而言,VFS 通过 inode 直接访问字符设备的驱动,实现设备调用。对于块设备,VFS 通过中间的文件系统协议层——块设备子系统和文件系统协议来访问块设备,通过 inode 封装块设备中的一个个文件,从而实现文件资源的访问。