Linux下的文件系统结构
目前在Linux操作系统中支持很多种文件系统,包括Ext2、ext4、Btrfs和XFS等,多达几十个文件系统。虽然支持的文件系统种类很多,但从用户层面使用方式无任何差别,用户并不感知其中的差异。对于普通用来说,数据都是组织成上文所述的树状结构。
Linux操作系统对各种文件系统的支持是通过名为VFS的组件实现的,也就是虚拟文件系统(Virtual File System)。如图所示,VFS作为一个抽象层,为用户提供统一的接口,屏蔽了其它具体文件系统(例如Ext4和Btrfs等)的实现。VFS为用户提供了open、close、read和write等接口。
文件系统到底是怎么管理磁盘,如何将磁盘空间转换为我们看到的文件夹和文件?
方法就是把磁盘划分为一个个的小块,就像切豆腐一样。然后把磁盘划分为不同的功能区,比如元数据区和数据区。而元数据区其实实现对磁盘空间的管理,就好像前文说的账本,里面记录着哪些磁盘空间被使用,哪些磁盘空间已经被占用。
经过文件系统的管理之后,文件内的数据就被映射到磁盘上的一块块的空间。而文件和磁盘空间的关系由文件系统管理,不需要用户操心。如下图所示,某个文件被映射到磁盘中的3个不同的空间。
实际的映射关系比可能比上图要复杂得多,但基本原理是这样。用户关心的只是文件名称和路径,而其存储的数据则有文件系统管理。当然,每个文件系统对数据的组织形式是不同的,以Ext2文件系统为例,其形式下图所示,其通过一些磁盘指针的方式记录了文件数据的存放位置,这样当用户读取数据时,文件系统根据数据的偏移地址和其记录的对应关系就可以找到数据具体存储在磁盘的什么位置,并进行读取。
Linux文件系统组成
Linux文件系统由三部分组成 : 文件名,inode,block
Linux文件系统: ext3,ext4,xfs
windows文件系统: FAT32,NTFS
Ext2 文件系统为例
- 文件系统最前面有一个启动扇区(boot sector)
- 这个启动扇区可以安装开机管理程序, 这个设计让我们能将不同的引导装载程序安装到个别的文件系统前端,而不用覆盖整个硬盘唯一的MBR, 也就是这样才能实现多重引导的功能
- 把每个区进一步分为多个块组 (block group),每个块组有独立的inode/block体系
- 如果文件系统高达数百 GB 时,把所有的 inode 和block 通通放在一起会因为 inode 和 block的数量太庞大,不容易管理
- 这其实很好理解,因为分区是用户的分区,实际计算机管理时还有个最适合的大小,于是计算机会进一步的在分区中分块
- (但这样岂不是可能出现大文件放不了的问题?有什么机制善后吗?)
- 每个块组实际还会分为分为6个部分,除了inode table 和 data block外还有4个附属模块,起到优化和完善系统性能的作用
inode table
- 主要记录文件的属性以及该文件实际数据是放置在哪些block中,它记录的信息至少有这些:
- 大小、真正内容的block号码(一个或多个)
- 访问模式(read/write/excute)
- 拥有者与群组(owner/group)
- 各种时间:建立或状态改变的时间、最近一次的读取时间、最近修改的时间
- 没有文件名!文件名在目录的block中!
- 一个文件占用一个 inode,每个inode有编号
- Linux 系统存在 inode 号被用完但磁盘空间还有剩余的情况
- 注意,这里的文件不单单是普通文件,目录文件也就是文件夹其实也是一个文件,还有其他的也是
- inode 的数量与大小在格式化时就已经固定了,每个inode 大小均固定为128 bytes (新的ext4 与xfs 可设定到256 bytes)
- 文件系统能够建立的文件数量与inode 的数量有关,存在空间还够但inode不够的情况
- 系统读取文件时需要先找到inode,并分析inode 所记录的权限与使用者是否符合,若符合才能够开始实际读取 block 的内容
- inode 要记录的资料非常多,但偏偏又只有128bytes , 而inode 记录一个block 号码要花掉4byte ,假设我一个文件有400MB 且每个block 为4K 时, 那么至少也要十万条block 号码的记录!inode 哪有这么多空间来存储?为此我们的系统很聪明的将inode 记录block 号码的区域定义为12个直接,一个间接, 一个双间接与一个三间接记录区(详细见附录)
data block
- 放置文件内容数据的地方
- 在格式化时block的大小就固定了,且每个block都有编号,以方便inode的记录
- 原则上,block 的大小与数量在格式化完就不能够再改变了(除非重新格式化)
- 在Ext2文件系统中所支持的block大小有1K, 2K及4K三种,由于block大小的区别,会导致该文件系统能够支持的最大磁盘容量与最大单一文件容量各不相同:
- Block 大小 1KB 2KB 4KB
- 最大单一档案限制 16GB 256GB 2TB
- 最大档案系统总容量 2TB 8TB 16TB
- 每个block 内最多只能够放置一个文件的资料,但一个文件可以放在多个block中(大的话)
- 若文件小于block ,则该block 的剩余容量就不能够再被使用了(磁盘空间会浪费)
- 所以如果你的档案都非常小,但是你的block 在格式化时却选用最大的4K 时,可能会产生容量的浪费
- 既然大的block 可能会产生较严重的磁碟容量浪费,那么我们是否就将block 大小定为1K ?这也不妥,因为如果block 较小的话,那么大型档案将会占用数量更多的block ,而inode 也要记录更多的block 号码,此时将可能导致档案系统不良的读写效能
- 事实上现在的磁盘容量都太大了,所以一般都会选择4K 的block 大小
superblock
- 记录整个文件系统相关信息的地方,一般大小为1024bytes,记录的信息主要有:
- block 与inode 的总量
- 未使用与已使用的inode / block 数量
- 一个valid bit 数值,若此文件系统已被挂载,则valid bit 为0 ,若未被挂载,则valid bit 为1
- block 与inode 的大小 (block 为1, 2, 4K,inode 为128bytes 或256bytes);
- 其他各种文件系统相关信息:filesystem 的挂载时间、最近一次写入资料的时间、最近一次检验磁碟(fsck) 的时间
- Superblock是非常重要的, 没有Superblock ,就没有这个文件系统了,因此如果superblock死掉了,你的文件系统可能就需要花费很多时间去挽救
- 每个块都可能含有superblock,但是我们也说一个文件系统应该仅有一个superblock 而已,那是怎么回事?事实上除了第一个块内会含有superblock 之外,后续的块不一定含有superblock,而若含有superblock则该superblock主要是做为第一个块内superblock的备份,这样可以进行superblock的救援
Filesystem Description
- 文件系统描述
- 这个区段可以描述每个block group的开始与结束的block号码,以及说明每个区段(superblock, bitmap, inodemap, data block)分别介于哪一个block号码之间
block bitmap
- 块对照表
- 如果你想要新增文件时要使用哪个block 来记录呢?当然是选择「空的block」来记录。那你怎么知道哪个block 是空的?这就得要通过block bitmap了,它会记录哪些block是空的,因此我们的系统就能够很快速的找到可使用的空间来记录
- 同样在你删除某些文件时,那些文件原本占用的block号码就得要释放出来, 此时在block bitmap 中对应该block号码的标志位就得要修改成为「未使用中」
inode bitmap
- 与block bitmap 是类似的功能,只是block bitmap 记录的是使用与未使用的block 号码, 至于inode bitmap 则是记录使用与未使用的inode 号码
示例1
用stat命令,查看某个文件的inode信息: [root@localhost mytest]# stat a.txt
示例2
使用ls -i命令,可以看到文件名对应的inode号码 [root@localhost mytest]# ls -i a.txt
示例3
查看每个硬盘分区的inode总数和已经使用的数量,可以使用df命令
[root@localhost mytest]# df -i
,