0

0

图解 Linux 文件系统

看不見的法師

看不見的法師

发布时间:2025-10-07 10:03:01

|

351人浏览过

|

来源于php中文网

原创

在之前的文章中,我曾从源码角度分析过 linux 文件系统,但这种方式对于新手来说可能略显枯燥。所以,这次我将通过图文结合的方式,详细讲解 linux 文件系统的原理,而不会深入到源代码的细节。

一、硬盘简介

在介绍文件系统之前,我们先来了解一下硬盘。

众所周知,内存中的数据会在断电后丢失,因此现代计算机使用硬盘来存储数据。硬盘中的数据在断电后依然能够保存。

目前,常见的硬盘类型包括机械硬盘(HDD)和固态硬盘(SSD)。由于本文的重点是文件系统,所以不会详细介绍硬盘的原理。以下是机械硬盘和固态硬盘的对比图:

图解 Linux 文件系统

我们可以将硬盘想象成一个巨大的数组,每个元素代表一个数据块,如下图所示:

图解 Linux 文件系统

在 Linux 内核中,每个数据块的大小定义为 4KB。因此,一个 128GB 的硬盘可以被划分为 33554432 个数据块,内核通过数据块的编号来进行读写操作。

二、什么是文件系统

前面提到,内核通过数据块来读写硬盘,但这种方式对人类来说并不直观,因为我们无法记住每个数据块存储的内容。

为了让用户使用起来更方便和直观,Linux 内核抽象出两个概念来管理硬盘中的数据:文件(File)和目录(Directory)。

文件用于存储数据,目录用于存储文件列表,当然,目录也可以包含其他目录。由于数据存储在硬盘的数据块中,文件只需要记录哪些数据块属于它即可。如下图所示:

图解 Linux 文件系统

从图中可以看出,目录可以包含文件和子目录,而文件则记录了属于它的数据块编号。因此,读取或写入文件时,只需找到对应的文件数据块即可。

三、MINIX 文件系统实现

现在,我们以 MINIX 文件系统为例,详细介绍文件系统的设计原理。由于 MINIX 文件系统结构简单,非常适合用于教学。

  1. MINIX 文件与目录

在 MINIX 文件系统中,一个文件由 minix2_inode 对象描述。我们来看一下 minix2_inode 的定义:

struct minix2_inode {
    __u16 i_mode;     // 模式
    __u16 i_nlinks;   // 链接数
    __u16 i_uid;      // 所属用户UID
    __u16 i_gid;      // 所属组ID
    __u32 i_size;     // 文件大小
    __u32 i_atime;    // 访问时间
    __u32 i_mtime;    // 修改时间
    __u32 i_ctime;    // 创建时间
    __u32 i_zone[10]; // 文件对应的数据块编号
};

我们需要特别关注 minix2_inode 对象中的 i_zone 字段,它记录了属于当前文件的数据块编号。从定义来看,i_zone 是一个包含 10 个元素的整数数组。那么,是否意味着 MINIX 文件只能存储 40 KB 的数据呢?

答案是否定的。MINIX 文件系统将 i_zone 数组分为四个部分:前 7 个元素直接指向存储数据的数据块编号,第 8 个元素是一级间接指向,第 9 个元素是二级间接指向,第 10 个元素是三级间接指向。我们通过下图来解释这种关系:

图解 Linux 文件系统

通过这种多级指向的方式,一个 MINIX 文件可以存储超过 40KB 的数据。

既然有描述文件的对象,那么也应该有描述目录的对象。在 MINIX 文件系统中,目录也使用 minix2_inode 对象来描述。那么,如何区分文件和目录呢?

minix2_inode 对象中,有一个名为 i_mode 的字段,它保存了 minix2_inode 对应的类型。普通文件使用 S_IFREG 标志表示,而目录使用 S_IFDIR 标志表示。因此,从本质上来说,目录也是一种特殊的文件。

