【Linux】(26) 详解磁盘与文件系统:从物理结构到inode机制

lvy¯ 2024-08-05 14:37:02 阅读 75

目录

1.认识磁盘

1.1 理论

1.2 磁盘的物理结构

CHS 寻址

1.3 磁盘的逻辑抽象结构

2. inode 结构

1.Boot Block 启动块

2.Super Block(超级块)

3.Group Descriptor Block(块组描述符)

4.Data Blocks (数据块)

5.Inode Table (inode表)

stat

示例

6.Bitmap 位图

思考:

3.文件系统

3.1 增/删/查/改 一个文件

3.2 理解目录

dentry 缓存:


Preface:

文件系统是一种用于在存储设备上组织数据的方法。Ext2是Linux操作系统中使用的一种文件系统,全称是Second Extended File System(第二扩展文件系统)

尽管Ext2在许多现代Linux系统中已被更新版本的文件系统(如Ext3和Ext4)所取代,它仍然在某些场景下被使用,尤其是在需要快速读写性能且不介意缺少日志功能的场合。

由于Ext2不支持日志功能,因此在系统崩溃时可能会丢失数据或在恢复时需要更长时间。现在,Ext4文件系统已经成为大多数Linux发行版的默认文件系统,因为它提供了更好的性能和更多的功能。

前面我们学习到了一个被打开的文件,那如果一个文件没有被打开呢??

我们可以知道它将在磁盘中进行存储,可以通过如下角度进行思考:

路径问题存储问题获取的问题(属性+文件内容)效率

引出了我们的学习路线:

认识硬件--磁盘对硬件进行抽象理解文件系统

1.认识磁盘

1.1 理论

磁盘上存储文件属性+内容

文件的内容--数据块文件属性--inode

sum: Linux 文件在磁盘中存储,是将属性和内容分开存的

当下磁盘存储的运用场景

  1.现在电脑上装的都是SSD了

 SSD代表固态硬盘(Solid State Drive),是一种使用闪存芯片作为存储介质的电脑存储设备。目前个人电脑或工作站等设备普遍采用SSD作为主要的存储介质。SSD相比传统的机械硬盘(HDD,Hard Disk Drive)有更快的读写速度、更低的功耗和更小的噪音,同时因为没有机械运动部件,所 以更耐震动,故障率也相对较低。

  2.公司服务器长时间存储还是使用磁盘,进行存储分级:冷热分离

在公司或企业的服务器存储解决方案中,尽管SSD在性能上有明显优势,但出于成本和容量考虑,长时间存储大量数据通常还是使用机械硬盘(HDD)。HDD的成本较低,存储容量较大,适合用来存储那些不经常访问但需要长期保存的数据。存储分级:这是指根据数据的访问频率和重要性将存储分为不同的级别。通常分为热存储(hot storage)和冷存储(cold storage)。

热存储:用于存储经常访问的数据,这些数据需要快速访问,因此通常使用SSD或快速的磁盘阵列。冷存储:用于存储不经常访问的数据,这些数据可以存储在成本更低的存储介质上,如大容量HDD或更便宜的云存储服务。

意义:优化了成本和性能,确保经常访问的数据能够快速访问,而不常用的数据则以较低的成本进行存储

机械硬盘在计算机系统中的两个特点:它是一种包含机械运动部件的设备,同时也是连接到计算机主机的外部硬件设备

磁盘是一个机械设备

这里的“磁盘”通常指的是机械硬盘(HDD,Hard Disk Drive),它是由多个机械部件组成的存储设备。在个人电脑或服务器中,尽管还有其他可能包含机械部件的设备(如光盘驱动器、软盘驱动器等),但在现代计算机系统中,机械硬盘往往是唯一的主要机械存储设备。这是因为其他类型的存储设备,如固态硬盘(SSD)、内存条(RAM)、U盘等,都不包含机械运动部件。

也是一个外设

