跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Shell / Bash

Linux 文件系统与硬件结构详解

系统介绍了 Linux 文件系统与底层硬件的关联。内容涵盖机械磁盘的物理结构(磁头、磁道、柱面、扇区)及逻辑寻址(CHS 与 LBA 转换)。详细解析了 ext2 文件系统的组成,包括超级块、块组描述符、块位图、inode 表及数据块的管理机制。文章还探讨了目录与文件名的映射关系、路径解析与缓存(dentry)、以及分区挂载的原理,帮助读者建立从硬件到软件的文件存储完整认知。

咸鱼开飞机发布于 2026/3/21更新于 2026/6/2030 浏览
Linux 文件系统与硬件结构详解

回顾基础 IO

前面的章节主要围绕已打开文件的操作与理解展开,重点在于说明文件与进程之间的关系。我们知道,文件大体可以分为两类:已打开的文件和未打开的文件。

对于未打开的文件,它们并不驻留在内存中,而是被保存在磁盘等存储设备上。这就引出了一个新的话题——数据保存的方案。接下来,我们将带领大家深入了解未打开文件的特性和存储方式,并逐步展开相关内容的介绍。

理解硬件

机械磁盘是计算机中唯一的机械设备,优点是:容量大,价格便宜。缺点:慢。而在像腾讯、阿里这样的公司里面,就有自己的机房,机房里面存在上万个机械磁盘,用来存储数据,而多出的机械磁盘则可以外租到外面。

那么,这种磁盘长啥样呢?物理结构又是如何?

磁盘物理结构

文章配图

磁盘存储结构

文章配图

  • 一个磁片是具有正反两个磁面的。磁头和盘面也是一对一的,即一面一个磁头。
  • 磁面上实际上是有很多的磁道,其间隙很小。
  • 对于一个磁道会分出很多个小区域,称为扇区 (sector),而扇区之间也是具有间隙的。扇区:是磁盘存储数据的基本单位,512 字节,块设备。

文章配图

  • 磁头:像'笔',负责对磁盘进行数据读写。写入时,把电信号转化为磁信号记录在磁盘磁性涂层;读取时,将磁盘磁信号还原成电信号,让系统获取数据,是数据交互核心部件。
  • 磁头臂:是'支架',带着磁头移动,精准定位到磁盘不同磁道,确保磁头在读写数据时,能稳定、准确到达指定位置,配合主轴(马达)带动磁盘转动,实现全盘数据访问。

文章配图

柱面其实就是磁道,相同半径的磁道看做一个整体。

一面一个磁头,而磁头之间是共进退的!!!

既然扇区是磁盘存储数据的基本单位。那么如何定位一个扇区呢?

从磁盘存储结构上我们可以知晓:确定磁头,即选择哪一面;确定哪个磁道或者柱面;确定是哪一个扇区,从而定位到一个扇区。

文章配图

对磁盘特定位置进行寻址:

左右摆动,本质是在定位哪一个磁道 (柱面);

盘片旋转的本质:是确定了那一个磁道 (柱面),定位该磁道 (柱面上) 的哪一个扇区。

CHS 地址定位

文件 = 内容 + 属性 都是数据,无非就是占据那几个扇区的问题!能定位一个扇区了,能不能定位多个扇区呢?

文章配图

  • 扇区是从磁盘读出和写入信息的最小单位,通常大小为 512 字节。
  • 磁头(head)数:每个盘片一般有上下两面,分别对应 1 个磁头,共 2 个磁头
  • 磁道(track)数:磁道是从盘片外圈往内圈编号 0 磁道,1 磁道...,靠近主轴的同心圆用于停靠磁头,不存储数据
  • 柱面(cylinder)数:磁道构成柱面,数量上等同于磁道个数
  • 扇区(sector)数:每个磁道都被切分成很多扇形区域,每道的扇区数量相同
  • 圆盘(platter)数:就是盘片的数量
  • 磁盘容量=磁头数 × 磁道 (柱面) 数 × 每道扇区数 × 每扇区字节数
  • 细节:传动臂上的磁头是共进退的 (这点比较重要,后面会说明)

