当前位置: 首页 > news >正文

【Linux】Ext系列文件系统

📝前言:

这篇文章我们来理解一下Linux文件系统

🎬个人简介:努力学习ing
📋个人专栏:Linux
🎀CSDN主页 愚润求学
🌄其他专栏:C++学习笔记,C语言入门基础,python入门基础,C++刷题专栏


这里写目录标题

  • 一,理解硬件
    • 1. 物理结构
    • 2. 逻辑结构
  • 二,文件系统
    • 1. 文件系统基本概念
    • 2. ext2 文件系统
      • 块组内部构成
        • Data Blocks
        • inode table
        • Block / inode Bitmap
        • GDT
        • Super Block
    • 3. 理解一
    • 4. 目录与文件名及路径解析
    • 5. 路径缓存
    • 6. 挂载分区
    • 7. 总结
  • 三,软硬链接
    • 1. 软链接
    • 2. 硬链接

一,理解硬件

在学习文件系统之前,我们需要先了解一下磁盘这个机械外设,在这里我不过多讲解,可能看看这篇文章。我提取并补充一些重要的知识:

1. 物理结构

物理结构基本了解:

  • 磁头用于在磁盘上寻址(定位磁道和定位扇区),所有磁头由机械臂杆控制,是共进退的
  • 往磁盘写入,本质上就是在改变盘片上“颗粒”(最小存储单元)的南北极 / 高低电平…(这些具有两态性的,能表示 0 / 1的)
  • 扇区:是磁盘存储数据的基本单位,512字节,块设备
    • 如果要改一个扇区的一个bit位,OS都得把一整个扇区的512个字节全部加载到内存里,修改完那一个bit后再写回
    • 如何寻找扇区(CHS定址方法)
      • 磁头先选柱面(Cylinder)
      • 再确定是哪一个盘面上的磁头(Head)
      • 然后等待磁盘旋转,等到对应扇区(Sector)转到在磁头下
  • 磁盘容量 = 磁头数 × 磁道(柱⾯)数 × 每道扇区数 × 每扇区字节数

2. 逻辑结构

逻辑结构基本了解:

  • 某⼀个磁道展开,是一个一维数组
  • 某一柱面的所有磁道展开,是一个二维数组(每一行是一个磁道)
  • 把整个磁盘的所有柱面展开,是一个三维数组(每一层是一个柱面)
  • 又因为,三维数组在物理存储中,本质上是连续(线性)存储的(约等于还是一位数组存储),所以我们可以直接用数组下标来得到某一扇区的地址,即:LBA地址
  • OS使用 LBA地址,交给磁盘以后,磁盘自动把LBA 转换成CHS地址然后搜索对应扇区

二,文件系统

我们想要在硬盘上储⽂件,必须先把硬盘格式化为某种格式的文件系统,才能存储文件。文件系统的⽬的就是组织和管理硬盘中的文件

1. 文件系统基本概念

  • 磁盘是“块”设备
  • OS在读取磁盘文件的时候,会一次性读取多个扇区(因为磁盘太慢了),即:一个“块”
  • ⼀个”块”的大小是由格式化的时候确定的,常见的是4KB为一块

分区

  • 我们将一个盘,进行分区。把管理一个盘变成 → 管理多个区,区与区之间又可以用相同的管理方法
  • 同样,分区又被分成组(分区和分组的方式,也是通过记录起始位置和结束位置来划分,每个组的大小一样)

在这里插入图片描述

inode(索引节点):

  • 用于存储文件的元数据信息,包括指向文件对应的数据块的指针
  • 通过 inode,系统可以快速获取文件的属性信息,而无需扫描整个文件系统来查找文件的相关信息
  • 文件名不存储在inode中,但是inode会存储inode_number来标识文件
  • inode_number可以跨组编号,但是不能跨区编号。即:一个组内不能出现同一个编号(一个区内编号唯一),但是不同区内可以出现同一编号
  • 每个文件的基本属性项是相同的(如,都有typesize…),对应的值不同。所以每个struct inode的大小是一样的

2. ext2 文件系统

