Linux Ext系列文件系统

前言

本章重点:

1.理解磁盘物理结构

2.掌握CHS和LBA地址

3.掌握Ext系列文件系统原理

4.理解分区、格式化、路径解析、挂载等过程和操作

5.理解软硬链接和使用

一、理解硬件

1.1 磁盘、服务器、机柜、机房

磁盘我们这里讨论的是机械磁盘:

机械磁盘是计算机中唯一的一个机械设备

磁盘是外设

磁盘的特点有:慢、容量大、价格便宜

机房是最大的物理空间,里面放满了机柜;机柜里插满了服务器;服务器里装着磁盘

1.2 磁盘物理结构

1.3 磁盘的存储结构

扇区: 是磁盘存储数据的基本单位,512字节,块设备

每个磁道都被分为很多的扇形区域,每道的扇区数量相同(现代也可能不相同)

磁头不直接与磁盘接触,而是在磁盘表面上一层薄薄的气垫上飞翔

磁头左右摆动的本质是在定位磁道

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

扇区的定位:

①:首先是选择磁头(header)

②:选择磁道(cylinder)

③:选择扇区(sector)

这种方法叫做CHS地址定位

扇区是从磁盘读出和写入信息的最小单位,通常大小为512字节

磁头数:每一个盘片一般有上下两面,分别对应一个磁道,共两个磁道

磁道数:磁道是从盘片外圈往内圈编号,靠近主轴的同心圆用于停靠磁头,不存储数据

柱面数:磁道构成柱面,数量上等于磁道数

扇区数:每个磁道被切分成很多扇形区域,一般来说每一道的扇区数量相同

圆盘数:就是盘片的数量

磁盘容量= 磁头数 * 柱面数(也是磁道数) * 每道扇区数 * 每个扇区的字节数

知道了柱面、磁头、扇区,显然就可以定位数据了,这就是数据定位(寻址)方法之一,叫做CHS寻址方式

1.4 磁盘的逻辑结构

1.4.1 理解过程

类比磁带,我们知道磁带就是一圈圈围起来的

磁带上可以存储数据,我们可以把磁带拉直,形成线性结构、

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

这样每一个扇区就有了一个线性地址(也就是数组下标),这种地址叫做LBA

1.4.2 真实过程

事实上,传动臂上的磁头是共进退的

柱面是一个逻辑上的概念,其实就是每一个面上,相同半径的磁道逻辑上构成柱面

所以,磁盘物理上分了很多面,但是在我们看来,逻辑上,磁盘整体是由柱面j卷起来的

真实情况是:

某一盘面的某一个磁道展开:是一个一位数组

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

柱面展开就是二维数组了

那么整盘展开呢?

整个磁盘就是多张二维的扇区数组表(也就是三维数组)

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

我们学习C/C++,我们知道不管是几维数组其实全部都是一维数组(在内存中这样存储)

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

OS只需要LBA就可以,LBA地址转成CHS地址,CHS转换成LBA是磁盘自己来做

1.5 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

二. 引入文件系统

2.1 引入"块"概念

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

磁盘的每一个分区是被划分为一个个"块",一个块的大小是由格式化的时候确定的,并且不可以更改,最常见的是4KB,即连续八个扇区组成一个块,"块"是文件存取的最小单位

注意:

①:磁盘就是一个三维数组,我们把它看待成一个"一维数组",数组下标就是LBA,每一个元素都是扇区

②:每个扇区都有LBA,那么8个扇区一个块,每一个块的地址我们也可以算出来

③:知道LBA :块号= LBA / 8

④:知道块号:LBA= 块号*8 + n(n是块内第几个扇区)

2.2 引入"分区"概念

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

柱面是分区的最小单位,我们可以参考柱面号码的方式来进行分区,其本质就是设置每个区 其实柱面和结束柱面号码,此时我们可以将硬盘上的柱面(分区)进行平铺,将其想象成一个大的平面

2.3 引入"inode"概念

文件 = 属性 + 数据,使用ls -l的时候看到的除了文件名,还能看到数据(属性)

展示出来的包含七列:

分别是模式、硬件链接、文件所有者、组、大小、最后修改时间、文件名

ls -l 读取存储在磁盘上的文件信息,然后显示出来

我们还可以使用stat命令来读取,可以看到更多的信息:

我们要思考一个问题,文件数据都存储在"块"中,那么显然我们还要找到一个地方存储文件的元信息(属性信息),这种存储元信息的区域就是inode,"索引节点"

每一个文件都有对应的inode,里面包含了与该文件相关的一些信息

Linux下文件的存储是属性和内容分离存储的

Linux下,保存文件属性的集合叫做inode,一个文件一个inode,inode内有一个唯一的标识符叫做inode号

我们已经知道硬盘是典型的"块"设备,操作系统读取硬盘数据的时候,读取的基本单位是"块",块又是硬盘每个分区下的结构,难道每个块是随意在分区上排布的吗,怎么找到块呢?

上面提到的存储文件属性的inode又是怎么放置的?

三、Ext2文件系统

3.1 宏观认识

想要在硬件上存储文件,**必须先把硬盘格式化为某种格式的文件系统,才能存储文件,文件系统的目的就是组织和管理硬盘中的文件,**在Linux系统中最常见的是Ext2系列的文件系统