磁头(head),柱面(cylinder),扇区(sector),显然可以定位数据了,这就是数据定位 (寻址) 方式之一,CHS 寻址方式。

CHS 寻址:

对早期的磁盘非常有效,知道用哪个磁头,读取哪个柱面上的第几扇区就可以读到数据了。

但是 CHS 模式支持的硬盘容量有限,因为系统用 8bit 来存储磁头地址,用 10bit 来存储柱面地址,用 6bit 来存储扇区地址,而一个扇区共有 512Byte,这样使用 CHS 寻址一块硬盘最大容量

为 256 * 1024 * 63 * 512B = 8064 MB(1MB = 1048576B)(若按 1MB=1000000B 来算就是

8.4GB)

磁盘逻辑结构

上面我们都是从磁盘的物理结构进行看待的。这里从零开始,构建对磁盘 OS 级别的理解抽象。

文章配图

那么磁盘本质上虽然是硬质的,但是逻辑上我们可以把磁盘想象成为卷在一起的磁带,那么磁盘的逻辑存储结构我们也可以类似于:

文章配图

如何定位一个扇区呢?

文章配图

仔细一瞧,这不就是一维数组 sector_array[N] 吗,每个下标都存储着一个扇区。这样每一个扇区,就有了一个线性地址 (其实就是数组下标),这种地址叫做 LBA ( Logic Block Address).

磁道

某一盘面的某一个磁道展开:

文章配图

我们把一个磁面拉开抽象成一个线性结构,一个磁面就具有无数个扇区。而每个磁面的扇区总量是相等的,扇区总数是 s 一个扇区假设有 n 个磁道,这样每个磁道的扇区总个数都是 s/n.

文章配图

那如何通过 LBA 确定在物理结构的哪一个扇区呢?

假设一个磁面的扇区总数是 100,每个磁道的扇区总数是 10.此时 LBA:124,那么 124/100 就能确定是哪一个磁头,即确定哪一个磁面。124%100=24 即能确定该磁面有多少个扇区。

此时 24 / 10 = 2 就能确定是哪一个磁道 (柱面), 24%10=4 确定是该磁道的第 4 个扇区.

柱面

前面我们理解展开的时候,是以一面为单位进行展开的!但是,磁盘真实的展开,并不是以物理盘面展开的。是以"柱面"为单位进行展开的!

整个磁盘所有盘面的同一个磁道,即柱面展开:

文章配图

  • 柱面上的每个磁道,扇区个数是一样的
  • 这不就二维数组 sector_array[][]

而一个磁盘具有多个柱面,这不就意味着存在多个二维数组吗?不就是三维数组吗?

所以,寻址某个扇区:先找到哪一个柱面 (Cylinder) ,在确定柱面内哪一个磁面 (其实就是磁头位置,Head),在确定扇区(Sector),所以就有了 CHS 寻址。

文章配图


我们之前学过 C/C++的数组,在我看来,磁盘,就是一个以 sector 为单位的一维数组!!!

文章配图

所以,每一个扇区都有一个下标,我们叫做 LBA(Logical Block Address) 地址,其实就是线性地址。那么怎么计算得到这个 LBA 地址呢?

OS 只需要使用 LBA 就可以了!!LBA 地址转成 CHS 地址 (本质是:一维数组的下标,转换成为三个数字!!!),CHS 如何转换成为 LBA 地址。谁做啊??磁盘自己做!固件 (硬件电路,伺服系统)

CHS && LBA 地址