“外设”是外部设备的简称,指的是连接到计算机主机的硬件设备,用于扩展计算机的功能。磁盘(如HDD)作为存储设备,通常被视为计算机的外设,因为它位于计算机主机的机箱外部(或者至少是可分离的),并通过数据传输接口(如SATA、SAS等)与主板连接。尽管它是计算机运行所必需的组成部分,但它并不直接集成在主板上,因此被分类为外设。

1.2 磁盘的物理结构

可以先根据下面的图片,有一个直观的感受

最后一张图的磁盘,类似于三张两面都光的光盘

磁盘作为计算机中唯一的机械部件,通常由一个或多个旋转的盘片组成,每个盘片有两个面,每个面上有一层磁性材料。通过主轴连接,磁盘上附有磁头。数据存储的基本单位是扇区(Sector),传统上每个扇区大小为512字节,但近年来逐渐过渡到4096字节的大扇区。

主轴下面有马达,一秒钟两万转都有可能

物理结构:

磁头是一面一个,左右摆动,两个整体移动的,有磁头停靠点磁头和盘面不接触,所以物理上不适用于笔记本,开机状态移来移去,磁头刮花了磁盘,属于硬件问题机械磁盘要在无尘环境下,灰尘落上去就像一座大山,可能会把数据都磨没了

磁盘存储:

所有的数据都在盘片上以二进制存储,磁头通过充放电写入内存掉电易失设备,磁盘永久性存储介质通过充放电/强弱/波,在磁盘上写入 01 数据,像吸铁石的 N S 级高温消磁大型互联网公司淘汰磁盘,国家规定不能数据泄露,磁盘擦除并不完全,局部数据的残留也可以被恢复,磁盘上的影子数据也挺危险的,解决方法:和厂商协商,调用接口去除~

磁盘的存储构成

磁盘被访问的最基本单元是扇区---大小有可能 512 字节/ 4KB我们可以把磁盘看作由无数个扇区构成的存储介质

3. 第一步:定位一个扇区:哪一面(哪个磁头),哪一个磁道(纵向上形成柱面),哪一个扇区

4. 磁头摆动:定位磁道和柱面的过程

    盘片转动:定位扇区的过程

5. 软件寻址,相关内容还是尽量放在一起,因为运动越少,效率越高

CHS 寻址

三个参数:Cylinder(柱面)Header(磁头)Sector(扇区)==》CHS 寻址方式

1.3 磁盘的逻辑抽象结构

我们可以类比于磁带,将扇区线性来看

将一个圆延展开来进行扇形分区(struct 来实现):存储 LBA 信息

随着技术发展,出现了逻辑块地址(LBA)的概念,它可以解决CHS寻址的局限性。LBA将磁盘上的所有扇区视为一个线性序列,操作系统可以通过LBA直接定位到扇区,而无需关心具体的磁头、柱面和扇区信息。

可以借助上图了解,基于对磁盘的理解建模的过程

磁盘对扇区一视同仁的划分,管理好了 10 G 的一个扇形,就能管理好 800 G--分治的思想 化大为小


2. inode 结构

1.Boot Block 启动块

文件系统不仅需要存储文件内容,还需要存储文件的元数据,如文件大小、所有者、权限等。这些元数据存储在索引节点(inode)中。

结合上部分,先来看一下这个 10G 的分区

在Linux文件系统中,Boot Block(启动块)是一个非常重要的组成部分,尤其是在传统的磁盘驱动器中。Boot Block位于磁盘的最前端,通常是磁盘的第一个扇区,也被称作主引导记录(Master Boot Record, MBR)。

Boot Block的功能

引导加载:当计算机启动时,BIOS会读取磁盘的第一个扇区(即Boot Block),并将控制权传递给该扇区中的主引导程序。分区检测:主引导程序会检查分区表,确定启动分区的位置。操作系统加载:主引导程序会根据分区表中的信息选择一个活动分区,并加载该分区上的引导加载程序(如GRUB或LILO)。

Boot Block的示例

对于一个传统的MBR分区布局,Boot Block(即MBR)的结构如下:主引导程序:占据MBR的前446字节。分区表:接下来的64字节(每个分区条目16字节,共4个)。引导签名:最后两个字节<code>0xAA55。