只要我们管理好一个组,就相当于管理好了一片区,就相当于管理好了一个盘。所以下面我们对每个组的结构进行了解
在这里插入图片描述

块组内部构成

Data Blocks
  • 数据区:存放文件内容
  • 一个文件通过inode里的指针可以找到对应的数据块
  • 如果一个文件过大,一个块(4KB)存不下,可以建立多级索引表,即块中存储指向别的块的指针,从而增大容量(并且可以跨组,但是不能跨区)
  • Block 号按照分区划分,不可跨分区

在这里插入图片描述

inode table
  • 用来存储该组内,所有文件的inode信息
  • inode table如果一块(4KB)不够用,也可以建立多级索引表
  • inode编号以分区为单位,整体划分,不可跨分区
Block / inode Bitmap
  • Block Bitmap:记录着 Data Block 中哪个数据块已经被占用,哪个数据块没有被占用
  • inode Bitmap:每个 bit 表示⼀个 inode 是否空闲可用
  • 文件的删除操作,无序删除data block里面数据块的内容,只需要改变block bitmap 和 inode bitmap 1 → 0就行,代表可用,下次就会覆盖写了。(格式化就是全置 0 了)
GDT
  • 块组描述符表,描述块组属性信息,整个分区分成多个块组就对应有多少个块组描述符
  • 每个块组描述符存储⼀个块组 的描述信息,如在这个块组中从哪里开始是inode Table,从哪⾥开始是DataBlocks,空闲的inode和数据块还有多少个等等。块组描述符在每个块组的开头都有⼀份拷贝
Super Block
  • 存放⽂件系统本⾝的结构信息,描述整个分区的文件系统信息
  • 不是所有的group里面都有super block,部分有,且这些super block的内容都一样
    • 为什么存多份?用于备份(因为super block是用来描述整个分区的,如果损坏了,那整个分区就乱了)

操作系统开机时,就会把磁盘的管理信息super block加载到内存里。而GDTBlock Bitmapinode Bitmap(是按需加载)

3. 理解一

我们捋一遍访问的过程:
当我们拿到文件inode_number的时候,就可以到对应的块组的inode table里面找到对应的struct inode,然后通过struct inode可以知道文件对应的属性,以及有了指向数据块的指针,也可以拿到数据。这时候就成功访问了对应的文件。

但是inode_number怎么得到呢?通过目录。

4. 目录与文件名及路径解析

  • 在Linux中,目录也是文件
  • 目录的内容,存储的就是当前目录下,普通文件的文件名和它的inode_number的映射关系
  • 我们访问一个文件的时候必须带路径(绝对 / 相对 / 默认):
    • 我们直接使用文件名:本质还是用的当前路径 + 文件名
    • 因为如果要找到一个文件的inode_number必须到上层目录的内容里面查找映射关系
    • 所以我们要访问任何一个文件,都需要从根目录开始,层层解析,直到在我们要访问的文件的目录里找到inode_number(这就是Linux路径解析)
  • 根目录是在开机的时候就自动打开的

一条命令ls code.c,路径都是由谁提供的?

  • ls的路径由系统提供:进程通过env找到PTAH默认路径
  • code.c的命令用户提供:即当前的相对路径

5. 路径缓存

访问任何⽂件,都要从/目录开始重新进行路径解析吗?
答:

  • 不是
  • 因为这样太慢。每次在目录里面找映射关系,也是对磁盘的IO,访问外设太慢。
  • 所以,Linux会缓存历史路径结构(用 dentry 树,用于维护树状路径结构)。

dentry树(内存数据结构):

  • 每个文件名(普通文件和目录)对应一个 dentrydentrystruct file里,dentry里面存储了指向对应文件inode的指针
  • 这些struct dentry会被系统用一颗树组织起来
  • dentry节点同时也会属于LRU(最近最少使⽤)结构中,用于淘汰。会属于Hash结构,方便快速查找
  • dentry树,整体构成了Linux的路径缓存结构。
    • 访问任何⽂件,都在先在dentry树下根据路径进行查找,找到了就可以通过里面的指针找到对应的inode
    • 没找到就从磁盘加载路径,添加dentry结构,缓存新路径