CHS 转成 LBA:

  • 磁头数*每磁道扇区数 = 单个柱面的扇区总数
  • LBA = 柱面号 C单个柱面的扇区总数 + 磁头号 H每磁道扇区数 + 扇区号 S - 1
  • 即:LBA = 柱面号 C*(磁头数每磁道扇区数) + 磁头号 H每磁道扇区数 + 扇区号 S - 1
  • 扇区号通常是从 1 开始的,而在 LBA 中,地址是从 0 开始的
  • 柱面和磁道都是从 0 开始编号的
  • 总柱面,磁道个数,扇区总数等信息,在磁盘内部会自动维护,上层开机的时候,会获取到这些参数。

LBA 转成 CHS:

  • 柱面号 C = LBA // (磁头数*每磁道扇区数)【就是单个柱面的扇区总数】
  • 磁头号 H = (LBA % (磁头数*每磁道扇区数)) // 每磁道扇区数
  • 扇区号 S = (LBA % 每磁道扇区数) + 1
  • "//": 表示除取整

所以:从此往后,在磁盘使用者看来,根本就不关心 CHS 地址,而是直接使用 LBA 地址,磁盘内部自己转换。

所以:从现在开始,磁盘就是一个 元素为扇区 的一维数组,数组的下标就是每一个扇区的 LBA 地址。OS 使用磁盘,就可以用一个数字访问磁盘扇区了。

引入文件系统

"块"概念

其实硬盘是典型的'块'设备,操作系统读取硬盘数据的时候,其实是不会一个个扇区地读取,这样效率太低,而是一次性连续读取多个扇区,即一次性读取一个'块'(block)。

硬盘的每个分区是被划分为一个个的'块'。一个'块'的大小是由格式化的时候确定的,并且不可以更改,最常见的是 4KB,就是 4096 字节,一个扇区占 512 个字节,那么就是有 4096/512=8 个扇区。即连续八个扇区组成一个'块'。'块'是文件存取的最小单位。

文章配图

注意:

  • 磁盘就是一个三维数组,我们把它看待成为一个"一维数组",数组下标就是 LBA,每个元素都是扇区
  • 每个扇区都有 LBA,那么 8 个扇区一个块,每一个块的地址我们也能算出来。
  • 知道 LBA:块号 = LBA / 8
  • 知道块号:LBA = 块号 * 8 + n. (n 是块内第几个扇区)

文章配图

至此,我们完成了对磁盘的完整建模的过程!!! 磁盘:本质就是一个 block array[N],块设备!!!

引入"分区"概念

其实磁盘是可以被分成多个分区(partition)的,以 Windows 观点来看,你可能会有⼀块磁盘并且将它分区成 C,D,E 盘。那个 C,D,E 就是分区。分区从实质上说就是对硬盘的一种格式化。但是 Linux 的设备都是以文件形式存在,那是怎么分区的呢?

柱面是分区的最小单位,我们可以利用参考柱面号码的方式来进⾏分区,其本质就是设置每个区的起始柱面和结束柱面号码。此时我们可以将硬盘上的柱面(分区)进行平铺,将其想象成一个大的平面,如下图所示:

文章配图

柱面大小一致,扇区个数一致,那么其实只要知道每个分区的起始和结束柱面号,知道每一个柱面多少个扇区,那么该分区多大,其实和解释 LBA 是多少也就清楚了.

引入"inode"概念

ext2 文件系统

为了能解释清楚 inode,在此之前,我们需要深入了解一下文件系统。

宏观认识

我们想要在硬盘上存储文件,必须先把硬盘格式化为某种格式的文件系统,才能存储文件。文件系统的目的就是组织和管理硬盘中的文件。在 Linux 系统中,最常见的是 ext2 系列的文件系统。(其早期版本为 ext2,后来又发展出 ext3 和 ext4。ext3 和 ext4 虽然对 ext2 进行了增强,但是其核心设计并没有发生变化,我们仍是以较老的 ext2 作为演示对象。)

ext2 文件系统将整个分区划分成若干个同样大小的块组 (Block Group),实际上就是一个块组对多个块和关键管理结构的组织形式。如下图所示。只要能管理一个分区就能管理所有分区,也就能管理所有磁盘文件。

