目录

LinuxExt系列文件系统

【Linux】Ext系列文件系统


1. 整体学习思维导图

https://i-blog.csdnimg.cn/direct/ddfeed046a024e0ab5bfccc8b46324f1.png

2. 认识理解磁盘

了解文件系统离不开存储文件的硬件–磁盘,我们需要认识一下磁盘的构造!

https://i-blog.csdnimg.cn/direct/bc2ee5eb235942569c5c817f339b4e3e.png

磁盘如图所示,我们可以看见许多部件:磁头,盘片,机械臂杆,主轴等等,并且一个磁盘由多个盘片构成,一张盘片的正反面都可以存储信息,正反也存在着两个读写的磁头。

存储原理

首先需要定位到需要读取的 柱面, 然后确定对应的 磁头 此时的盘片正在高速转动,磁头定位到我们需要读取的 扇区 ,我们知道盘片由一个个小的磁性分子组成,磁性存在着两级正好对应计算机中的0和1,写入文件时我们只需要改变其磁性即可实现,读取文件时我们收集其磁性的排列进行解读即可得到信息。

  • CHS定址

指的就是我们前面定位的过程:先确定柱面(cylinder),次之磁头(head),最后是扇区(sector)!

物理结构

我们从硬件物理的角度来看,磁盘由一个个盘片构成,物理结构是一种圆形的,那么磁盘在我们计算机是以什么样的存储方式描述的呢?答案是线性的结构,类似于数组一样的,那么圆形怎么到线性的结构?我们知道盘片就像一圈圈的 磁道 “卷"起来的,我们将他舒展开来不就是一个线性的结构吗?

https://i-blog.csdnimg.cn/direct/e5f13c498a1248318ff6e9e0c39916dc.png

逻辑结构

对于一个盘片来说磁道展开是一个一维数组,我们的磁盘由多个盘片组成,多个盘片构成的就是柱面,这个柱面的构造展示给我们的就是一个多维数组的样子:

https://i-blog.csdnimg.cn/direct/dd55398a313347beaab1aea19da7a8f1.png

  • 多个柱面

https://i-blog.csdnimg.cn/direct/43d0566b64f74aaf801049898e9be2ea.png

但是在我们所学的c/c++底层中的多维数组最后还是一个线性的一维数组,我们将柱面拼接起来,磁盘拼接起来,我们就会得到一个线性的数组结构!

https://i-blog.csdnimg.cn/direct/c7efb63ee2764ef69ea71d2ee1b49c49.png

CHS && LAB 定址

OS文件系统访问磁盘,不以扇区为单位,而是以"块"为单位,一般单次访问是4KB(连续的8个扇区),这个访问的大小可以调整。对于物理磁盘来说是CHS寻址,但是对于OS来说就需要换一种形式的寻址->LAB!

  • LAB和CHS的相互转换

    • **LAB = 柱面号 *** 磁头 数 * 每个 磁道 扇区 个数 + 磁头号 * 每个磁道的扇区个数 + 扇区个数 - 1(-1是因为LAB地址从0开始,扇区号基本从1开始)
    • CHS = LAB % ( 磁头 数 * 每个 磁道 扇区 个数) + LAB % (磁头号 * 每个磁道的扇区个数) + LAB % (每个磁道的扇区个数) + 1

有了这个转换关系,我们OS就可以使用一串数字去访问对应的磁盘位置了!

3. 文件系统

3.1 块的概念

我们前面提到过"块”,单次访问扇区的速率太低,我们OS一次访问8个扇区,我们将其命名为一个块,块的大小常见的是4KB,“块"是文件存储的最小单位

[ouyang@iZ2ze0j6dd76e0o9qypo2rZ ~]$ stat Linux_Git/
  File: ‘Linux_Git/’
  Size: 4096              Blocks: 8          IO Block: 4096   directory
Device: fd01h/64769d        Inode: 1315336     Links: 3
Access: (0775/drwxrwxr-x)  Uid: ( 1001/  ouyang)   Gid: ( 1001/  ouyang)
Access: 2025-02-27 10:18:08.496640943 +08:00
Modify: 2025-02-27 10:18:06.488552668 +08:00
Change: 2025-02-27 10:18:06.488552668 +08:00
 Birth: -

块号 = LAB / 8

3.2 分区的概念

我们知道现在计算机的存在着好几个盘:C/D/E等等,其实底层他们是一块总的内存是通过分区来实现多个盘的,比如一个800G的存储,我们可能会以300G为单位分区为3个区,每个区含有大量的快组成:

