一、文件系统架构
1、Linux文件系统的架构如下图,分为用户空间、内核空间和硬件3个部分。
- 用户空间层面
应用程序使用glibc库封装的标准I/O流函数访问文件。分别使用fopen(打开)、fclose(关闭)、fread(关闭)、fwrite(写)、fseek(设置文件偏移)等。
- 硬件层面
外部存储设备分别为块设备、闪存、NVDIMM设备。
- 内核空间层面
由于内核支持多种文件系统类型,为了给用户提供统一的操作接口,内核实现一个抽象层,虚拟文件系统(VFS)。文件系统分为以下4种:
- 块设备文件系统,机械硬盘和固态硬盘等块设备。常用的是文件系统EXT和btrfs。
- 闪存文件系统,存储设备为NAND闪存和NOR闪存。常用的是JFFS2、UBIFS。
- 内存文件系统,常用的是tmpfs。
- 伪文件系统,是为了使用虚拟文件系统的编程接口。常用的是sockfs、proc、sysfs、hugetlbfs、cgroup等。
二、虚拟文件系统的数据结构
虚拟文件系统定义一套统一的数据结构。
- 超级块。文件系统的开始部分是超级块,描述文件系统的总体信息,挂载文件系统时,内存中创建结构体super_block。
- VFS在内存中把目录组织为一棵树,进程根据树目录访问对应的文件系统。
- 根据文件系统的超级块格式,注册文件系统类型file_system_type.
- 索引节点。每个文件对应一个索引节点,每个索引节点有唯一编号。当内核访问存储设备上的文件时,会在内存中创建索引节点的结构体inode。
- 目录项。当内核访问存储设备上的一个目录项时,会在内存中创建该目录项的一个副本:结构体dentry。
- 当进程打开一个文件的时候,VFS就会创建文件的一个file结构体,然后为文件表中分配一个文件描述符,最后把文件描述符和file结构体的映射添加到打开文件表中。