ext2 文件系统将整个分区划分为若干个同样大小的块组(Block Group),只要能管理一个分区就能管理所有分区,也就能管理所有磁盘文件

上图中启动块(Boot Block/Sector)的大小是确定的,为1KB,又PC标准规定,用来存储磁盘分区信息和启动信息,任何文件系统都不能修改启动块,启动块之后才是ext2文件系统的开始

3.2 Block Group

ext2 文件系统或根据分区的大小划分为数个Block Group,而每个Block Group 都有着相同的结构组成

3.3 块内部构成

3.3.1 超级块(super Block)

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

超级块在每个块组的开头都有一份拷贝(第一个块组必须有,后面的块组可以没有)。 为了保证文 件系统在磁盘部分扇区出现物理问题的情况下还能正常工作,就必须保证文件系统的super block信 息在这种情况下也能正常访问。所以一个文件系统的super block会在多个block group中进行备份, 这些super block区域的数据保持一致。

3.3.2 GDT(Group Describe Table)

块组描述符表,描述块组属性信息,整个分区分成过个块组就对应着多少个块组描述符,每个块组描述存储一个块组的描述信息,块组描述符在每一个块组的开头都有一份拷贝

3.3.3 块位图(Block Bitmap)

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

3.3.4 inode位图(Inode Bitmap)

每一个Bit表示一个Inode是否空闲可用

3.3.5 i结点表(inode Table)

存放文件属性

当前分组所有Inode属性集合

Inode编号以分区为单位,整体划分,不可跨分区

3.3.6 Data Block

数据区:存放文件内容

对于普通文件,文件的数据存储在数据块中

对于目录,该目录下的所有文件名和目录名存储在目录的数据块中

Block号按区划分,不可跨分区

3.4 Inode和datatable映射

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

1.存储属性

内核先找到一个空闲的结点,内核把文件信息记录到其中

2.存储数据

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

3.记录分配情况

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

4.添加文件名到目录

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

3.5 目录与文件名

目录也是文件,但是磁盘上没有目录的概念,只有文件属性+文件内容的概念

目录保存的内容是:文件名和Inode号的映射关系

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

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

3.6 路径解析

打开当前工作目录文件,查看当前工作目录文件的内容?当前工作目录不也是文件吗?我们访问 当前工作目录不也是只知道当前工作目录的文件名吗?要访问它,不也得知道当前工作目录的inode 吗?

实际上,任何文件,都有路径,访问目标文件,比如: /home/whb/code/test/test/test.c 都要从根目录开始,依次打开每一个目录,根据目录名,依次访问每个目录下指定的目录,直到访问 到test.c。这个过程叫做Linux路径解析

访问文件,都是指令/工具访问,本质是进程访问,进程有CWD!进程提供路径

open文件,提供了路径

3.7 路径缓存

Linux磁盘中,存在真正的目录吗

不存在,只有文件。只保存文件属性+文件内容

访问任何文件,都要从/目录开始进行路径解析

原则上是,但是这样太慢,所以Linux会缓存历史路径结构

Linux目录的概念,怎么产生的

打开的文件是目录的话,由OS自己在内存中进行路径维护

每个文件其实都要有对应的dentry结构,包括普通文件。这样所有被打开的文件,就可以在内存中 形成整个树形结构

整个树形节点也同时会隶属于LRU(Least Recently Used,最近最少使用)结构中,进行节点淘汰 • 整个树形节点也同时会隶属于Hash,方便快速查找

更重要的是,这个树形结构,整体构成了Linux的路径缓存结构,打开访问任何文件,都在先在这 棵树下根据路径进行查找,找到就返回属性inode和内容,没找到就从磁盘加载路径,添加dentry 结构,缓存新路径

3.8 挂载分区

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

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

四、软硬件连接

4.1 硬链接

真正找到磁盘上文件的并不是文件名,而是inode。其实在linux中可以让多个文件名对应 于同一个inode

abc和def的链接状态完全相同,他们被称为指向文件的硬链接。内核记录了这个连接数,inode 263466 的硬连接数为2

我们在删除文件时干了两件事情:1.在目录中将对应的记录删除,2.将硬连接数-1,如果为0,则 将对应的磁盘释放

4.2 软链接

硬链接是通过inode引用另外一个文件,软链接是通过名字引用另外一个文件,但实际上,新的文件和 被引用的文件的inode不同,应用常见上可以想象成一个快捷方式

相关推荐
云深麋鹿1 小时前
三.栈和队列
开发语言·数据结构·c++·算法
爆打维c1 小时前
01BFS算法(例题:网格传送门旅游)
c语言·c++·python·算法·leetcode·广度优先
像素猎人2 小时前
力扣:面试题16.01.交换数字
c++·算法·leetcode·面试
zpedu2 小时前
给大家普及一下,1月才开始PMP的强度
学习
Suchadar2 小时前
在Linux中安装Python
linux·运维·服务器
CSDN_RTKLIB2 小时前
C++仿函数
c++·算法·stl
YQ_012 小时前
Ubuntu 18.04 离线安装 CUDA 11.2 + cuDNN 8.2 (修复 Paddle 缺少 .so 报错)
linux·ubuntu·paddle
Lv11770082 小时前
Visual Studio中的二维数组和交错数组
ide·笔记·c#·visual studio
零基础的修炼2 小时前
Linux网络---TCP原理
linux·网络·tcp/ip