文章配图

Super Block(超级块)

存放文件系统本身的结构信息,描述整个分区的文件系统信息。记录的信息主要有:block 和 inode 的总量,未使用的 block 和 inode 的数量,一个 block 和 inode 的大小,最近一次挂载的时间,最近一次写入数据的时间,最近一次检验磁盘的时间等其他文件系统的相关信息。Super Block 的信息被破坏,可以说整个文件系统结构就被破坏了.

GDT(Group Descriptor Table)

块组描述符表,描述块组属性信息,整个分区分成多个块组就对应有多少个块组描述符。每个块组描述符存储一个块组的描述信息,如在这个块组中从哪里开始是 inode Table,从哪里开始是 Data Blocks,空闲的 inode 和数据块还有多少个等等。块组描述符在每个块组的开头都有一份拷贝。

// 磁盘级 blockgroup 的数据结构
/* * Structure of a blocks group descriptor */
struct ext2_group_desc {
    __le32 bg_block_bitmap; /* Blocks bitmap block */
    __le32 bg_inode_bitmap; /* Inodes bitmap */
    __le32 bg_inode_table; /* Inodes table block*/
    __le16 bg_free_blocks_count; /* Free blocks count */
    __le16 bg_free_inodes_count; /* Free inodes count */
    __le16 bg_used_dirs_count; /* Directories count */
    __le16 bg_pad;
    __le32 bg_reserved[3];
};
Block Group

文章配图

那么该如何管理好一个小组 group 呢?

文章配图

在 ext2 文件系统中就有一个 Block Group,它里面含有 Super Block 超级块,Block 块和块的位图,inode 结点和 inode 位图以及 inode Table,最后就是 Data Blocks 数据块,里面就是存储着我们写的数据。接下来小编带着大家理解它们之中的含义以及联系。

Data Block

我们说过文件 = 文件内容 + 文件属性 -->都是数据 -->既然都是数据,那么都要存储

  1. Linux 中,文件的内容和属性是分开存储的!
  2. OS 文件系统中,和磁盘进行 I/O 的基本单位数:4KB

数据区:存放文件内容,也就是一个一个的 Block。根据不同的文件类型有以下几种情况:

  • 对于普通文件,文件的数据存储在数据块中。
  • 对于目录,该目录下的所有文件名和目录名存储在所在目录的数据块中,除了文件名外,ls -l 命令看到的其它信息保存在该文件的 inode 中。
  • Block 号按照分区划分,不可跨分区
  • 每一个数据块,都有唯一的编号

文章配图

既然每一个数据块,都有唯一的编号 -->一个组可能会存在多个文件,那么该如何确定该数据块是否被其他文件所占用了呢?

Block Bitmap

Block Bitmap 中记录着 Data Block 中哪个数据块已经被占用,哪个数据块没有被占用

  • 比特位的位置,表示对应哪一个数据块
  • 比特位的内容 [0,1],表示对应的数据块 [是否] 被占用
inode 结构体 (i 节点表)

还是因为文件 = 文件内容 + 文件属性。既然是数据,那么文件属性也需要存储。

那么 Linux 中,该如何表达文件属性呢?

struct inode{} 结构体!!!

struct inode 表示文件的属性 --> 其大小是固定的,一般是 128 或 256 字节,因为是一样的成员变量。换句话讲,任何文件,它们的 inode 结构体中包含多少种属性,是一样的,但是属性的内容不同!

扩展:OS 读取文件时,会读取 inode,并且一次是 4KB 读取。总共能读取多少个文件的 inode 呢?

41024 个字节,而一个 inode 大小是固定的,假设是 128.那么 41024/128=32 个文件的 inode

一般而言,一个文件一个 inode 一个文件,可能对应 0 或者多个 data block.那该如何标示这个文件的唯一性呢?

inode 结构体里有 inode number

并且在 Linux 中文件名不能也不在 inode 保存!!!(看似不符合我们的期望,放在后面讲解)

