【Linux】Ext系列文件系统

📝前言:

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

🎬个人简介:努力学习ing

📋个人专栏:Linux

🎀CSDN主页 愚润求学

🌄其他专栏:C++学习笔记C语言入门基础python入门基础C++刷题专栏


这里写目录标题

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

  • 软连接是创建了独立的文件
  • 语法:
cpp 复制代码
 ln -s [源文件或目录] [目标软链接文件或目录]
  • 例如,要为当前目录下的file.txt文件创建一个名为file_link.txt的软链接
cpp 复制代码
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. 硬链接

语法:

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

示例:

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

🌈我的分享也就到此结束啦🌈

要是我的分享也能对你的学习起到帮助,那简直是太酷啦!

若有不足,还请大家多多指正,我们一起学习交流!

📢公主,王子:点赞👍→收藏⭐→关注🔍

感谢大家的观看和支持!祝大家都能得偿所愿,天天开心!!!

相关推荐
欧先生^_^1 小时前
Linux内核可配置的参数
linux·服务器·数据库
若风的雨2 小时前
【deekseek】P2P通信路由过程
服务器·网络协议·p2p
海尔辛2 小时前
学习黑客5 分钟读懂Linux Permissions 101
linux·学习·安全
Python私教2 小时前
征服Rust:从零到独立开发的实战进阶
服务器·开发语言·rust
王RuaRua3 小时前
[数据结构]5. 栈-Stack
linux·数据结构·数据库·链表
曼岛_3 小时前
[架构之美]linux常见故障问题解决方案(十九)
linux·运维·架构
tan180°3 小时前
Linux进程信号处理(26)
linux·c++·vscode·后端·信号处理
大神的风范3 小时前
从0开始学linux韦东山教程第三章问题小结(4)
linux·服务器
sz66cm4 小时前
Linux基础 -- SSH 流式烧录与压缩传输笔记
linux·笔记·ssh
YOYO--小天4 小时前
RS485和RS232 通信配置
linux·嵌入式硬件