为了更好地理解Ext文件系统下称文件系统需要先了解一下外存的知识主要是了解其中的基本存储单元的概念下面以机械硬盘为例。机械硬盘数据存储原理机械硬盘造价低容量大但是读写速度慢一般用于服务器的数据存储。在机械硬盘中存储数据的原理就是改变磁盘上磁性颗粒非常小的N极、S极要么改成N极要么改成S极。一旦遇到高温这些磁性颗粒就会失去磁性彻底丢失数据。大致结构先看图中下半部分的侧视图一个机械硬盘上有多个磁盘每个磁盘都有正反两面。再看上半部分的俯视图一个盘面被分为多个磁道一个同心圆就是一个磁道。磁道又被分为多个扇区扇区之间有间隙。扇区是机械硬盘的基本存储单元也就是说机械硬盘读写数据时是以扇区为单位的一个扇区能存储512个字节每次就是读写512字节。如果要修改其中的一部分数据必须将该扇区的数据全部加载到内存中修改完成后再写回。每个盘面都有各自的磁头(图中的读写头)磁头就是用来读写数据的通过传动臂移动磁头就能读写不同磁道上的数据。虽然磁头很多但是它们无法分开单独行动只能跟着传动臂一起移动并且同一时间只能有一个磁头在读写数据。数据读写原理在机械硬盘运行时马达会通过主轴带动所有磁盘高速旋转而所有的磁头都在同一竖直线上一个磁头可以读写一个扇区通过磁盘的旋转整个结构的操作范围就从多个扇区变成多条在不同盘面上的相同大小的磁道可以看成一个柱面。当然每次依旧只有一个磁头在读写一次也只能读取或写入一个扇区只是说可以通过磁盘的旋转和磁头的切换快速地在柱面的范围中读写。当需要进行大量数据的写入时机械硬盘会先通过一个磁头向柱面的一个磁道写入数据完成后再切换到另一个磁头向柱面的另一个磁道写入整体上看就是在对柱面写入数据这样一来不需要移动传动臂就能快速地写入大量的数据移动传动臂的速度远不如马达带动磁盘旋转的速度。整个柱面都写满后再通过传动臂移动磁头读写其它柱面。读取数据时则需要确定数据所在的柱面接着是需要使用哪一个磁头柱面上一个磁头对应一个磁道最后确定在哪一个扇区。这种查找方式叫做CHS定址。虽然机械硬盘是通过这种方式进行定位的但操作系统只需将其看做线性的存储结构其它外存硬件也是如此硬件内部会给所有的基本存储单元编号。比如机械硬盘就是给扇区编号这样每个扇区就有了一个线性地址LBA其本质就是数组下标。要访问扇区时机械硬盘会通过硬件电路将接收到的LBA转化为CHS参数进行访问。这样操作系统只需将外存视为一个数组通过管理数组就能管理外存。事实上机械硬盘内部也是以数组的形式访问基本存储单元扇区的不过这个数组是三维的。我们知道CHS定址就是通过柱面、磁头和扇区进行定位。从总的角度看机械硬盘是一个柱面一个柱面地写入进一步就是在柱面内依次对各个磁道进行写入再进一步就是在磁道上依次向各个扇区写入。我们很容易就能明白三维数组中各维的含义假设该数组是chs[ i ][ j ][ k ]那么 i 就对应柱面 j 对应磁头也就是柱面上的磁道k对应磁道上的各个扇区。根据读写方式确定好LBA的编号规则用简单的公式就能使LBA与这个三维数组的三个下标相互转化感兴趣的可以自行了解。“块”概念其实机械硬盘是典型的“块”设备。操作系统要从中读取数据到内存中时为了提高效率会规定若干个基本存储单元为读取的基本单位每次读取时都是这个基本单位的整数倍这个基本单位就是块。块的大小可以更改但不能随意更改因为每次更改都要格式化硬盘。块的大小一般是4KB在机械硬盘中就是8个扇区所以硬盘中每8个扇区会被操作系统视为一个块并且操作系统还会对每个块进行编号用块号进行访问访问时将块号乘以8就得到了块的起始LBA。即使将整个磁盘按块划分块的数量还是太多了。为了方便管理在块之上还有分区的概念一般我们电脑中默认的C盘、D盘就是两个分区。而在Linux操作系统中分组与块之间还有划分了一层名为块组块组就是由多个块构成。文件系统基本概念文件系统是操作系统的一个子系统它由两部分组成一是文件系统驱动本质就是一种程序随着操作系统的启动从磁盘加载到内存中对文件的读写操作就是由它处理可以看成操作系统的一部分二是磁盘中的数据组织结构也就是存储文件的结构如果没有特殊说明的话我们后面说的文件系统就是特指这个结构它的载体是分区如下图图中的Partition就是分区的意思。每个分区有自己的文件系统这些文件系统相互独立也就是独自管理自己的分区不会相互干涉。管理结构分区由块组Block Group构成块组中又分为不同的区域分别存储不同的数据这些区域自然是由整数个块构成。Linux下文件的内容和属性是分开存储的文件的属性存储在inode中inode是一个结构体存储在inode Table中文件内容则存储在Data Blocks中。位图Block Bitmap和inode Bitmap中分别记录了数据块Data Blocks内的各个块和inode Table内的各个inode有没有被使用值为0表示未使用为1则相反。我们删除文件的本质就是将这两个位图中对应的部分改成0文件的数据依旧在原处。直到写入新文件时操作系统通过位图发现对应的区域没有被使用新文件会直接覆盖该区域这时旧文件的数据才会彻底消失。所以即使将文件删除也是有恢复的可能的。inode大小是固定的128字节而文件名的大小不能确定因此并不在inode中。要注意这里是磁盘不是内存没有用malloc开辟空间的概念。文件系统是通过inode中的编号inode_number对文件进行区分的。使用指令 ls 或 ll 时带上-i选项就能看到文件的inode编号。下图输出结果中的第一列就是inode编号。通过inode编号只能在一个分区内查找文件不能跨分区毕竟每个分区的文件系统是相互独立的不过可以跨组也就是inode与文件内容存储在同一个分区下的不同的块组中因为inode编号在一个分区的文件系统内是唯一的。至于查找文件时怎么确认在哪个分区等下会提到。GDT是块组描述符表里面的一个块组描述符对应所属分区内的一个块组。块组描述符中记录了对应块组的信息如inode Bitmap的起始位置、Data Blocks的起始位置、空闲的inode和数据块个数等。Super Block中存储的也是关于整个分区的信息其中就有各个块组中inode和数据块的使用数量和空闲数量。操作系统运行时会将所有分区的Super Block加载到内存中用链表管理起来通过这个链表就能管理所有的分区。需要说明的是虽然一个分区只需要一个Super Block和GDT但是它们中的数据是使用整个分区的关键为了防止磁盘存储它们的位置发生故障而导致整个分区无法使用文件系统会在许多块组中存储Super Block和GDT的备份。当我们格式化整个分区的时候除了将所有块组的两个位图全部置0还要修改所有的备份中的数据。格式化的真正意义在于修改分区内文件系统的管理信息使分区中存储的数据可以被覆盖或是在分区中建立文件系统使分区可以正常使用。文件访问原理路径访问目录本身也是一种文件。在文件系统中目录的存储方式和文件是一样的包含inode文件属性和文件内容两部分比较特殊的是它的文件内容是该目录内文件的文件名与inode的映射关系。通过目录就能找到文件名对应的inode进而找到对应的文件。由此也可以看出文件名的存储方式比较特殊它存储在目录文件内。同时我们也能发现在我们看来处于同一目录下的文件实则分散在磁盘各处这就是不能直接发送目录或文件夹要先打包的原因。当我们要访问某一文件时就是通过根目录逐级向下查找这就是路径解析。而根目录就是默认打开的。但是如果为了查找一个文件就不停地将磁盘中的目录文件加载到内存的话效率会很低因此操作系统会用一颗多叉树记录所有访问过的目录的内容也就是文件名和inode的映射关系这颗多叉树就是目录树。其次bash中还记录了当前工作路径打开文件的操作或者包含了打开文件这个操作的操作本身也是一个进程如命令 ./[文件名] 和cat [文件名]等会继承bash中的当前工作路径进程将工作路径和我们输入的文件名提供给操作系统操作系统再通过目录树就能快速地访问对应的文件。目录树的节点同时还会连接在LRU结构中通过节点中的多个指针实现以便进行节点淘汰和快速访问具体细节不再展开。访问磁盘中的文件时都会先在目录树中查找如果没找到才会用路径解析在磁盘中查找。使用inode前需要确认其属于哪个分区那么操作系统是怎么知道它属于哪个分区的呢事实上每一个分区都与一个目录相关联进入这个目录就相当于进入这个分区。将分区与目录关联的操作叫做挂载对应的目录叫做挂载点。从Windows系统的角度可以更方便我们理解最简单的例子就是给我们的电脑插上一块U盘在电脑上确认后就可以发现在文件资源管理器中除了原有的C盘、D盘等还多了一块盘而我们访问这块盘的方式就是双击这块盘的图标打开对应的目录那么这个U盘就是挂载到这个目录了而这个目录就是挂载点。在Linux系统中也是类似的道理不过Linux系统将挂载点视为普通的目录文件Windows则将其视为特殊的“盘符”。链接访问Linux下存在两种链接文件一种是软链接另一种则是硬链接。软链接可以用命令ln -s [目标文件名] [链接文件名]创建。软链接文件是一个独立的文件在下图中可以看到它的inode编号与对应文件不同。在它里面保存了目标文件的路径我们可以通过软链接快速访问对应的文件相当于Windows下的快捷方式。使用时将软链接文件名看成目标文件的文件名即可如cat [链接文件名]。如果使用指令ln创建链接文件时不带选项-s那么创建的就是硬链接。硬链接不是独立的文件可以发现它的inode编号和目标文件是一样的。它的本质是一组新的文件名与inode的映射和C中的引用类似相当于给文件起了个别名。创建硬链接后目标文件的inode中的引用计数会增加也就是硬链接数会增加。上图输出结果的第三列就是文件的引用计数。目标文件原本的文件名和inode的映射也相当于一个硬链接只有将所有的硬链接全部删除文件才会真正被删掉。所以当我们需要防止文件被误删时不需要拷贝一份创建硬链接即可。此外我们可以发现新建的目录文件的引用计数是2这是因为目录中默认存在的文件.就是该目录的硬链接。相应地另一个默认存在的文件. .就是上一级目录的硬链接。但在Linux下我们是不能为目录建立硬链接的这是为了防止出现路径环导致一些功能出现错误。比如我们建立了一个根目录的硬链接再使用查找文件的功能从根目录开始查找文件当查找到我们建立的根目录的硬链接时会将其当成目录并进入这样就陷入了死循环。至于目录自带的 . 和 .. 以及目录的软连接自然是会被直接跳过。
(Linux)Ext文件系统
发布时间:2026/6/3 20:48:51
为了更好地理解Ext文件系统下称文件系统需要先了解一下外存的知识主要是了解其中的基本存储单元的概念下面以机械硬盘为例。机械硬盘数据存储原理机械硬盘造价低容量大但是读写速度慢一般用于服务器的数据存储。在机械硬盘中存储数据的原理就是改变磁盘上磁性颗粒非常小的N极、S极要么改成N极要么改成S极。一旦遇到高温这些磁性颗粒就会失去磁性彻底丢失数据。大致结构先看图中下半部分的侧视图一个机械硬盘上有多个磁盘每个磁盘都有正反两面。再看上半部分的俯视图一个盘面被分为多个磁道一个同心圆就是一个磁道。磁道又被分为多个扇区扇区之间有间隙。扇区是机械硬盘的基本存储单元也就是说机械硬盘读写数据时是以扇区为单位的一个扇区能存储512个字节每次就是读写512字节。如果要修改其中的一部分数据必须将该扇区的数据全部加载到内存中修改完成后再写回。每个盘面都有各自的磁头(图中的读写头)磁头就是用来读写数据的通过传动臂移动磁头就能读写不同磁道上的数据。虽然磁头很多但是它们无法分开单独行动只能跟着传动臂一起移动并且同一时间只能有一个磁头在读写数据。数据读写原理在机械硬盘运行时马达会通过主轴带动所有磁盘高速旋转而所有的磁头都在同一竖直线上一个磁头可以读写一个扇区通过磁盘的旋转整个结构的操作范围就从多个扇区变成多条在不同盘面上的相同大小的磁道可以看成一个柱面。当然每次依旧只有一个磁头在读写一次也只能读取或写入一个扇区只是说可以通过磁盘的旋转和磁头的切换快速地在柱面的范围中读写。当需要进行大量数据的写入时机械硬盘会先通过一个磁头向柱面的一个磁道写入数据完成后再切换到另一个磁头向柱面的另一个磁道写入整体上看就是在对柱面写入数据这样一来不需要移动传动臂就能快速地写入大量的数据移动传动臂的速度远不如马达带动磁盘旋转的速度。整个柱面都写满后再通过传动臂移动磁头读写其它柱面。读取数据时则需要确定数据所在的柱面接着是需要使用哪一个磁头柱面上一个磁头对应一个磁道最后确定在哪一个扇区。这种查找方式叫做CHS定址。虽然机械硬盘是通过这种方式进行定位的但操作系统只需将其看做线性的存储结构其它外存硬件也是如此硬件内部会给所有的基本存储单元编号。比如机械硬盘就是给扇区编号这样每个扇区就有了一个线性地址LBA其本质就是数组下标。要访问扇区时机械硬盘会通过硬件电路将接收到的LBA转化为CHS参数进行访问。这样操作系统只需将外存视为一个数组通过管理数组就能管理外存。事实上机械硬盘内部也是以数组的形式访问基本存储单元扇区的不过这个数组是三维的。我们知道CHS定址就是通过柱面、磁头和扇区进行定位。从总的角度看机械硬盘是一个柱面一个柱面地写入进一步就是在柱面内依次对各个磁道进行写入再进一步就是在磁道上依次向各个扇区写入。我们很容易就能明白三维数组中各维的含义假设该数组是chs[ i ][ j ][ k ]那么 i 就对应柱面 j 对应磁头也就是柱面上的磁道k对应磁道上的各个扇区。根据读写方式确定好LBA的编号规则用简单的公式就能使LBA与这个三维数组的三个下标相互转化感兴趣的可以自行了解。“块”概念其实机械硬盘是典型的“块”设备。操作系统要从中读取数据到内存中时为了提高效率会规定若干个基本存储单元为读取的基本单位每次读取时都是这个基本单位的整数倍这个基本单位就是块。块的大小可以更改但不能随意更改因为每次更改都要格式化硬盘。块的大小一般是4KB在机械硬盘中就是8个扇区所以硬盘中每8个扇区会被操作系统视为一个块并且操作系统还会对每个块进行编号用块号进行访问访问时将块号乘以8就得到了块的起始LBA。即使将整个磁盘按块划分块的数量还是太多了。为了方便管理在块之上还有分区的概念一般我们电脑中默认的C盘、D盘就是两个分区。而在Linux操作系统中分组与块之间还有划分了一层名为块组块组就是由多个块构成。文件系统基本概念文件系统是操作系统的一个子系统它由两部分组成一是文件系统驱动本质就是一种程序随着操作系统的启动从磁盘加载到内存中对文件的读写操作就是由它处理可以看成操作系统的一部分二是磁盘中的数据组织结构也就是存储文件的结构如果没有特殊说明的话我们后面说的文件系统就是特指这个结构它的载体是分区如下图图中的Partition就是分区的意思。每个分区有自己的文件系统这些文件系统相互独立也就是独自管理自己的分区不会相互干涉。管理结构分区由块组Block Group构成块组中又分为不同的区域分别存储不同的数据这些区域自然是由整数个块构成。Linux下文件的内容和属性是分开存储的文件的属性存储在inode中inode是一个结构体存储在inode Table中文件内容则存储在Data Blocks中。位图Block Bitmap和inode Bitmap中分别记录了数据块Data Blocks内的各个块和inode Table内的各个inode有没有被使用值为0表示未使用为1则相反。我们删除文件的本质就是将这两个位图中对应的部分改成0文件的数据依旧在原处。直到写入新文件时操作系统通过位图发现对应的区域没有被使用新文件会直接覆盖该区域这时旧文件的数据才会彻底消失。所以即使将文件删除也是有恢复的可能的。inode大小是固定的128字节而文件名的大小不能确定因此并不在inode中。要注意这里是磁盘不是内存没有用malloc开辟空间的概念。文件系统是通过inode中的编号inode_number对文件进行区分的。使用指令 ls 或 ll 时带上-i选项就能看到文件的inode编号。下图输出结果中的第一列就是inode编号。通过inode编号只能在一个分区内查找文件不能跨分区毕竟每个分区的文件系统是相互独立的不过可以跨组也就是inode与文件内容存储在同一个分区下的不同的块组中因为inode编号在一个分区的文件系统内是唯一的。至于查找文件时怎么确认在哪个分区等下会提到。GDT是块组描述符表里面的一个块组描述符对应所属分区内的一个块组。块组描述符中记录了对应块组的信息如inode Bitmap的起始位置、Data Blocks的起始位置、空闲的inode和数据块个数等。Super Block中存储的也是关于整个分区的信息其中就有各个块组中inode和数据块的使用数量和空闲数量。操作系统运行时会将所有分区的Super Block加载到内存中用链表管理起来通过这个链表就能管理所有的分区。需要说明的是虽然一个分区只需要一个Super Block和GDT但是它们中的数据是使用整个分区的关键为了防止磁盘存储它们的位置发生故障而导致整个分区无法使用文件系统会在许多块组中存储Super Block和GDT的备份。当我们格式化整个分区的时候除了将所有块组的两个位图全部置0还要修改所有的备份中的数据。格式化的真正意义在于修改分区内文件系统的管理信息使分区中存储的数据可以被覆盖或是在分区中建立文件系统使分区可以正常使用。文件访问原理路径访问目录本身也是一种文件。在文件系统中目录的存储方式和文件是一样的包含inode文件属性和文件内容两部分比较特殊的是它的文件内容是该目录内文件的文件名与inode的映射关系。通过目录就能找到文件名对应的inode进而找到对应的文件。由此也可以看出文件名的存储方式比较特殊它存储在目录文件内。同时我们也能发现在我们看来处于同一目录下的文件实则分散在磁盘各处这就是不能直接发送目录或文件夹要先打包的原因。当我们要访问某一文件时就是通过根目录逐级向下查找这就是路径解析。而根目录就是默认打开的。但是如果为了查找一个文件就不停地将磁盘中的目录文件加载到内存的话效率会很低因此操作系统会用一颗多叉树记录所有访问过的目录的内容也就是文件名和inode的映射关系这颗多叉树就是目录树。其次bash中还记录了当前工作路径打开文件的操作或者包含了打开文件这个操作的操作本身也是一个进程如命令 ./[文件名] 和cat [文件名]等会继承bash中的当前工作路径进程将工作路径和我们输入的文件名提供给操作系统操作系统再通过目录树就能快速地访问对应的文件。目录树的节点同时还会连接在LRU结构中通过节点中的多个指针实现以便进行节点淘汰和快速访问具体细节不再展开。访问磁盘中的文件时都会先在目录树中查找如果没找到才会用路径解析在磁盘中查找。使用inode前需要确认其属于哪个分区那么操作系统是怎么知道它属于哪个分区的呢事实上每一个分区都与一个目录相关联进入这个目录就相当于进入这个分区。将分区与目录关联的操作叫做挂载对应的目录叫做挂载点。从Windows系统的角度可以更方便我们理解最简单的例子就是给我们的电脑插上一块U盘在电脑上确认后就可以发现在文件资源管理器中除了原有的C盘、D盘等还多了一块盘而我们访问这块盘的方式就是双击这块盘的图标打开对应的目录那么这个U盘就是挂载到这个目录了而这个目录就是挂载点。在Linux系统中也是类似的道理不过Linux系统将挂载点视为普通的目录文件Windows则将其视为特殊的“盘符”。链接访问Linux下存在两种链接文件一种是软链接另一种则是硬链接。软链接可以用命令ln -s [目标文件名] [链接文件名]创建。软链接文件是一个独立的文件在下图中可以看到它的inode编号与对应文件不同。在它里面保存了目标文件的路径我们可以通过软链接快速访问对应的文件相当于Windows下的快捷方式。使用时将软链接文件名看成目标文件的文件名即可如cat [链接文件名]。如果使用指令ln创建链接文件时不带选项-s那么创建的就是硬链接。硬链接不是独立的文件可以发现它的inode编号和目标文件是一样的。它的本质是一组新的文件名与inode的映射和C中的引用类似相当于给文件起了个别名。创建硬链接后目标文件的inode中的引用计数会增加也就是硬链接数会增加。上图输出结果的第三列就是文件的引用计数。目标文件原本的文件名和inode的映射也相当于一个硬链接只有将所有的硬链接全部删除文件才会真正被删掉。所以当我们需要防止文件被误删时不需要拷贝一份创建硬链接即可。此外我们可以发现新建的目录文件的引用计数是2这是因为目录中默认存在的文件.就是该目录的硬链接。相应地另一个默认存在的文件. .就是上一级目录的硬链接。但在Linux下我们是不能为目录建立硬链接的这是为了防止出现路径环导致一些功能出现错误。比如我们建立了一个根目录的硬链接再使用查找文件的功能从根目录开始查找文件当查找到我们建立的根目录的硬链接时会将其当成目录并进入这样就陷入了死循环。至于目录自带的 . 和 .. 以及目录的软连接自然是会被直接跳过。