对于现代系统的变化

对于使用GUID分区表(GPT)的现代系统,Boot Block的概念略有不同。在GPT分区方案中,磁盘的第一个扇区(通常称为保护MBR)通常包含一个简单的MBR,用于兼容旧版BIOS系统。真正的引导加载程序和GPT分区表位于磁盘的其他位置。

如何查看Boot Block

尽管查看Boot Block的内容通常不是日常管理任务的一部分,但如果需要,可以使用特定的工具来进行。例如,使用dd命令可以从磁盘复制第一个扇区:

sudo dd if=/dev/sda of=mbr bs=512 count=1

这将把磁盘/dev/sda的第一个扇区(即Boot Block)复制到文件mbr中。随后,可以使用十六进制编辑器或特定的工具来查看该扇区的内容。

总结

Boot Block是磁盘上非常重要的一个区域,它包含了启动系统所需的关键信息。无论是传统的MBR还是现代的GPT,Boot Block都扮演着启动过程中的关键角色。

2.Super Block(超级块)

超级块是文件系统中的一种特殊的数据结构,它包含了整个文件系统的全局信息。这些信息包括但不限于:

文件系统类型(如ext2、ext3、ext4等)。文件系统块大小(例如1024字节、2048字节或4096字节)。文件系统的总块数和可用块数。文件系统的总inode数和可用inode数。文件系统的挂载时间、上次写入时间、上次检查时间等。文件系统的特征标志(例如是否有日志功能等)。

超级块对于文件系统的正确操作至关重要。如果超级块损坏,可能导致文件系统无法被识别或挂载。大多数文件系统都会在不同的位置保存多个超级块副本,以防止单点故障。

3.Group Descriptor Block(块组描述符)

在某些文件系统中,如ext2、ext3和ext4,文件系统被分割成多个块组,以提高性能和简化管理。每个块组都包含一个块组描述符,该描述符包含了该块组的一些重要信息,例如:

该块组内的数据块总数。该块组内的可用数据块数量。该块组内的inode总数。该块组内的可用inode数量。该块组的块位图和inode位图的位置。该块组的inode表的位置。

块组描述符使得文件系统能够快速访问每个块组的状态信息,而无需每次都访问超级块。这对于大型文件系统尤其有用,因为它减少了对超级块的访问频率,提高了性能。

总结一下:

Super Block:包含整个文件系统的全局信息,如总块数、总inode数等。Group Descriptor Block:针对文件系统中的每个块组,包含该块组内的数据块和inode的数量和位置等信息。

这些信息对于文件系统的管理和维护至关重要,确保了文件系统能够正确地处理文件和目录的存储、检索和删除等操作。

4.Data Blocks (数据块)

数据块是文件系统中用于存储文件实际内容的基本单位。每个文件的内容都分布在磁盘上的一个或多个数据块中。数据块的大小取决于文件系统的配置,通常为1024字节、2048字节或4096字节等。

特点

可变大小:数据块的大小在文件系统创建时被定义,并且在整个文件系统的生命周期中保持不变。非连续存储:文件的内容不一定存储在连续的数据块中,而是可以分散在磁盘的不同位置。间接寻址:文件的内容通过inode中的指针来间接寻址,这些指针指向文件的数据块。

用途

存储文件内容:每个文件的实际内容(如文本、图像、音频等)都存储在数据块中。高效利用磁盘空间:通过允许文件内容分散存储,文件系统可以更高效地利用磁盘空间。

5.Inode Table (inode表)

inode是文件系统中的一个数据结构,用于存储文件的元数据。每个文件都有一个与之对应的inode。inode表则是inode的集合,它包含了文件系统中所有inode的列表。

特点

固定大小:每个inode的大小通常是固定的,通常是128字节或256字节。元数据存储:inode中存储了文件的元数据,包括文件的大小、创建时间、修改时间、权限、所有者等。文件内容的指针:inode中包含指向文件数据块的指针,这些指针告诉系统文件内容存储在哪里。