inode Table(i 节点表)
  • 存放文件属性 如 文件大小,所有者,最近修改时间等
  • 当前分组所有 Inode 属性的集合
  • inode 编号以分区为单位,整体划分,不可跨分区

文章配图

inode Bitmap

每个 bit 表示一个 inode 是否空闲可用.

  • 比特位得的位置:表示第几个 inode
  • 比特位的内容 [1/0]:表示对应的 inode,[是否] 被占用!
inode 和 datablock 映射 (弱化)
  • inode 内部存在 __le32 i_block[EXT2_N_BLOCKS];/ * Pointers to blocks */, EXT2_N_BLOCKS =15,就是用来进行 inode 和 block 映射的
  • 这样文件=内容 + 属性,就都能找到了。

文章配图

如果一个文件的内容不是很大,占的数据块不是很多。那么就用 12 个直接块指针,前 12 个映射的是内容,一个数据块占 4KB,那么就可以存 124KB=48KB 的数据。当文件内容过大时,就需要有一级、二级、三级间接块索引表指针:一级间接块索引表指针:inode 里有一个一级间接块指针,它指向一个'索引块'.这个索引块里存放的是更多的数据块指针,每个指针再指向实际的数据块。一个数据块能存 4KB,而每个块指针占 4B 字节,那么一个"索引块"就能存下 4KB/4B=1024 个指针,就能存下 10244KB=4MB 的数据。二级间接块索引表指针:inode 里还有一个二级间接块指针,它指向一个'二级索引块'.二级索引块里存放的是一级索引块的指针,每个一级索引块再指向实际数据块。一个二级"索引块"同样也是 4KB,存放着一级索引块的指针,就是 4KB/4B=1024 个一级索引块指针,那么就可以存放 102410244KB=4GB 的数据。三级间接块索引表指针:inode 里还有一个三级间接块指针,它指向一个'三级索引块'。三级索引块里存放的是二级索引块的指针,二级索引块再指向一级索引块,一级索引块再指向实际数据块。同理就可以存放 102410241024*4KB=4TB 的数据 (使得文件系统可以支持极大的单个文件,比如几十 GB 甚至更大)

总结:有一级、二级、三级间接指针,是为了让文件系统既能高效管理小文件,又能支持超大文件。

数据块的分配是全局有效的虽然磁盘被分成了多个'块组'(block group),每个组有自己的 inode table 和 data block 区域。但数据块编号(block number)是全局唯一的,不局限于某个组.

inode table 和 data block 的映射关系 inode 结构体中的数据块指针,指向的是全局编号的数据块。只要知道块号,就能定位到磁盘上的具体位置,无论它属于哪个组。

文件的数据块可以跨组分配当一个文件很大,或者本组的数据块用完时,文件的数据块可以分配到其他组的空闲块。也就是说,一个文件的数据块可以分布在磁盘的任意位置,不一定都在同一个块组里。

既然有 group 就会存在两种情况:

1.inode 用完,block 没用完这种情况下,你无法再在这个 group 里创建新文件或目录,因为没有多余的 inode 了。但这个 group 里的数据块还可以被其他 group 的文件使用(比如大文件跨组分配数据块)。常见于大量小文件的场景(比如邮件服务器、图片存储等)。

2.inode 没用完,block 用完无法再在这个 group 里为文件分配新的数据块,但还可以创建新文件(只要 inode 还有)。新文件的数据块可能会被分配到其他 group。常见于少量大文件的场景(比如视频、数据库等)。

总结与问题

总结:

经过前面学习,将来我们就可以先拿到文件的 inode 号,那么如何找到该文件的内容呢?只要通过 inode 编号,就能找到文件对应的 inode 属性,内部具有和数据块的对应关系,就能进一步找到文件的内容了!!

问题 1:Super Block 既然是描述一个分区的所有分组的整体情况,sb 为什么会在一个块组中???

