Linux的文件组织结构
文件系统

虽然 EXT 文件系统是为 Linux 编写的,但其真正起源于 Minix 操作系统和 Minix 文件系统,而 Minix 最早发布于 1987,早于 Linux 5 年。如果我们从 EXT 文件系统大家族的 Minix 起源来观察其历史与技术发展那么理解 EXT4 文件系统就会简单得多。

Minix
当 Linux Torvalds 在写最初的 Linux 内核的时候,他需要一个文件系统但是他又不想自己写一个。于是他简单地把 Minix 文件系统 加了进去,这个 Minix 文件系统是由 Andrew S. Tanenbaum 写的,同时它也是 Tanenbaum 的 Minix 操作系统的一部分。Minix 是一个类 Unix 风格的操作系统,最初编写它的原因是用于教育用途。Minix 的代码是自由可用的并有适当的许可协议,所以 Torvalds 可以把它用 Linux 的最初版本里。

Minix 有以下这些结构,其中的大部分位于生成文件系统的分区中:
引导扇区 是硬盘安装后的第一个扇区。这个引导块包含了一个非常小的引导记录和一个分区表。
每一个分区的第一个块都是一个包含了元数据的超级块superblock ,这些元数据定义了其他的文件系统结构并将其定位于物理硬盘的具体分区上。
一个 inode 位图块 决定了哪些 inode 是在使用中的,哪一些是未使用的。
inode 在硬盘上有它们自己的空间。每一个 inode 都包含了一个文件的信息,包括其所处的数据块的位置,也就是该文件所处的区域。
一个 区位图 用于保持追踪数据区域的使用和未使用情况。
一个 数据区, 这里是数据存储的地方。
对上述了两种位图类型来说,一个位bit表示一个指定的数据区或者一个指定的 inode。 如果这个位是 0 则表示这个数据区或者这个 inode 是未使用的,如果是 1 则表示正在使用中。

那么,inode 又是什么呢 ? 就是 index-node(索引节点)的简写。 inode 是位于磁盘上的一个 256 字节的块,用于存储和该 inode 对应的文件的相关数据。这些数据包含了文件的大小、文件的所有者和所属组的用户 ID、文件模式(即访问权限)以及三个时间戳用于指定:该文件最后的访问时间、该文件的最后修改时间和该 inode 中的数据的最后修改时间。

同时,这个 inode 还包含了位置数据,指向了其所对应的文件数据在硬盘中的位置。在 Minix 和 EXT 1-3 文件系统中,这是一个数据区和块的列表。Minix 文件系统的 inode 支持 9 个数据块,包括 7 个直接数据块和 2 个间接数据块。如果你想要更深入的了解,这里有一个优秀的 PDF 详细地描述了 Minix 文件系统结构 。同时你也可以在维基百科上对 inode 指针结构 做一个快速了解。

EXT
原生的 EXT 文件系统 (意即扩展的extended) 是由 Rémy Card 编写并于 1992 年与 Linux 一同发行。主要是为了克服 Minix 文件系统中的一些文件大小限制的问题。其中,最主要的结构变化就是文件系统中的元数据。它基于 Unix 文件系统 (UFS),其也被称为伯克利快速文件系统(FFS)。我发现只有很少一部分关于 EXT 文件系统的发行信息是可以被确证的,显然这是因为其存在着严重的问题,并且它很快地被 EXT2 文件系统取代了。

EXT2
EXT2 文件系统 就相当地成功,它在 Linux 发行版中存活了多年。它是我在 1997 年开始使用 Red Hat Linux 5.0 时接触的第一个文件系统。实际上,EXT2 文件系统有着和 EXT 文件系统基本相同的元数据结构。然而 EXT2 更高瞻远瞩,因为其元数据结构之间留有很多供将来使用的磁盘空间。

和 Minix 类似,EXT2 也有一个引导扇区 ,它是硬盘安装后的第一个扇区。它包含了非常小的引导记录和一个分区表。接着引导扇区之后是一些保留的空间,它填充了引导记录和硬盘驱动器上的第一个分区(通常位于下一个柱面)之间的空间。GRUB2 - 也可能是 GRUB1 - 将此空间用于其部分引导代码。

每个 EXT2 分区中的空间被分为柱面组cylinder group,它允许更精细地管理数据空间。 根据我的经验,每一组大小通常约为 8MB。 下面的图 1 显示了一个柱面组的基本结构。 柱面中的数据分配单元是块,通常大小为 4K。