6. 挂载分区

我可以用inode_number的在一个分区内找到对应文件的inode,但是我们怎么知道它属于哪个分区呢?

  • 分区写入文件系统,无法直接使用,需要和指定的目录关联,进行挂载才能被用户访问。
  • 通过挂载点,我们就可以知道这个文件属于哪个分区(即:可以根据访问⽬标⽂件的 路径前缀 准确判断我在哪⼀个分区。)
  • 如:将 /dev/sda1 挂载到 /mnt/data
    • mount /dev/sda1 /mnt/data
    • 挂载后,访问 /mnt/data 目录实际上就是访问 /dev/sda1 分区的内容,我们就知道是哪个分区了

7. 总结

在这里插入图片描述
在这里插入图片描述
图片来自:极客时间趣谈操作系统

三,软硬链接

1. 软链接

  • 软连接是创建了独立的文件
  • 语法:
 ln -s [源文件或目录] [目标软链接文件或目录]
  • 例如,要为当前目录下的file.txt文件创建一个名为file_link.txt的软链接
ln -s file.txt file_link.txt
  • 建立好以后,运行file_link.txt == 运行file.txt(相当于file_link.txtfile.txt的快捷方式)

示例:

当前目录下建立软链接:
在这里插入图片描述
建立一个软链接在上级目录:
在这里插入图片描述

  • 路径一定要写清楚
  • 如果链接成:b.exe -> a.exe,则你在b.exe的目录下运行b.exe的时候,也是去当前目录下找a.exe

2. 硬链接

语法:

 ln [源文件或目录] [目标软链接文件或目录]
  • 硬链接不是独立的文件,硬链接只是⽂件名和目标文件inode的映射关系
  • ...就是硬链接
  • 硬链接可以用于文件备份
  • 但是,用户不能给目录进行硬链接,只有Linux系统可以(如...,因为怕用户乱链接,形成文件呢路径环问题)

示例:

在这里插入图片描述

  • ls -li:可以查文件inode_number
  • 可见,a.exe,文件权限后面的数字为2,代表硬链接数为2

🌈我的分享也就到此结束啦🌈
要是我的分享也能对你的学习起到帮助,那简直是太酷啦!
若有不足,还请大家多多指正,我们一起学习交流!
📢公主,王子:点赞👍→收藏⭐→关注🔍
感谢大家的观看和支持!祝大家都能得偿所愿,天天开心!!!

相关文章:

  • 鸿蒙-5.1.0-release构建编译环境
  • Oracle中的select1条、几条、指定范围的语句
  • 每日算法-250514
  • 【golang】网络数据包捕获库 gopacket
  • 嵌入式系统中WAV音频文件格式详解与处理实践
  • 【CustomPagination:基于Vue 3与Element Plus的高效二次封装分页器】
  • Lightpanda开源浏览器:专为 AI 和自动化而设计的无界面浏览器
  • 安卓基础(Bitmap)
  • scons user 3.1.2
  • C#强类型枚举的入门理解
  • C++【STL】(2)string
  • 4级流程控制
  • 复现:DemoGen 用于数据高效视觉运动策略学习的 合成演示生成 (RSS) 2025
  • Docker 常见问题及其解决方案
  • nginx报错-[emerg] getpwnam(“nginx“) failed in /etc/nginx/nginx.conf:2
  • FastAPI + OpenAI 模型 的 GitHub 项目结构模板
  • 未来软件开发趋势与挑战
  • Python+Selenium爬虫:豆瓣登录反反爬策略解析
  • C#调用C++dll 过程记录
  • 【VS】VS2019中使用rdlc报表,生成之前修改XML
  • 秦洪看盘|指标股发力,A股渐有突破态势
  • 遭“特朗普关税”冲击,韩国今年经济增长预期“腰斩”降至0.8%
  • 崔登荣任国家游泳队总教练
  • 杭勇已任常州市政协党组成员,此前任常州市委常委、秘书长
  • AI含量非常高,2025上海教育博览会将于本周五开幕
  • 经济日报:美国滥施汽车关税损人不利己