超级块 (Super Block) 在每个块组的开头都有一份拷贝(第一个块组必须有,后面的块组可以没有)。为了保证文件系统在磁盘部分扇区出现物理问题的情况下还能正常工作,就必须保证文件系统的 super block 信息在这种情况下也能正常访问。为了实现上述目的,super block 不仅仅在一个组里,可能会同时存在在多个 block group 里!(不一定所有组都有,但是几乎多个组会同时存在同样的 super block).万一 super block 出了错误,多个组里面存多个 super block。即使搞坏了一个,可以用其他组的 super block 进行修复,是一种数据容灾的备份处理.

问题 2:新建一个分区,Super Block 和 GDT 一定是有效数据,为什么呢?

这是因为给特定分区写入管理信息,即写入文件系统和分区分组相关的的管理数据,对于文件数据可以暂时不用。(这不就相当于格式化吗!)

因此要使用一块硬盘:分区格式化 (给当前分区,写入文件系统)

问题 3:访问一个文件,在分区内,标识该文件的唯一性:inode 编号!!!新建一个文件:

在块组里查找 inode bitmap,找到一个为 0 的比特位,由 0 置 1,即申请 inode。就可以在 inode table 里申请一个 128 字节的空间。

通过 touch 一个新文件来看看如何工作。

创建一个新文件主要有以下 4 个操作:

  1. 存储属性

     内核先找到一个空闲的 i 节点(这里是 263466)。内核把文件信息记录到其中。
    
  2. 存储数据

     该文件需要存储在三个磁盘块,内核找到了三个空闲块:300,500,800。将内核缓冲区的第⼀块数据复制到 300,下一块复制到 500,以此类推。
    
  3. 记录分配情况

     文件内容按顺序 300,500,800 存放。内核在 inode 上的磁盘分布区记录了上述块列表。
    
  4. 添加文件名到目录

     新的文件名 abc。linux 如何在当前的目录中记录这个文件?内核将入口(263466,abc)添加到目录文件。文件名和 inode 之间的对应关系将文件名和文件的内容及属性连接起来。
    

删除一个文件:

拿着 inode 编号,在 Inode bitmap 找,确认是否有效,再通过 inode 编号读取 inode 结构,获取该文件的属性,判断文件的大小。如果不为 0,通过 inode 结构体内的数据块指针数组找到具体的数据块编号,计算在 Block Bitmap 的位置,由 1 置为 0,那么数据块就被释放了。

所以删除文件只改位图!!!→ 计算机删除数据,只要设置数据无效就行了 ->所以如果误删数据怎么办?啥都不做。修改文件:

修改文件无疑就是修改文件的内容或者属性。根据文件的 inode 编号找到 inode 结构体,接着检查文件的权限,如果不通过则返回权限错误。若通过,用 inode 结构体的数据块指针数组读取数据块,确认是否需要新的数据块,如果需要,则在 Block Bitmap 中查找为 0 的位置,申请 Data Block 数据块,更新 inode 数据块指针。再将数据写入到数据块中,更新 inode 元数据,最后同步元数据到磁盘中。查文件:

查文件和修改文件的逻辑是类似的,这里就不过多赘述。

问题 4:关于 inode 编号和 Data Block 编号 inode 是全分区统一分配的,不是只在分组内有效。inode 不能跨区域,一个分区,一个文件系统,互相独立!--> 即 inode 和 block 编号是在整个区有效

那么我们是如何通过 inode 确定 inode bitmap 在哪个位置的呢?

inode:1234 在 sb 中找到 block_per_group:1000,1234/1000 说明在块组 1 中;

找到 inode_per_group:1000,1234%1000 说明在 inode bitmap 中 234 位置中

目录与文件名

问题 5: 我们打开、删除、查找等操作都是通过文件名啊,那 inode 在哪存着呢?

        文件名不在 inode 结构体内部,应该在哪里呢?

该如何看待目录呢?