普通文件的数据块存储的是文件的数据,那么目录的数据块存储的是什么呢?答案是文件列表,每个表项使用 minix_dir_entry 对象表示,定义如下:

struct minix_dir_entry {
    __u16 inode;     // 当前文件对应的 minix2_inode 对象在 inode 数组中的索引
    char name[0];    // 用于记录当前文件的文件名,由于文件名长度不固定,这里使用柔性数组表示
};

我们通过下图来展示文件与目录在数据内容上的区别:

AMiner
AMiner

AMiner——新一代智能型科技情报挖掘与服务系统,能够为你提供查找论文、理解论文、分析论文、写作论文四位一体一站式服务。

下载

图解 Linux 文件系统

上图展示了文件与目录的两个明显区别:

  • 文件的 i_mode 字段设置为 S_IFREG,而目录的 i_mode 字段设置为 S_IFDIR
  • 文件的 i_zone 字段指向的数据块存储的是文件的数据,而目录的 i_zone 字段指向的数据块存储的是文件列表。
  1. MINIX 文件系统格式化

现在,我们基本了解了 MINIX 文件系统对文件与目录的存储方式,接下来介绍 MINIX 文件系统如何管理硬盘中的文件和目录,也就是我们常说的格式化。

我们可以将硬盘视为一个由数据块组成的巨大数组,MINIX 文件系统将硬盘划分为以下几个部分,如下图所示:

图解 Linux 文件系统

下面我们对这几个部分进行解释:

  • 引导块:占用一个数据块,用于操作系统启动时使用,我们可以忽略。
  • 超级块:占用一个数据块,用于保存文件系统的信息,MINIX 文件系统使用 minix_super_block 对象来保存文件系统的信息,如 inode位图 占用几个数据块、数据块位图 占用几个数据块等。
  • inode位图:占用若干个数据块,用于描述 inode表 中哪些成员已经被使用,每个位表示一个 inode 的使用情况。
  • 数据块位图:占用若干个数据块,用于描述 数据块列表 中哪些成员已经被使用,每个位表示一个数据块的使用情况。
  • inode表:占用若干个数据块,由多个 minix2_inode 对象组成,每个 minix2_inode 对象表示一个文件或目录。
  • 数据块列表:占用若干个数据块,用于保存文件的数据。

上图展示了 MINIX 文件系统在硬盘中的格式化结构。我们先来看一下 超级块 记录的信息有哪些,超级块由 minix_super_block 对象表示,其定义如下:

struct minix_super_block {
    __u16 s_ninodes;       // inode表的元素个数
    __u16 s_nzones;        // 数据块列表的元素个数(v1版本)
    __u16 s_imap_blocks;   // inode位图占用的数据块数量
    __u16 s_zmap_blocks;   // 数据块位图占用的数据块数量
    __u16 s_firstdatazone; // 第一个数据块起始号
    __u16 s_log_zone_size;
    __u32 s_max_size;      // 文件最大尺寸
    __u16 s_magic;         // 魔数(用于识别MINIX文件系统)
    __u16 s_state;         // 文件系统状态
    __u32 s_zones;         // 数据块列表的元素个数(v2版本)
};

minix_super_block 每个字段的作用都在注释中进行了说明,通过 minix_super_block 对象我们可以了解到 MINIX 文件系统的信息。

  1. 读取文件过程

了解了 MINIX 文件系统的结构组织,现在我们介绍一下 MINIX 文件系统读取文件的过程。

例如,我们要读取 /home/file.txt 文件的内容,MINIX 文件系统是如何准确地找到文件并读取其中的内容呢?下面我们分步描述这个过程。

第一步:读取根目录

要读取 /home/file.txt 文件,首先要从根目录 / 开始。MINIX 文件系统约定根目录使用 inode表 的第一个元素进行存储。如下图:

图解 Linux 文件系统

如上图所示,根目录使用 inode表 的第一个元素进行存储,然后从根目录的文件列表中查找目录 home。从图中可以看出,home 目录的 inode索引 为 5,表示 home 目录存储在 inode表 的第 5 个元素中。