https://i-blog.csdnimg.cn/direct/3e7266edb9b14175bae48e562aa6ec6f.png

一个分区又可以分为多个组,每个组这边以30G来划分:

https://i-blog.csdnimg.cn/direct/428f8fba8de848fab156286ba6e6b435.png

3.3 inode概念

我们之前了解过一个 文件 = 内容 + 属性 组成的,在Linux中文件的内容和属性是分开存储的,每个文件的属性被存储在一个结构体中 struct inode 之中。

[ouyang@iZ2ze0j6dd76e0o9qypo2rZ ~]$ ls -l
total 28
drwxrwxr-x 2 ouyang ouyang 4096 Dec 15 11:00 dir_2024_12_11
drwxrwxr-x 4 ouyang ouyang 4096 Dec 16 08:40 dir_2024_12_15
drwxrwxr-x 3 ouyang ouyang 4096 Dec  8 10:40 dir_2024_12_3
drwxrwxr-x 2 ouyang ouyang 4096 Dec 11 16:04 dir_2024_12_8
drwxrwxr-x 3 ouyang ouyang 4096 Jan 25 11:44 dir_2025
drwxrwxr-x 3 ouyang ouyang 4096 Feb 27 10:18 Linux_Git
-rw-rw-r-- 1 ouyang ouyang  827 Oct 23 15:00 vimrc-install.sh
struct inode
{
    int type;
    int size;
    ....
    int inode_number; // inode号
};

这个结构体的大小是固定的128字节,一个数据块4KB可以存储32个inode,并且每一个文件都有一个inode,并且inode内部有一个标识符叫做inode号。

https://i-blog.csdnimg.cn/direct/8b2ff68bbb4a4e5facf335af0b39bfbc.png

• 文件名属性并未纳入到inode数据结构内部

• inode的大小⼀般是128字节或者256,我们后面统⼀128字节

• 任何文件的内容大小可以不同,但是属性大小⼀定是相同的

4. Ext2文件系统

https://i-blog.csdnimg.cn/direct/7d1a862241ba4c6a81add1f71d25c63a.png

每个分区会被划分为多个 Block Group(块组) ,进一步划分是为了更加方便管理。

  • Data Blocks

这一块区域主要用于存储文件的内容部分

  • Inode Table

这块区域主要用于存储文件的属性部分,使用结构体存储

  • Block/Inode Bitmap

位图部分,主要是用于表示Data Blocks/Inode Table某个块是否被占用,更加快速找到未占用的块进行访问

  • GDT

块组描述符,描述块组的属性信息,整个分区被划分为多少块组就存在多少GDT,GDT用于存储一个块组的描述信息,比如从哪到哪是Data Blocks/Inode Table/(Block/Inode Bitmap),还存在多少空闲的inode和数据块等等。

  • Super Block

是描述整个文件操作系统的描述符,和GDT的作用相似。记录的信息主要有:bolck和inode的总量,未使用的block和inode的数量,⼀个block和inode的大小,最近⼀次挂载的时间,最近⼀次写入数据的时间,最近⼀次检验磁盘的时间等其他文件系统的相关信息。SuperBlock的信息被破坏,可以说整个文件系统结构就被破坏了。

注意 :

  • 每个分区内部,inode编号和块号都是唯一的,所以我们只需要拿到inode_number就可以知道文件在哪个分组之中。
  • 格式化的本质:我们平时可能有过这种感觉:下载一个软件很慢,删除一个软件很快。这是为什么呢?我们下载一个软件是需要实打实的写入到 Data Blocks ,但是我们删除一个软件只需要将其对应的位图位置改为未占用,后来的数据直接覆盖写入即可!

5. Linux下的目录

首先我们知道以下几点:

  • inode中并没有保存文件名,那么文件名保存在哪?

    • 文件名保存在当前文件所在的目录文件之中,那么目录文件名呢?保存在根目录文件之中,根目录文件名由OS管理加载。
  • 我们平时使用Linux系统寻找文件,都是路径+文件名,并没有使用inode号寻找,为什么可以找到?

    • 存在一个映射的哈希表管理者文件名和inode号的映射关系。

由以上两点我们得到一个信息:我们访问任何文件都需要其对应的路径进行查找,并且这个路径由/路径开始,对这个路径进行解析找到对应的文件内容块无疑是一次I/O操作,这会带来效率问题,因此OS在进行路径解析时候,会把我们历史访问的所有目录(路径)形成一棵多叉树进行保存,Linux系统的树状目录结构就是这么来的。