目录也是文件,目录 = 目录内容 + 目录属性。

而目录自己的 inode 就在属性中存着。

那么目录的文件名又在哪呢?

实际上是在上一级目录的内容中。

那么文件内容存储着文件名有啥用呢?甚至我们打开、删除、查找等操作都是通过文件名啊,是如何找到 inode 编号的?

目录的文件内容存的是文件名和 inode 编号的映射关系啊,只要有了文件名就能确定其 inode 编号。

结论:文件系统中,从存储方式角度,存储普通文件和目录,有区别吗?没有

下面这段代码验证:目录是否确实是存的文件名与 inode 编号的映射关系

所以,访问文件,必须打开当前目录,根据文件名,获得对应的 inode 号,然后进行文件访问

所以,访问文件必须要知道当前工作目录,本质是必须能打开当前工作目录文件,查看目录文件的内容!

由问题 5 我们就可以解决之前存在的未解决的问题:

为什么同一个目录下,文件名不能重复呢?

结论一:因为文件名和 inode 编号是具有映射关系的,重复的文件名确有多个 inode 编号,如何进行映射就是存在问题的,因此在同一目录下文件名不能重复。

结论二:在指定目录下,新建文件的本质:文件名->inode,写入到当前目录的 data block 里,这就是为什么在当前目录下新建文件,需要该目录具有'w'权限.

结论三:读取一个文件的属性的话,需要当前目录具有'r'权限,是因为如果不可读文件内容,就找不到文件名和 inode 编号的映射,,就不能确定 inode 编号,最终无法读取一个文件的属性。

总结来说结论二、三是对目录设置 rw 本质是约束用户,访问目录的 datablock

结论四:x 权限比较特殊:允许我们是否打开该目录!

路径解析

问题 6:为什么 Linux 访问文件,都必须带路径啊?但是我 pwd 指令又是如何得到路径的?

这就是为什么我们访问文件,本质是进程访问,进程具有 cwd 的根本原因!

这就是为什么,以前 open 文件的时候,必须要有路径的原因! 这就是为什么 Linux 下访问任意文件,都需要路径访问!

这就是为什么 linux 下,文件路径可以定位文件的根本原因!Linux 下访问文件,都必须带路径 (无论是显示的,还是隐式的!)

我们知道了:访问文件必须要有目录 + 文件名=路径的原因 (根目录固定文件名,inode 号,无需查找,系统开机之后就必须知道)

路径缓存

但这样也会出现一个问题,每次访问一个文件,都需要做路径解析,这样不是很慢吗? 实际上在 linux 系统里有一个目录树:

Linux 系统中,当用户访问指定路径下的文件 (包括路上目录,最终的目标文件在内)

Linux 会在进行路径解析的过程中,在内核中形成目录树和路径缓存! --> 目录结构是内存级的

路径缓存:在做路径解析的时候,只有第一次是慢的,第 2..n 次的时候,路径解析会优先从 dentry 树结构中进行解析!

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

注意:每个文件其实都要有对应的 dentry 结构,包括普通文件。这样所有被打开的文件,就可以在内存中形成整个树形结构整个树形节点也同时会隶属于 LRU(Least Recently Used,最近最少使用) 结构中,进行节点淘汰整个树形节点也同时会隶属于 Hash,方便快速查找更重要的是,这个树形结构,整体构成了 Linux 的路径缓存结构,打开访问任何文件,都在先在这棵树下根据路径进行查找,找到就返回属性 inode 和内容,没找到就从磁盘加载路径,添加 dentry 结构,缓存新路径

挂载分区

一个磁盘,必须分区格式化,才能具有使用的前提;

一个分区,要真正的使用,必须挂在到指定的目录才可以.

那该如何把一个分区挂载到指定的目录呢?

挂载到 / 目录下

dd 命令 : 二进制写入,制作一个大的文件,就当做一个分区.

格式化写入文件系统

建立空目录

查看可以使用的分区

将分区挂载到指定的目录

