文件系统特性
文件系统通常会将这两部份的数据分别存放在不同的区块,权限与属性放置到 inode 中,至于实际数据则放置到 data block 区块中。 另外,还有一个超级区块 (superblock) 会记录整个文件系统的整体信息,包括 inode 与 block 的总量、使用量、剩余量等。
每个 inode 与 block 都有编号,至于这三个数据的意义可以简略说明如下:
- superblock:记录此 filesystem 的整体信息,包括inode/block的总量、使用量、剩余量, 以及文件系统的格式与相关信息等;
- inode:记录文件的属性,一个文件占用一个inode,同时记录此文件的数据所在的 block 号码;
- block:实际记录文件的内容,若文件太大时,会占用多个 block 。
由于每个 inode 与 block 都有编号,而每个文件都会占用一个 inode ,inode 内则有文件数据放置的 block 号码。 找到文件的 inode 的话,就会知道这个文件所放置数据的 block 号码, 就能够读出该文件的实际数据了。这种数据存取的方法我们称为索引式文件系统(indexed allocation)。如下图所示:
[图片上传中...(image-2f8871-1600850655336-5)]
inode/block 数据存取示意图
还有一种链式存储结构,FAT 这种格式的文件系统并没有 inode 存在,所以 FAT 没有办法将这个文件的所有 block 在一开始就读取出来。每个 block 号码都记录在前一个 block 当中, 他的读取方式有点像底下这样:
[图片上传中...(image-66ced4-1600850655336-4)]
FAT文件系统数据存取示意图
Linux 的 EXT2 文件系统(inode):
Linux 文件系统 Ext2 就是使用 inode 为基础的文件系统啦!
Ext2 文件系统在格式化的时候基本上是区分为多个区块群组 (block group) 的,每个区块群组都有独立的 inode/block/superblock 系统。Ext2 格式化后有点像底下这样:
[图片上传失败...(image-fe6002-1600850655336)]
在整体的规划当中,文件系统最前面有一个启动扇区(boot sector),这个启动扇区可以安装启动管理程序, 这是个非常重要的设计,因为如此一来我们就能够将不同的启动管理程序安装到个别的文件系统最前端,而不用覆盖整颗硬盘唯一的 MBR, 这样也才能够制作出多重引导的环境啊!
- data block (数据区块)
data block 是用来放置文件内容数据地方,在 Ext2 文件系统中所支持的 block 大小有 1K, 2K 及 4K 三种而已。在格式化时 block 的大小就固定了,且每个 block 都有编号,以方便 inode 的记录啦。 不过要注意的是,由于 block 大小的差异,会导致该文件系统能够支持的最大磁盘容量与最大单一文件容量并不相同。 因为 block 大小而产生的 Ext2 文件系统限制如下:
Block 大小 | 1KB | 2KB | 4KB |
---|---|---|---|
最大单一文件限制 | 16GB | 256GB | 2TB |
最大文件系统总容量 | 2TB | 8TB | 16TB |
除此之外 Ext2 文件系统的 block 还有限制如下:
- 原则上,block 的大小与数量在格式化完就不能够再改变了(除非重新格式化);
- 每个 block 内最多只能够放置一个文件的数据;
- 承上,如果文件大于 block 的大小,则一个文件会占用多个 block 数量;
- 承上,若文件小于 block ,则该 block 的剩余容量就不能够再被使用了(磁盘空间会浪费)。
- inode table (inode 表格)
inode 记录的文件数据至少有底下这些:
- 该文件的存取模式(read/write/excute);
- 该文件的拥有者与群组(owner/group);
- 该文件的容量;
- 该文件创建或状态改变的时间(ctime);
- 最近一次的读取时间(atime);
- 最近修改的时间(mtime);
- 定义文件特性的旗标(flag),如 SetUID...;
- 该文件真正内容的指向 (pointer);
inode 的数量与大小也是在格式化时就已经固定了,除此之外 inode 还有如下特点:
- 每个 inode 大小均固定为 128 bytes;
- 每个文件都仅会占用一个 inode 而已;
- 承上,因此文件系统能够创建的文件数量与 inode 的数量有关;
- 系统读取文件时需要先找到 inode,并分析 inode 所记录的权限与用户是否符合,若符合才能够开始实际读取 block 的内容。
我们约略来分析一下 inode / block 与文件大小的关系好了。inode 要记录的数据非常多,但偏偏又只有 128bytes 而已, 而 inode 记录一个 block 号码要花掉 4byte ,假设我一个文件有 400MB 且每个 block 为 4K 时, 那么至少也要十万笔 block 号码的记录呢!inode 哪有这么多可记录的信息?为此我们的系统很聪明的将 inode 记录 block 号码的区域定义为12个直接,一个间接, 一个双间接与一个三间接记录区。这是啥?我们将 inode 的结构画一下好了。
[图片上传失败...(image-e5def4-1600850655335)]
这样子 inode 能够指定多少个 block 呢?我们以较小的 1K block 来说明好了,可以指定的情况如下:
-
12 个直接指向: 12*1K=12K
由于是直接指向,所以总共可记录 12 笔记录,因此总额大小为如上所示; -
间接: 256*1K=256K
每笔 block 号码的记录会花去 4bytes,因此 1K 的大小能够记录 256 笔记录,因此一个间接可以记录的文件大小如上; -
双间接: 2562561K=2562K
第一层 block 会指定 256 个第二层,每个第二层可以指定 256 个号码,因此总额大小如上; -
三间接: 256256256*1K=2563K
第一层 block 会指定 256 个第二层,每个第二层可以指定 256 个第三层,每个第三层可以指定 256 个号码,因此总额大小如上; -
总额:将直接、间接、双间接、三间接加总,得到 12 + 256 + 256256 + 256256*256 (K) = 16GB
- 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 。
Superblock 是非常重要的,因为我们这个文件系统的基本信息都写在这里,因此,如果 superblock 死掉了, 你的文件系统可能就需要花费很多时间去挽救啦!一般来说, superblock 的大小为 1024bytes。 事实上除了第一个 block group 内会含有 superblock 之外,后续的 block group 不一定含有 superblock , 而若含有 superblock 则该 superblock 主要是做为第一个 block group 内 superblock 的备份,这样可以进行 superblock 的救援呢!
- Filesystem Description (文件系统描述说明)
这个区段可以描述每个 block group 的开始与结束的 block 号码,以及说明每个区段 (superblock, bitmap, inodemap, data block) 分别介于哪一个 block 号码之间。这部份也能够用来观察的。
- block bitmap (区块对照表)
从 block bitmap 当中可以知道哪些 block 是空的,因此我们的系统就能够很快速的找到可使用的空间来处置文件啰。同样的,删除文件时,那么那些文件原本占用的 block 号码就得要释放出来。
- inode bitmap (inode 对照表)
这个其实与 block bitmap 是类似的功能。
- 目录
在 Linux 下的 ext2 文件系统中,目录的 block 则是记录在这个目录下的文件名与该文件名占用的 inode 号码数据。也就是说目录所占用的 block 内容在记录如下的信息:
[图片上传中...(image-7ed6fa-1600850655335-1)]
目录占用的 block 记录的数据示意图
下面展示 /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 内容的数据读出来。
- 挂载点的意义 (mount point):
每个 filesystem 都有独立的 inode / block / superblock 等信息,这个文件系统要能够链接到目录树才能被我们使用。 将文件系统与目录树结合的动作我们称为挂载。 挂载点一定是目录,该目录为进入该文件系统的入口。 因此并不是你有任何文件系统都能使用,必须要挂载到目录树的某个目录后,才能够使用该文件系统的。
其他 Linux 支持的文件系统与 VFS
虽然 Linux 的标准文件系统是 ext2 ,且还有添加了日志功能的 ext3 ,事实上,Linux 还有支持很多文件系统格式的, 尤其是最近这几年推出了好几种速度很快的日志式文件系统,包括 SGI 的 XFS 文件系统, 可以适用更小型文件的 Reiserfs 文件系统,以及 Windows 的 FAT 文件系统等等, 都能够被 Linux 所支持喔!常见的支持文件系统有:
- 传统文件系统:ext2 / minix / MS-DOS / FAT (用 vfat 模块) / iso9660 (光盘)等等;
- 日志式文件系统: ext3 / ReiserFS / Windows' NTFS / IBM's JFS / SGI's XFS
- 网络文件系统: NFS / SMBFS
了解了我们使用的文件系统之后,再来则是要提到,那么 Linux 的核心又是如何管理这些认识的文件系统呢? 其实,整个 Linux 的系统都是透过一个名为 Virtual Filesystem Switch 的核心功能去读取 filesystem 的。 也就是说,整个 Linux 认识的 filesystem 其实都是 VFS 在进行管理,我们使用者并不需要知道每个 分区上的 filesystem 是什么~ VFS 会主动的帮我们做好读取的动作呢~
假设你的 / 使用的是 /dev/hda1 ,用 ext3 ,而 /home 使用 /dev/hda2 ,用 reiserfs , 那么你取用 /home/dmtsai/.bashrc 时,有特别指定要用的什么文件系统的模块来读取吗? 应该是没有吧!这个就是 VFS 的功能啦!透过这个 VFS 的功能来管理所有的 filesystem, 省去我们需要自行配置读取文件系统的定义啊~方便很多!整个 VFS 可以约略用下图来说明:
image实体链接与符号链接: ln
在 Linux 底下的连结档有两种,一种是类似 Windows 的快捷方式功能的文件,可以让你快速的链接到目标文件(或目录); 另一种则是透过文件系统的 inode 连结来产生新文件名,而不是产生新文件!这种称为实体链接 (hard link)。
Hard Link (实体链接, 硬式连结或实际连结)
文件名只与目录有关,但是文件内容则与 inode 有关。而hard link 只是在某个目录下新增一个文件名链接到某 inode 号码的关连记录而已。
hard link 有如下限制:
- 不能跨 Filesystem;
- 不能 link 目录。
Symbolic Link (符号链接,亦即是快捷方式)
Symbolic link 就是在创建一个独立的文件,会创建inode和block,而这个文件会让数据的读取指向他 连接的文件的inode。由于只是利用文件来做为指向的动作, 所以,当源文件被删除之后,symbolic link 的文件会开不了。
网友评论