柱面组中的第一个块是一个超级块superblock,它包含了元数据,定义了其它文件系统的结构并将其定位于物理硬盘的具体分区上。分区中有一些柱面组还会有备用超级块,但并不是所有的柱面组都有。我们可以使用例如 dd 等磁盘工具来拷贝备用超级块的内容到主超级块上,以达到修复损坏的超级块的目的。虽然这种情况不会经常发生,但是在几年前我的一个超级块损坏了,我就是用这种方法来修复的。幸好,我很有先见之明地使用了 dumpe2fs 命令来备份了我的系统上的分区描述符信息。

EXT3
EXT3 文件系统是应一个目标而生的,就是克服 fsck 程序需要完全恢复在文件更新操作期间发生的不正确关机而损坏的磁盘结构所需的大量时间。它对 EXT 文件系统的唯一新增功能就是 日志,它将提前记录将对文件系统执行的更改。 EXT3 的磁盘结构的其余部分与 EXT2 中的相同。

除了同先前的版本一样直接写入数据到磁盘的数据区域外,EXT3 上的日志会将文件数据随同元数据写入到磁盘上的一个指定数据区域。一旦这些(日志)数据安全地到达硬盘,它就可以几乎零丢失率地被合并或被追加到目标文件上。当这些数据被提交到磁盘上的数据区域上,这些日志就会随即更新,这样在日志中的所有数据提交之前,系统发生故障时文件系统将保持一致状态。在下次启动时,将检查文件系统的不一致性,然后将仍保留在日志中的数据提交到磁盘的数据区,以完成对目标文件的更新。

日志功能确实降低了数据写入性能,但是有三个可用于日志的选项,允许用户在性能和数据完整性、安全性之间进行选择。 我的个人更偏向于选择安全性,因为我的环境不需要大量的磁盘写入活动。

日志功能将失败后检查硬盘驱动器所需的时间从几小时(甚至几天)减少到了几分钟。 多年来,我遇到了很多导致我的系统崩溃的问题。要详细说的话恐怕还得再写一篇文章,但这里需要说明的是大多数是我自己造成的,就比如不小心踢掉电源插头。 幸运的是,EXT 日志文件系统将启动恢复时间缩短到两三分钟。此外,自从我开始使用带日志记录的 EXT3,我从来没有遇到丢失数据的问题。

EXT3 的日志功能可以关闭,然后其功能就等同于 EXT2 文件系统了。 该日志本身仍然是存在的,只是状态为空且未使用。 只需在 mount 命令中使用文件系统类型参数来重新挂载即可指定为 EXT2。 你可以从命令行执行此操作,但是具体还是取决于你正在使用的文件系统,不过你也可以更改 /etc/fstab 文件中的类型说明符,然后重新启动。 我强烈建议不要将 EXT3 文件系统挂载为 EXT2 ,因为这会有丢失数据和增加恢复时间的潜在可能性。

EXT4
EXT4 文件系统主要提高了性能、可靠性和容量。为了提高可靠性,它新增了元数据和日志校验和。同时为了满足各种关键任务要求,文件系统新增了纳秒级别的时间戳,并在时间戳字段中添加了两个高位来延缓时间戳的 2038 年问题 ,这样 EXT4 文件系统至少可用到 2446 年。

在 EXT4 中,数据分配从固定块改为扩展盘区extent方式,扩展盘区由硬盘驱动器上的开始和结束位置来描述。这使得可以在单个 inode 指针条目中描述非常长的物理上连续的文件,这可以显著减少描述大文件中所有数据的位置所需的指针数。其它在 EXT4 中已经实施的分配策略可以进一步减少碎片化。

EXT4 通过将新创建的文件散布在磁盘上,使其不会像早期的 PC 文件系统一样全部聚集在磁盘起始位置,从而减少了碎片。文件分配算法尝试在柱面组中尽可能均匀地散布文件,并且当文件(由于太大)需要分段存储时,使不连续的文件扩展盘区尽可能靠近同一文件中的其他部分,以尽可能减少磁头寻道和电机旋转等待时间。当创建新文件或扩展现有文件时,使用其它策略来预先分配额外的磁盘空间。这有助于确保扩展文件时不会自动导致其分段。新文件不会紧挨这现有文件立即分配空间,这也可以防止现有文件的碎片化。

除了磁盘上数据的实际位置外,EXT4 使用诸如延迟分配的功能策略,以允许文件系统在分配空间之前收集到所有正在写入磁盘的数据,这可以提高数据空间连续的可能性。

较旧的 EXT 文件系统(如 EXT2 和 EXT3)可以作为 EXT4 进行 mount ,以使其性能获得较小的提升。但不幸的是,这需要关闭 EXT4 的一些重要的新功能,所以我建议不要这样做。