卸载分区

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

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

分区写入文件系统,无法直接使用,需要和指定的目录关联,进行挂载才能使用。

所以,可以根据访问目标文件的"路径前缀"准确判断我在哪一个分区。

扩展

那么 OS 是如何将数据写到磁盘的呢?

实际上不只 CPU 具有寄存器,外设同样也可以有寄存器。OS 对外设的控制,是通过对设备内部的寄存器进行数据写入的!

文章配图

文件系统总结

文章配图

文章配图

文章配图

本文从硬件到软件系统性地介绍了 Linux 下磁盘存储与文件系统的核心概念。首先讲解了机械磁盘的物理结构(磁头、磁道、柱面、扇区)和逻辑寻址方式(CHS 与 LBA 转换),指出操作系统通过 LBA 线性地址访问磁盘。其次详细阐述了文件系统的关键组件:超级块记录文件系统元信息,块位图管理数据块分配,inode 结构存储文件属性并通过多级索引映射数据块,目录则保存文件名与 inode 的映射关系。最后解释了文件访问路径解析机制(dentry 缓存)和分区挂载原理,揭示了 Linux 通过路径前缀确定分区的设计思想。全文由浅入深地构建了对磁盘存储体系的完整认知框架。

文章配图

目录

  1. 回顾基础 IO
  2. 理解硬件
  3. 磁盘物理结构
  4. 磁盘存储结构
  5. CHS 地址定位
  6. 磁盘逻辑结构
  7. 磁道
  8. 柱面
  9. CHS && LBA 地址
  10. 引入文件系统
  11. "块"概念
  12. 引入"分区"概念
  13. 引入"inode"概念
  14. ext2 文件系统
  15. 宏观认识
  16. Super Block(超级块)
  17. GDT(Group Descriptor Table)
  18. Block Group
  19. Data Block
  20. Block Bitmap
  21. inode 结构体 (i 节点表)
  22. inode Table(i 节点表)
  23. inode Bitmap
  24. inode 和 datablock 映射 (弱化)
  25. 总结与问题
  26. 目录与文件名
  27. 路径解析
  28. 路径缓存
  29. 挂载分区
  30. 扩展
  31. 文件系统总结
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • MusicFreeDesktop 开源音乐播放器跨平台与插件架构解析
  • FPGA 实时图像处理:从流水线架构到系统优化
  • 软体机器人动作捕捉系统:6 大主流方案深度测评与选型指南
  • Rasa 电商对话机器人 GLM-TTS 语音集成实战
  • ChatGPT 如何利用结构化方法实现高效信息管理
  • 基于腾讯混元 3D 大模型实现静态图片转 3D 模型教程
  • OpenClaw 智能体生态与移动端应用解析
  • NDK 开发入门:C++ 基础与 JNI 调用详解
  • 高校论文 AIGC 检测阈值与合规降重策略探讨
  • 使用 rclone 将远程 WebDAV 文件共享映射为本地硬盘
  • OpenClaw 结合 cpolar 实现本地 AI 服务外网访问教程
  • 在 Visual Studio Code 中配置 Anaconda 环境
  • Android 开发核心面试题汇总:Java、Kotlin、Flutter 及 Framework
  • Llama-2-7b在昇腾NPU上的六大核心场景性能基准报告
  • LLaMA Factory 微调时报 disable multiprocessing 错误解决方法
  • Python 异步编程:asyncio 核心原理与实战
  • 鸿蒙 HarmonyOS 6 混合开发:ArkWeb 加载机制与 Cookie 管理
  • 单片机与 FPGA 通信方式及 STM32 高速并行接口实现
  • Windows 系统下如何更新 npm 及 Node.js 至最新版本
  • 基于 OpenClaw 框架在 Discord 部署 AI 对话机器人实战指南

相关免费在线工具

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online

  • HTML转Markdown

    将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online

  • JSON 压缩

    通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online

  • JSON美化和格式化

    将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online