Linux文件系统层次

  • 用户空间:用户使用的各种应用程序
  • 内核空间:进一步分为文件管理系统和设备驱动

文件管理系统:包括虚拟文件系统VFS和具体文件系统

设备驱动:包括缓冲区和设备驱动

虚拟文件系统

  • 虚拟文件系统:Virtual Filesystem Switch,一种对真实文件系统的抽象和软件实现,定义了所有文件系统都支持的、基本的 、 抽象的接口和数据结构

VFS对于具体的文件系统,允许同时使用不同的文件系统,例如在不同的文件系统之间复制或移动文件,而对于其他内核的子系统及其用户的各种不同应用程序,VFS提供统一接口,使得程序开发者无需关注Linux实际使用的文件系统,因此Linux支持同时使用多个不同的文件系统

具体文件系统(如ext4,xfs,btrfs等等)实现了VFS 定义的抽象接口和数据结构,将自身的诸如文件 、 目录等概念在形式上与 VFS 的定义保持一致,在统一的接口和数据结构下隐藏了具体的实现细节

  • VFS的数据结构

超级块:superblock,存放系统中已安装的文件系统的所有信息,对基于磁盘的文件系统,这类对象通常对英语存放在磁盘上的文件系统控制块,即每个文件系统都有一个超级块对象

索引节点:index node,存放对于具体文件的元数据信息,每个文件都有一个索引节点,每个索引节点对象有一个索引节点号,该号唯一标识了在某个文件系统中的指定文件

目录项:dentry,存放目录项与对应文件进行链接的信息,VFS将每个目录是为有若干个子目录和文件组成的常规文件

文件:file,存放打开文件与进程之间进行交互的信息,该信息仅当进程访问文件存放于内存中

Ext4

图片显示了Ext4的布局,磁盘划分为分区,每个分区又划分为N个块组,每个块组中又根据块组的编号有不同的内部结构

  • 引导快:该磁盘分区的第一个块,若该分区存放操作系统,则记录引导启动信息,用于引导启动该分区安装的系统,通常占用2KB
  • 超级块:记录关于封闭文件系统的各种信息,比如块数量(已用和未用数量),inode数量(已用和未用数量),支持的功能特性,维护信息(比如分区上有多少个块组,块组的数据区和元数据区,)等等

超级块有备份,一般只使用块组0中的超级块(即主超级块),主超级块损坏则可以从超级块的备份信息中恢复

  • 块组描述符:Group Descriptor,GDT,主要包含块位图,inode位图和inode表位置,当前空闲块数,inode数及其使用的目录树(用于平衡各个块组目录数),每个块组都有一个

GDT同样有备份

  • 预留GDT:创建文件兄同时,为了便于将来扩展文件系统,块组描述符表后分配预留的数据块
  • 块位图:Block bitmap,用来标识Block Group中的block使用情况,其中的每一位代表该Block Group中的一个block,如果是1则代表使用,如果是0则代表空闲

通过Block bitmap,可以快速知道该block group中每个block的使用情况

  • inode位图:inode bitmap,用于描述该块组所管理的inode的分配状态,如果inode位图中相应位置为1,那么代表该inode已经分配出去,否则可以使用

inode中包含下列信息:inode编号,文件大小,属主(User ID),属组(Group ID),权限(rwx),时间戳(ctime,mtime,atime),链接数,指向存放文件实际数据块的块指针(直接指针和最高三级间接指针)

  • inode表:inode table,用于存储inode信息,占用一个或多个块(占用多块的目的是更好的利用空间),大小取决于文件系统创建时的参数
  • 数据块:data block,前面的数据结构存放了Ext4文件系统的元数据,其他磁盘空间用于存放文件的真正内容,因此称为数据块

Ext4文件管理

Ext4文件系统内部使用inode number识别文件,任何文件在其分区内都有为一个的inode number,且通过块指针与文件数据关联,文件名仅用于使用者方便记忆,实际上Ext4不存储文件名

由于Linux一切皆为文件(磁盘设备也是),因此目录文件的结构非常简单,也即一系列的目录项的列表,每个目录项均由目录直接子文件的文件名和对应的inode号码组成,根目录由Linux内核直接管理并记录其inode number

  • 需要注意的是,子文件的子文件不会记录在目录内,因为不是直接子文件,目录项内仅记录直接子文件

因此通过根目录及其子目录,找到文件名对应的inode number,再根据inode number中指向数据块的块指针就可以找到文件内容数据

示例:假如说想要找到/home/temp/test.txt文件

  • 先通过内核找到根目录的inode number,并通过该inode number找到根目录的块指针
  • 通过块指针找到根目录的数据块,根据其中的数据找到下级目录/home对应的inode number
  • 重复上述步骤,直到找到test.txt文件

需要注意的是,文件查找过程不一定可以找到,若文件不存在,则在查找/home/temp的目录项时会发现没有test.txt的记录,从而报错:No such file or directory

对于ls等命令,仅需要找到/home/temp的目录项即可,而对于vim或cat访问test.txt文件的命令,则需要找到最后的数据块

  • 硬链接

多个文件同时只想一个inode,这些文件的inode number相同

硬链接表名文件可能通过不同的文件名访问

但是不能对目录创建硬链接

硬链接不能跨分区

每多一个硬链接,inode中的引用计数器会+1

  • 软链接

文件及其软链接使用的不是同一个inode,因此inode number不相同

软链接实际数据是另一个文件的路径,即本质是一个字符串,软链接文件的大小取决于该路径字符串的长度

可以对目录创建软链接

可以跨分区

增加文件软链接不会增加inode引用计数器