自 Fedora 14 以来,EXT4 一直是 Fedora 的默认文件系统。我们可以使用 Fedora 文档中描述的 流程 将 EXT3 文件系统升级到 EXT4,但是由于仍然存留的之前的 EXT3 元数据结构,它的性能仍将受到影响。从 EXT3 升级到 EXT4 的最佳方法是备份目标文件系统分区上的所有数据,使用 mkfs 命令将空 EXT4 文件系统写入分区,然后从备份中恢复所有数据。

EXT 文件系统在一些 Linux 发行版本上作为默认文件系统已经超过二十多年了。它们用最少的维护代价提供了稳定性、高可用性、可靠性和性能。我尝试过一些其它的文件系统但最终都还是回归到 EXT。每一个我在工作中使用到 Linux 的地方都使用到了 EXT 文件系统,同时我发现了它们适用于任何主流负载。毫无疑问,EXT4 文件系统应该被用于大部分的 Linux 文件系统上,除非我们有明显需要使用其它文件系统的理由。

FHS

因为利用linux来开发产品者发行版的社区,公司及个人实在太多了,如果每人个都用自己的想法来配置文件放置的目录,那么将可能靠这成很多管理上的困扰。你能想月象,当你使用每一个发行版时,linux目录配置跟你以前用的发行版完全不一样.那怎么办呢,于是有了Filesystem Hierarche Standard标准,简称FHS。

文件种类

linux文件种类很多,不同类型的文件专属于不同的功能。

常归文件 regular file
纯文本文件
二进制文件
数据文件
目录
连接文件
设备与设备文件
数据库接口文件
数据输送文件

文件属性

在LINUX系统下,当你执行ls -al 时会显示:
linux
ls是LIST的意思
-a 显示所有文件,即包括隐藏文件
-l 以每行显示文件
更多参数可以查看man手册。

drwxr-xr-x. 13 root root 4096 Oct 15 2017 usr

第一个字符代表这个文件是目录,文件或链接文件等。
d 目录
- 文件
l 链接文件 link file
b 设备文件里面的可供存储的周边设备(可按块随机读写的设备)
c 设备文件里面的串行端口设备,例如健盘,鼠标(一次性读取设备)

第一个字符的后9个字符,以三个为一组,且均为rwx的三个参数的组合。其中r代表可读(read),
w代表可写(write),x代表可执行(execute).这三个权限的位置不会改变,如果没有权限,就会出现减号 “-“ 。
第一组为文件拥有者可具备的权限。
第二组为加入此用户组之帐号的权限。
第三组为非本人且没有加入本用户组的其它帐号的权限。

第二栏表示有多少文件名链接到此节点(inode),每个文件都会将它的权限与属性记录到文件系统的inode中,这个属性记录的就是有多少不同的文件名链接到相同的inode号码。

第三栏表示此文件或目录的拥有者帐号。

第四栏表示这个文个文件的所属用户组。

第五栏为这个文件的容量大小,默认单位为Btypes, 你可以换算成M G 等。

第六栏为这个文件的创建日期或最近的修改日期。
这栏的内容分别为日期(月/日)和时间,如果这个文件被修改的时间距离现在太久,那么时间部分会仅显示年份。
如果要显示完整的时间格式,可以利用ls选项 ls -l —full-time 就能显示完整的时间格式,包括年月日时间。另外如果你当初以简体中文安装你的linux系统,那么日期字段将会以中文来显示。可惜中文并没有办法在纯命令行的终端模式中正确地显示,所以此栏会变成乱码。那你就得要使用export LC_ALL=en_US.utf8来修改语系。
如果想要让系统默认的语系变成英文的话,那么你可以修改系统配置文件/etc/locale.conf。

第7栏为这个文件名。
比较特殊

目录权限

我们知道linux操作系统有三种身份(所有者,用户组,其它人),每种身份都有三种权限(rwx),可以用chown,chgrp,chmod修改这些权限与属性。

文件是存放数据的一串字符,包括但不限于文本文件,数据库文件,二进制可执行文件biniary program等。每个文件包括三种属性,分别是:
r - read 可读取皮文件的实际内容。
w - write 可以编辑,新增或修改文件的内容,但是不可以删除。
x - execute 如果是文件,该文件具有可以被系统执行的权限。如果是目录表示可以进入目录,读取目录内文件列表。

目录组权限

修改文件的属性与权限主要有三个命令:
chgrp 修改文件所属用户组
chown 修改文件拥有者
chmod 修改文件的权限, SUID, SGID, SBIT等特性。