内容源于《鸟哥的Linux私房菜》
文件系统
superblock,inode,block
superblock,inode,block数据简略说明:
- superblock:记录此 filesystem 的整体信息,包括inode/block的总量、使用量、剩余量, 以及文件系统的格式与相关信息等;
- inode:记录文件的权限与属性,一个文件占用一个inode,同时记录此文件的数据所在的 block 号码;
- block:实际记录文件的内容,若文件太大时,会占用多个 block .
每个 inode 与 block 都有编号,而每个文件都会占用一个 inode ,inode 内则有文件数据放置的 block 号码.所以如果能够找到文件的 inode 的话,那么自然就会知道这个文件所放置数据的 block 号码, 当然也就能够读出该文件的实际数据了.
data block (数据区块)
block 基本限制:
- 原则上,block 的大小与数量在格式化完就不能够再改变了(除非重新格式化)
- 每个 block 内最多只能够放置一个文件的数据
- 若文件大于 block 的大小,则一个文件会占用多个 block 数量
- 若文件小于 block ,则该 block 的剩余容量就不能够再被使用了(磁盘空间会浪费)
- 在 Ext2 文件系统中所支持的 block 大小有 1K, 2K 及 4K 三种而已
Block 大小 | 1KB | 2KB | 4KB |
最大单一文件限制 | 16GB | 256GB | 2TB |
最大文件系统总容量 | 2TB | 8TB | 16TB |
inode table (inode 表格)
inode 数据内容:
- 该文件的存取模式(read/write/excute)
- 该文件的拥有者与群组(owner/group)
- 该文件的容量
- 该文件创建或状态改变的时间(ctime)
- 最近一次的读取时间(atime)
- 最近修改的时间(mtime)
- 定义文件特性的旗标(flag),如 SetUID...
- 该文件真正内容的指向 (pointer)
inode 的特色点:
- 每个 inode 大小均固定为 128 bytes
- 每个文件都仅会占用一个 inode 而已
- 承上,因此文件系统能够创建的文件数量与 inode 的数量有关
- 系统读取文件时需要先找到 inode,并分析 inode 所记录的权限与用户是否符合,若符合才能够开始实际读取 block 的内容
系统将 inode 记录 block 号码的区域定义为12个直接,一个间接, 一个双间接与一个三间接记录区,如下图所示:
- 12 个直接指向: 12*1K=12K
- 间接: 256*1K=256K
- 双间接: 256*256*1K=2562K=64M
- 三间接: 256*256*256*1K=16777216K=16384M=16G
Superblock (超级区块)
Superblock 是记录整个 filesystem 相关信息的地方, 没有 Superblock ,就没有这个 filesystem 了.
记录的信息主要有:
- block 与 inode 的总量
- 未使用与已使用的 inode / block 数量
- block 与 inode 的大小 (block 为 1, 2, 4K,inode 为 128 bytes)
- filesystem 的挂载时间、最近一次写入数据的时间、最近一次检验磁盘 (fsck) 的时间等文件系统的相关信息
- 一个 valid bit 数值,若此文件系统已被挂载,则 valid bit 为 0 ,若未被挂载,则 valid bit 为 1
block bitmap (区块对照表)
block bitmap 记录使用与未使用的 block 号码,并在进行文件添加修改时候对应的修改 block 的使用状况
inode bitmap (inode 对照表)
inode bitmap 记录使用与未使用的 inode 号码,并在进行文件添加修改时候对应的修改 inode 的使用状况
boot sector 与 superblock 的关系
block 为 1024 bytes (1K) 时:
如果 block 大小刚好是 1024 的话,那么 boot sector 与 superblock 各会占用掉一个 block , 所以整个文件系统图示就会如同图 1.3.1 所显示的那样,boot sector 是独立于 superblock 外面的!
如果 block 大于 1024 的话:
那么 superblock 将会在 0 号,在第一个 block 内 superblock 仅占有 1024-2047 ( 由 0 号起算的话)之间的咚咚,至于 2048bytes 以后的空间就真的是保留啦!而 0-1023 就保留给 boot sector 来使用
索引式文件系统(indexed allocation)
在索引式文件系统(indexed allocation)中将 inode 与 block 区块用图解来说明一下,如下图所示,文件系统先格式化出 inode 与 block 的区块,假设某一个文件的属性与权限数据是放置到 inode 4 号(下图较小方格内),而 这个 inode 记录了文件数据的实际放置点为 2, 7, 13, 15 这四个 block 号码,此时我们的操作系统就能够据此来排列磁盘的阅读顺序,可以一口气将四个 block 内容读出来! 那么数据的读取就如同下图中的箭头所指定的模样了.
FAT 格式
闪盘使用的文件系统一般为 FAT 格式.FAT 这种格式的文件系统并没有 inode 存在,所以 FAT 没有办法将这个文件的所有 block 在一开始就读取出来.每个 block 号码都记录在前一个
block 当中, 他的读取方式有点像底下这样:
上图中我们假设文件的数据依序写入1->7->4->15号这四个 block 号码中, 但这个文件系统没有办法一口气就知道四个 block 的号码,他得要一个一个的将 block 读出后,才会知道下一个
block 在何处. 如果同一个文件数据写入的 block 分散的太过厉害时,则我们的磁盘读取头将无法在磁盘转一圈就读到所有的数据, 因此磁盘就会多转好几圈才能完整的读取到这个文件的
内容!此时文件读取的效能将会变的很差所致. 这个时候可以透过碎片整理将同一个文件所属的 blocks 汇整在一起.
Ext2 文件系统
件系统一开始就将 inode 与 block 规划好了,除非重新格式化(或者利用 resize2fs 等命令变更文件系统大小),否则 inode 与 block 固定后就不再变动
Ext2 文件系统在格式化的时候基本上是区分为多个区块群组 (block group) 的,每个区块群组都有独立的 inode/block/superblock 系统,整个来说,Ext2 格式化后有点像底下这样:
文件系统最前面有一个启动扇区(boot sector),这个启动扇区可以安装启动管理程序,如此一来我们就能够将不同的启动管理程序安装到个别的文件系统最前端,而不用覆盖整颗硬盘唯一的
MBR, 这样也才能够制作出多重引导的环境!
目录
在 Linux 下的 ext2 文件系统创建一个目录时, ext2 会分配一个 inode 与至少一块 block 给该目录.
inode 记录该目录的相关权限与属性,并可记录分配到的那块 block 号码
block 则是记录在这个目录下的文件名与该文件名占用的 inode 号码数据.如下图所示:
文件
在 Linux 下的 ext2 创建一个一般文件时, ext2 会分配一个 inode 与相对于该文件大小的 block 数量给该文件
目录树读取
由于目录树是由根目录开始读起,因此系统透过挂载的信息可以找到挂载点的 inode 号码(通常一个 filesystem 的最顶层 inode 号码会由 2 号开始喔!),此时就能够得到根目录的 inode 内容,并依据该 inode 读取根目录的 block 内的文件名数据,再一层一层的往下读到正确的档名.举例来说,如果我想要读取 /etc/passwd 这个文件时,系统是如何读取的呢?
[root@www ~]# ll -di / /etc /etc/passwd 2 drwxr-xr-x 23 root root 4096 Sep 22 12:09 / 1912545 drwxr-xr-x 105 root root 12288 Oct 14 04:02 /etc 1914888 -rw-r--r-- 1 root root 1945 Sep 29 02:21 /etc/passwd
在鸟哥的系统上面与 /etc/passwd 有关的目录与文件数据如上表所示,该文件的读取流程为(假设读取者身份为 vbird 这个一般身份使用者):
- / 的 inode:
透过挂载点的信息找到 /dev/hdc2 的 inode 号码为 2 的根目录 inode,且 inode 规范的权限让我们可以读取该 block 的内容(有 r 与 x) ; - / 的 block:
经过上个步骤取得 block 的号码,并找到该内容有 etc/ 目录的 inode 号码 (1912545); - etc/ 的 inode:
读取 1912545 号 inode 得知 vbird 具有 r 与 x 的权限,因此可以读取 etc/ 的 block 内容; - etc/ 的 block:
经过上个步骤取得 block 号码,并找到该内容有 passwd 文件的 inode 号码 (1914888); - passwd 的 inode:
>读取 1914888 号 inode 得知 vbird 具有 r 的权限,因此可以读取 passwd 的 block 内容; - passwd 的 block:
最后将该 block 内容的数据读出来.