用途

存储文件元数据:inode存储了文件的重要属性,如权限、所有者、大小等。文件内容的间接寻址:inode通过指针间接指向文件的内容,这意味着文件名和文件内容是分离的。inode与文件名的关联:文件名不在inode中存储,而是存储在目录项中。目录项将文件名与inode编号关联起来,以便通过文件名找到对应的inode。

stat

用法查看文件具体信息

stat [OPTION]... FILE...

FILE:可以是一个文件名或目录名。OPTION:可以是多个选项,用于定制输出信息。

选项

-c--format:指定输出格式,可以使用特定的格式化字符串来自定义输出结果。-f--file-system:显示文件所在文件系统的统计信息,而不是文件本身的统计信息。-L:递归地显示符号链接的目标的统计信息。-l:显示符号链接本身的统计信息,而不是链接的目标。-t--time=WORD:指定输出的时间戳类型,WORD 可以是 atimemtimectime-h--human-readable:以人类易读的格式显示文件大小(例如,1K 234M 2G 等)。

使用场景

文件调试:当需要了解文件的具体信息时,比如权限、所有者等。脚本编写:在编写 shell 脚本时,可以利用 stat 获取文件的详细信息,进行条件判断或动态生成文件列表。系统监控:监控文件的访问、修改或状态改变时间,用于安全审计或性能分析。

stat 命令是 Linux 系统管理员和开发者不可或缺的工具之一,它提供了文件系统的深入视图,有助于更好地理解和管理文件和文件系统。

会显示 acm(时间戳)

下面解释一下文件的三个时间:

Access 最后访问时间Modify 文件内容最后修改时间Change 属性最后修改时间

示例

实现操作的融会贯通:

1. 查看文件example.txt的inode信息

stat example.txt

这个命令将显示文件example.txt的inode信息,包括inode编号、文件大小、权限等。

2. 查找文件<code>example.txt的inode编号

回顾:ls -l 做的就是读取存储在磁盘上的文件信息,然后把它们显示出来

<code>ls -i example.txt

这个命令将显示文件<code>example.txt的inode编号。

3. 查看文件<code>example.txt的内容

cat example.txt

这个命令将输出文件example.txt的内容到标准输出。

4. 假设需要直接访问数据块200(通常不建议这样做,因为它绕过了文件系统)

首先,需要确定文件系统的设备文件,比如/dev/sda1。然后使用dd命令读取数据块。以下是一个示例命令,假设每个数据块大小为4096字节,数据块200的偏移量计算方式为200 * 4096

dd if=/dev/sda1 bs=4096 skip=200 count=1 of=data_block_200.bin

这里:

if 指定输入文件(文件系统设备)。bs 设置块大小(这里为4096字节)。skip 指定跳过的块数(这里为200)。count 指定复制的块数(这里为1)。of 指定输出文件(这里将数据块内容输出到data_block_200.bin)。

5. 假设需要修改文件权限

chmod 644 example.txt

这个命令将设置文件example.txt的权限,使得所有者有读写权限,组和其他用户只有读权限。

6. 假设需要修改文件所有者

chown user:group example.txt

这个命令将更改文件example.txt的所有者为user,所属组为group

注意:

直接访问数据块的操作通常不应该在正常操作中进行,因为它可能破坏文件系统结构。在执行这些操作之前,请确保备份重要数据,避免数据丢失。这些命令可能需要root权限才能执行。文件系统的具体实现可能会有所不同,上述命令是在一般情况下的示例。


总结

Data Blocks:存储文件的实际内容。Inode Table:存储各种文件各自的 inode 元数据,包括文件内容所在的数据块的指针。

通过这种方式,文件系统可以有效地管理文件的内容和元数据,同时也提供了灵活的方式来处理文件的存储和检索。

6.Bitmap 位图

inode Bitmap (属性)位图:

比特位的内容 inode 是否有效的

Block Bitmap (文件内容)位图

和块号联系起来,申请和释放有关,内容块是否存在

思考:

