当前位置:

首页 > 软件教程 > 图解Linux文件系统结构与原理

图解Linux文件系统结构与原理

在之前的文章中,我曾从源码角度分析过Linux文件系统,但这种方式对于新手来说可能略显枯燥。所以,这次我将通过图文结合的方式,详细讲解Linux文件系统的原理,而不会深入到源代码的细节。一、硬盘简介在介绍文件系统之前,我们先来了解一下硬盘。众所周知,内存中的数据会在断电后丢失,因此现代计算机使用硬盘来存储数据。硬盘中的数据在断电后依然能够保存。目前,常见的硬盘类型包括机械硬盘(HDD)和固态硬盘(SSD)。由于本文的重点是文件系统,所以不会详细介绍硬盘的原理。以下是机械硬盘和固态硬盘的对比图:我们

本文目录

    在之前的文章中,我曾从源码角度分析过 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];    // 用于记录当前文件的文件名,由于文件名长度不固定,这里使用柔性数组表示
    };

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

    图解 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 文件系统的设计对理解其他不同的文件系统有非常大的帮助。

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系bd@zhengruan.com
    作者最新文章
    软件教程
    相关文章 更多
    怎么通过 LocalDate.toEpochSecond() 计算日期对应的 Unix 秒级时间戳
    怎么通过 LocalDate.toEpochSecond() 计算日期对应的 Unix 秒级时间戳

    LocalDate不含时间与时区,不能直接获取Unix时间戳。需要先调用atStartOfDay(ZoneId)方法,传入时区ID转为ZonedDateTime对象,再通过toInstant().getEpochSecond()获得对应的秒数。时区决定了最终结果,务必显式指定如Asia/Shanghai,避免依赖系统默认时区或夏令时影响,否则可能导致错误。

    C#怎么获取当前时间戳_C# DateTime与Unix时间戳转换【基础】
    C#怎么获取当前时间戳_C# DateTime与Unix时间戳转换【基础】

    C#获取Unix时间戳可将DateTime.UtcNow转为整数,但推荐使用DateTimeOffset.UtcNow的ToUnixTimeSeconds或ToUnixTimeMilliseconds方法。手动计算需指定DateTimeKind.Utc,互转时注意时区与精度截断。

    使用Samba,如何在客户机上显示中文
    使用Samba,如何在客户机上显示中文

    用Solaris 10自带的Samba 3.0.4,配置文件直接走/etc/sfw默认路径,在WinXP下访问倒是一切正常。可一开telnet终端上去,文件名全成了乱码——这就有点难受了。翻了下man手册才发现,unix charset默认用的UTF-8编码,跟中文环境对不上。解决办法很简单,在sm

    UNIX下VI编辑器使用
    UNIX下VI编辑器使用

    vi 编辑器核心命令速查 文本编辑器几乎是所有计算机系统里最常用的工具了。在 UNIX 环境下,编辑器有不少,比如 ex、sed,但用的人最多、流传最广的还得是 vi。vi 的命令确实繁杂,很多人刚上手时会觉得无从下手。下面这份整理涵盖了 vi 在三种模式下的核心命令,希望能帮大家快速上手,也欢迎补

    Unix时间戳异常返回0或极小值的排查与正确用法
    Unix时间戳异常返回0或极小值的排查与正确用法

    Go应用中time.Now().Unix()返回0或1969年日期,通常源于环境或代码问题。环境上,容器平台节点时钟未同步或故障是主因。代码中,错误使用string()转换int64时间戳会导致解析失败返回0。正确做法是直接使用Unix()获取秒级时间戳,或通过Format(time.RFC3339)格式化。排查时应优先检查节点时间服务状态,并避免用stri

    unix php,如何在Linux/Unix上安装PHP
    unix php,如何在Linux/Unix上安装PHP

    在Linux/Unix系统上安装PHP:一份详细的操作指南 如果你正计划在Linux或Unix系统上部署PHP,那么在动手之前,有几项准备工作是必须完成的。这就像盖房子前要打好地基一样,确保环境满足要求,后续的安装过程才能顺畅无阻。 具体来说,你需要准备好这几样东西:一个能与PHP协同工作的数据库(

    Linux系统入门指南与实用技巧
    Linux系统入门指南与实用技巧

    [TOC]0x00Linux发展史1.Linux前身Unix历史从unix中繁衍出了许多,现在大家耳熟能详的Linux发行版本:1969年以前,一个伟大的梦想Bell,MIT与GE的“Multics”系统。其目的是为了实现一台大型主机提供给300以上终端同时使用。由于缺乏资金Bell实验室退出了该计划。1969年,原“Multics”计划成员KenThomspon根据“Multics”,以汇编语言写出了第一个Unix原型,因为相对”Multics“来说,简化了许多,所以当时朋友称这个系统为”Uni

    网络服务器操作系统是什么?有哪些类型?
    网络服务器操作系统是什么?有哪些类型?

    无论是电脑还是手机,它们都离不开操作系统,操作系统可以对软件和硬件资源进行管理,并且能够执行特定的程序,用户打游戏、看电影以及聊天交友等,这些功能的实现都与操作系统存在联系。什么是网络服务器操作系统?能够被分为哪些类型?什么是网络服务器操作系统什么是网络服务器操作系统?先来解答这个问题,网络服务器操作系统的概念是很好理解的,它就是指大型计算机设备上安装的操作系统,包括数据库服务器以及Web服务器等等,它既可以为企业客户提供服务,也可以为个人用户带来价值,网络服务器操作系统可以被安装在个人电脑上,计算机与服

    编程的UNIX哲学原则
    编程的UNIX哲学原则

    1Unix哲学Unix哲学强调实用性,源自丰富经验,不受传统方法学或标准限制。这种知识更像是潜在的、半本能的。Unix程序员通过开发经验积累的知识可让其他程序员受益。(1)每个程序应专注于完成一项任务,遇到新任务时应重新开始,避免在原程序中添加新功能而导致复杂性增加。(2)假设程序的输出将成为另一个程序的输入,即使下一个程序尚不清楚,也应确保输出中不包含无关信息。(3)尽早将设计和编写的软件投入试用,对低质量代码应果断放弃并重新编写。(4)使用工具优先于低效的辅助手段来减轻编程任务的负担,精益求精,必须善

    typora怎么高亮 文本标记语法设置
    typora怎么高亮 文本标记语法设置

    本教程演示如何在 Windows 版 Typora 中开启 Highlight 高亮功能,通过双等号语法标记重点文本,并展示如何编辑、取消高亮及验证源码保存状态。

    查看更多
    精品专题 更多
    装机必备
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows
    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    PDF教程
    PDF教程

    正软商城PDF教程频道提供PDF编辑、转换、合并、拆分、压缩及格式处理方法,同时介绍常用PDF软件和工具的使用技巧。

    Mac软件 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    Aperty macOS版
    Aperty macOS版
    macOS

    Aperty 是 Skylum 推出的 AI 人像修图软件,支持自然肤质修饰、瑕疵处理、面部与身体调整、预设及批量同步。

    WINDOWS 更多
    讯飞智作 网页版
    讯飞智作 网页版
    Windows/ macOS/ Linux

    讯飞智作是一款基于语音合成技术、虚拟人驱动技术与数字人形象声音构建能力的 AI 数字人音视频创作平台。

    火山引擎 网页版
    火山引擎 网页版
    Windows/ macOS/ Linux

    火山引擎是字节跳动旗下企业级云与AI服务平台。聚焦大模型核心能力,依托字节自研豆包多模态大模型,凭借火山方舟一站式平台,提供模型精调、推理部署、智能应用搭建等全链路服务,结合高性能AI算力,助力各行业快速落地大模型数字化与智能化应用。

    PixTV 网页版
    PixTV 网页版
    Windows

    PixTV 是一款在浏览器中使用的 AI 视觉内容创作平台,提供图片、视频、音频、文字生成、AI 分镜、局部重绘、提示词反推和无限画布等工具,适合短剧、漫剧、广告及社交媒体内容制作。