第二步:读取 home 目录

知道 home 目录的 inode索引 为 5 后,再读取 inode表 的第 5 个元素,然后从 home 目录的文件列表中查找文件 file.txt,过程如下图:

图解 Linux 文件系统

如上图所示,从 home 目录的文件列表中找到 file.txt 文件的 inode索引 为 9,所以现在可以通过读取 inode表 的第 9 个元素来获得 file.txt 文件对应的 inode 节点。

第三步:读取 file.txt 文件的内容

现在我们已经知道了 file.txt 文件对应的 inode索引,所以从 inode表 中读取第 9 个元素即可获得 file.txt 文件的 inode节点,然后就可以通过 inode节点i_zone 字段所指向的数据块来读取文件的内容,如下图所示:

图解 Linux 文件系统

如上图所示,通过读取 inode表 的第 9 个元素获得 file.txt 文件的 inode节点 后,可以通过 inode节点i_zone 字段所指向的数据块读取文件的内容。

四、总结

本文通过 MINIX 这种简单的文件系统来介绍如何设计一个文件系统。虽然 Linux 系统有多种文件系统,但其基本思想都是如何有效地管理硬盘的数据。因此,掌握 MINIX 文件系统的设计对理解其他不同的文件系统有非常大的帮助。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
磁盘配额是什么
磁盘配额是什么

磁盘配额是计算机中指定磁盘的储存限制,就是管理员可以为用户所能使用的磁盘空间进行配额限制,每一用户只能使用最大配额范围内的磁盘空间。php中文网为大家提供各种磁盘配额相关的内容,教程,供大家免费下载安装。

1564

2023.06.21

如何安装LINUX
如何安装LINUX

本站专题提供如何安装LINUX的相关教程文章,还有相关的下载、课程,大家可以免费体验。

716

2023.06.29

linux find
linux find

find是linux命令,它将档案系统内符合 expression 的档案列出来。可以指要档案的名称、类别、时间、大小、权限等不同资讯的组合,只有完全相符的才会被列出来。find根据下列规则判断 path 和 expression,在命令列上第一个 - ( ) , ! 之前的部分为 path,之后的是 expression。还有指DOS 命令 find,Excel 函数 find等。本站专题提供linux find相关教程文章,还有相关

300

2023.06.30

linux修改文件名
linux修改文件名

本专题为大家提供linux修改文件名相关的文章,这些文章可以帮助用户快速轻松地完成文件名的修改工作,大家可以免费体验。

800

2023.07.05

linux系统安装教程
linux系统安装教程

linux系统是一种可以免费使用,自由传播,多用户、多任务、多线程、多CPU的操作系统。本专题提供linux系统安装教程相关的文章,大家可以免费体验。

587

2023.07.06

linux查看文件夹大小
linux查看文件夹大小

Linux是一种自由和开放源码的类Unix操作系统,存在着许多不同的Linux版本,但它们都使用了Linux内核。Linux可安装在各种计算机硬件设备中,比如手机、平板电脑、路由器、视频游戏控制台、台式计算机、大型机和超级计算机。linux怎么查看文件夹大小呢?php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

570

2023.07.20

linux查看ip命令
linux查看ip命令

本专题为大家提供linux查看ip命令相关文章内容,感兴趣的朋友可以免费下载体验试试。

314

2023.07.20

linux查看cpu使用率
linux查看cpu使用率

在linux的系统维护中,可能需要经常查看cpu使用率,分析系统整体的运行情况。本专题为大家带来了linux查看cpu使用率的相关文章,感兴趣的朋友千万不要错过了。

400

2023.07.25

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

3

2026.03.11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL 教程
PostgreSQL 教程

共48课时 | 10.5万人学习

swoole入门物联网开发与实战
swoole入门物联网开发与实战

共15课时 | 1.3万人学习

swoole项目实战(第二季)
swoole项目实战(第二季)

共15课时 | 1.3万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号