删一个文件的时候,用不用把块内容清空呢?                                                                  不用清空原始数据,直接把管理 位图清零 即可inode 理论上连续的,但是还存在删除后的加入(搜索到空位就添加)inode 和 data block 都有对应的编号,可以找到对应的扇区super block 整个文件的基本信息,不是每个块组都存有,零零星星的存在,确立了稳健性❗格式化: 每一个分区在被使用之前,都必须提前先将部分文件系统的属性信息提前设置进对应的分区中,方便我们后续使用这个分区或者分组,所以格式化就是把前四个重新设置,后面两个清空


3.文件系统

3.1 增/删/查/改 一个文件

系统做了些什么?

思路:

Linux 系统中,一个文件,一个 inode ,每个 inode 都有自己的编号(不能跨分区),文件名不属于 inode 内的文件属性!

通过路径能确定 200G ,存到 10G 的块里面了,找组后,在 inode map 里面找空的块

把文件误删了,是把位图删了,删除=允许被覆盖

✔️ 步骤

系统会执行一系列底层操作来完成这些任务。下面是每个操作涉及的主要步骤:

新建文件

创建一个新文件,操作系统主要会做如下四个操作:

① 存储属性:内核找到一个空闲的结点 (这里是 263466),内核把文件信息记录到其中。

② 存储数据:该文件需要存储在三个磁盘块,内核找到了三个空闲,300,500,800。将内核缓冲区的第一块数据复制到 300,下一块复制到 500,最后复制到 800……

③ 记录分配情况:文件内容按顺序 300,500,800 存放,内核在 inode 上的磁盘分布区记录了上述块列表。

④ 添加文件名到目录:新的文件名 abc。Linux 在当前目录中记录该文件,通过内核将入口 (263466, abc) 添加到目录文件,文件名和 inode 之间的对应关系将文件名和文件的内容及属性链接起来。

删除文件

查找 inode:通过文件名找到对应的 inode。释放 inode 引用:减少 inode 的链接计数。删除目录项:从父目录中删除指向该 inode 的条目。回收资源:如果 inode 的链接计数降为 0,则回收 inode 和其关联的数据块。更新文件系统元数据:更新文件系统的其他元数据,比如文件系统的块使用情况。

我怎么知道一个文件的 inode 编号?

ls -i 可查看,but 使用者基本不关心 inode ,用的是文件名


3.2 理解目录

目录也是文件,也有自己的 inode ,目录也要有自己的属性

目录有内容吗??要不要有数据块?里面放什么呢?

要,该目录下,文件的文件名 和 对应文件的 inode 的映射关系

❗ 所以我们现在就能解释, 为什么同一个目录下不能有同名文件?

ll 查看时,先找到目录的 inode, 目录内容中存储了文件的 inode,找到对应文件的 inode,就可以访问文件内容啦,例如说删除文件实际上是删除文件名与 inode 的关联,也就是从目录项中移除该文件名。这个操作需要对目录进行写操作,因为目录项(包含文件名)存储在磁盘上,并且需要被修改。但是我们限制了这一操作

目录下,没有 w ,我们无法删除文件,没有 r,我们无法查看文件是为什么?

因为想读取,目录不让读,拿什么查找到 inode,还有没有 x 无法 cd,都是通过对目录中 对文件 inode 的访问设置来管理的

目录是文件,也有 inode 编号,那么是如何管理的呢?

往上会一直访问到根目录,相当于是一个递归的实现

dentry 缓存:

目录项对象:dentry代表文件系统中的一个目录项,即一个文件或目录的名称与其inode(索引节点)之间的关联。路径解析:当用户或程序请求访问一个文件或目录时,文件系统需要解析路径名,dentry缓存可以快速地定位到对应的inode,从而避免了每次都从磁盘读取目录信息

有绝对路径的话,不就可以从根目录往下拿到对应的 inode 了,为什么还要递归?

递归是我们从内部讲起的,就说要一路找上去,实际拿着文件路径从左到右解析就行,因为我们的任何一个文件,在进程内部都有路径,按照路径,应用层是知道文件和路径的



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。