[ouyang@iZ2ze0j6dd76e0o9qypo2rZ linux_-git_-warehouse]$ tree dir_2025_1_10
dir_2025_1_10
└── Test.cpp

0 directories, 1 file

Linux中,在内核中维护树状路径结构的内核结构体叫做: struct dentry

5.1 挂载分区

我们已经能够根据inode号在指定分区找文件了,也已经能根据目录文件内容,找指定的inode了,在指定的分区内,我们可以为所欲为了。可是:

问题:inode不是不能跨分区吗?Linux不是可以有多个分区吗?我怎么知道我在哪⼀个分区???

  • 磁盘->分区->格式化->我们不能使用该分区,需要有一个目录进行关联才可以使用!
  • 分区写入文件系统,无法直接使用,需要和指定的目录关联,进行挂载才能使用。所以,可以根据访问目标文件的"路径前缀"准确判断我在哪⼀个分区。通过这样进入一个目录就相当于进入一个分区。

https://i-blog.csdnimg.cn/direct/9bdc6b217c2447fcb2f40c34d55685a5.png

6. 软硬链接

6.1 概念/应用

  • 软连接:
ln -s obj desc
ln -s code_soft /home/ouyang/Linux_Git/linux_-git_-warehouse/dir_2025_3_2/code.c(绝对路径)

软链接是一个独立的文件,他拥有独立的 inode number ,软连接相当于创建一个快捷方式

https://i-blog.csdnimg.cn/direct/d29bc58d080c4cabaf38134b06402b6e.png

  • 硬链接:
ln  obj desc
ln  code_head /home/ouyang/Linux_Git/linux_-git_-warehouse/dir_2025_3_2/code.c(绝对路径)
[ouyang@iZ2ze0j6dd76e0o9qypo2rZ linux_-git_-warehouse]$ ll
total 92
drwxrwxr-x 2 ouyang ouyang 4096 Dec 24 10:21 dir_2024_12_23
drwxrwxr-x 2 ouyang ouyang 4096 Feb 22 21:52 dir_2024_12_24
[ouyang@iZ2ze0j6dd76e0o9qypo2rZ dir_2025_3_2]$ sudo ln code_Hard /home/ouyang/Linux_Git/linux_-git_-warehouse/dir_2025_3_2/Test.c 
[ouyang@iZ2ze0j6dd76e0o9qypo2rZ dir_2025_3_2]$ ls -li
total 8
1315789 -rw-rw-r-- 2 ouyang ouyang    0 Mar  3 09:35 code_Hard
1315786 drwxrwxr-x 2 ouyang ouyang 4096 Mar  3 09:29 dir
1315788 -rw-rw-r-- 1 ouyang ouyang    0 Mar  3 09:31 Test
1315789 -rw-rw-r-- 2 ouyang ouyang    0 Mar  3 09:35 Test.c
1315783 drwxrwxr-x 3 ouyang ouyang 4096 Mar  3 09:27 Test_Dir

硬链接之后,不是一个独立的文件,文件的 inode number 相等,相当于一个引用,对应的引用计数会++,可以用作于备份,只有当连接数为0时,磁盘才会释放其文件的空间内容!

硬链接的新文件名也和原本的 inode number 进行了一次映射关系!

  • 我们在删除文件时干了两件事情:1.在目录中将对应的记录删除,2.将硬连接数-1,如果为0,则将对应的磁盘释放。
  • . / .. 表示当前目录和上级目录也是硬链接的一种使用!

探究硬链接:

  • 硬链接只能给普通文件建立,不能给目录建立!
[ouyang@iZ2ze0j6dd76e0o9qypo2rZ dir_2025_3_2]$ ln Dir_link_hard /home/ouyang/Linux_Git/linux_-git_-warehouse/dir_2025_3_2/Test_Dir/
ln: ‘Dir_link_hard’: hard link not allowed for directory
  • 问题:为啥 ... 文件是对目录的硬链接?这不和上面构成矛盾吗?

    • Linux 允许给 ... 建立硬链接,不允许用户自己对目录建立硬链接
    • 不允许用户建立链接是防止树结构查找出现路径循环问题!

https://i-blog.csdnimg.cn/direct/ae3f5a811c7741d68e169cb88d767657.png

  • ... 的名字是特殊处理的,就是为了防止路径循环问题,也是为了方便用户操作!

  • 软连接不也是会带来路径循环问题吗,如果说硬链接的处理方式是特殊名字,软连接的处理方式是什么?

    https://i-blog.csdnimg.cn/direct/80f5262161ed49d69e6e13a8ed9b674d.png

软连接文件前带了一个 l 作为区分!