【Linux】基础IO(二)--- 理解内核级和用户级缓冲区、磁盘与ext系列文件系统、inode与软硬连接(下)

简介: 【Linux】基础IO(二)--- 理解内核级和用户级缓冲区、磁盘与ext系列文件系统、inode与软硬连接(下)

2 磁盘的具体物理存储结构


存储的基本单元:扇区 ---- 一般磁盘,所有的扇区都是512字节

同半径的所有扇区 — 称为 : 磁道

如何定位一个扇区?


磁盘中定位一个扇区需要知道它所在的柱面号、磁头号和扇区号,这三个参数构成了磁盘的物理地址。

磁盘中定位一个扇区的过程分为两步:第一步是寻道,即将磁头移动到目标柱面上;第二步是旋转延迟,即等待目标扇区旋转到磁头下方。

磁盘中定位一个扇区的时间取决于寻道时间和旋转延迟时间,寻道时间与磁头移动的距离有关,旋转延迟时间与磁盘的转速有关。

磁盘中定位一个扇区的方法有多种,常见的有CHS(柱面-磁头-扇区)方法、LBA(逻辑块地址)方法和GPT(全局唯一标识分区表)方法。


d31903723e544b4dbf4e464a28feb5fa.png

483284a5841f4ea79b05e5e45ee8e011.png



3 进行逻辑抽象


谈到过物理层面定位某个扇区运用的算法是CHS定位法,那么LBA如何转到CHS定位呢?其实很简单,只需通过一些计算方式就可以进行转换,下面图片中的计算方法是捏出来的数据,方便大家理解LBA转到CHS定位的过程。

H磁头用来判断是哪个扇面,C柱面用来判断是哪个磁道,S就是确定在具体扇面的具体磁道中的具体某个扇区,这些工作在软件层面都可以解决,解决的过程其实就是LBA转到CHS的过程。


bcb48f02db8a4c5380a8422bb42d04da.png


为什么OS要进行磁盘的逻辑抽象呢?直接用CHS定位不行吗?

其实有两个原因,第一点是便于管理:在软件层面OS只要管理一个线性数组就可以了,而在物理层面管理一个三维立体结构可不是轻松的。最重要的第二点是:不想让OS的代码和硬件强耦合,因为如果强耦合,底层换了存储设备由SSD换成HHD,OS的代码就失效了,而如果进行逻辑抽象的话,底层无论更换任何存储设备,在操作系统看来都不过只是一个线性数组结构罢了,适应性很强。


4 磁盘文件的管理

磁盘文件的管理思想 — 分而治之

操作系统对磁盘空间的抽象 — 数据块 一般是4kb大小


至于为什么选择4KB为基本单位,之前的计算机科学家做过测试,发现以4KB作为IO的基本单位,性能是最好的,所以文件系统就采用了4KB了,这背后都是有论文作为依据的。

早些年诞生一项理论,叫做局部性原理,这项理论证明,当计算机访问某些数据时,极大可能访问到它周围的数据,所以在进程IO数据时,多加载一些数据是有助于提高操作系统的效率的,并且在一定程度上减缓了数据多次IO的过程。顺序表相比链表优势便在于数据更加集中,缓存时数据的命中率更高。

所以多加载数据的原因就是,达到预加载数据和以空间换时间的目的!!!


所以真实的内存被划分是以4KB作为基本数据大小的空间,16G内存的笔记本中大约有4194304个基本数据大小的空间,这些空间叫做页框,就是内存中一个个的块。

磁盘中的文件,尤其是可执行文件,实际上也是按照4KB大小划分为一个个的块,可执行文件中的一个个块叫做页帧。

所以从磁盘中加载数据到内存时,就是分为一个个的块进行加载,将页帧的数据加载到页框里,这就是文件系统和内存管理之间的耦合,他们都是以4KB为大小进行划分的。


磁盘分区的各个区的管理策略都是相同的,只要把管理方法ctrl+c,ctrl+v就可以解决其他区的管理问题了,区域中细分的组之间的管理策略也是如此,所以在管理时,我们只要管理好细分的组便可以管理好磁盘这一大块空间了。


从磁盘文件管理角度为什么有类型?操作系统的访问方式就是起始地址加上偏移地址这么访问的。所以只需要知道数据块的起始地址即可访问对应数据内容

所以块的地址本质就是:数组的一个下标,N,我们采用线性下标N的方式,就能定位任何一个块了

介绍下位图:


文件系统中的位图是一种数据结构,用来表示有限域中的稠集,即每个元素至少出现一次,没有其他的数据和元素相关联。文件系统中的位图通常用来标记磁盘空间的分配情况,每个比特位对应一个磁盘块,0表示空闲,1表示占用。


5 理解ext系列文件系统(以ext2为例)


我们可以通过ls -l读取存储在磁盘上的文件信息,然后显示出来


cfb12cee458f441582def5c1a162c5cd.png


其实这个信息除了通过这种方式来读取,还有一个stat命令能够看到更多信息:

[root@localhost linux]# stat test.c
 File: "test.c"
 Size: 654 Blocks: 8 IO Block: 4096 普通文件
Device: 802h/2050d Inode: 263715 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2017-09-13 14:56:57.059012947 +0800
Modify: 2017-09-13 14:56:40.067012944 +0800
Change: 2017-09-13 14:56:40.069012948 +0800


inode


inode表是文件系统中的一种数据结构,它存放了文件的元数据信息,如inode号、大小、属性、时间等。 inode表中的每个条目叫做inode,它是文件或目录在一个文件系统中的唯一标识。


inode表的内容可以用·stat命令或ls -i命令来查看。 例如,如果你有一个文件叫file.txt,你可以用stat file.txt来查看它的inode信息,如下:

$ stat file.txt
  File: file.txt
  Size: 13              Blocks: 8          IO Block: 4096   regular file
Device: fd02h/64770d    Inode: 123456      Links: 1
Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2022-10-05 10:00:00.000000000 +0800
Modify: 2022-10-05 10:00:00.000000000 +0800
Change: 2022-10-05 10:00:00.000000000 +0800
 Birth: -


从上面的输出可以看出,file.txt的inode号是123456,它的大小是13字节,它的权限是0644,它的所有者是root,它的修改时间是2022-10-05 10:00:00等等。


你也可以用ls -i file.txt来查看它的inode号,如下:

$ ls -i file.txt
123456 file.txt


从上面的输出可以看出,file.txt的inode号是123456。

为了能解释清楚inode我们先简单了解一下文件系统



baa53c162e5c4d178a60fcd8ebb0e3c7.png



Linux ext2文件系统,上图为磁盘文件系统图(内核内存映像肯定有所不同),磁盘是典型的块设备,硬盘分区被划分为一个个的block。一个block的大小是由格式化的时候确定的,并且不可以更改。例如mke2fs的-b选项可以设定block大小为1024、2048或4096字节。而上图中启动块(Boot Block)的大小是确定的.


块组 Block Group:ext2文件系统会根据分区的大小划分为数个Block Group。而每个Block Group都有着相同的结构组成。如政府管理各区的例子

超级块(Super Block):存放文件系统本身的结构信息。记录的信息主要有:bolck 和 inode的总量,未使用的block和inode的数量,一个block和inode的大小,最近一次挂载的时间,最近一次写入数据的时间,最近一次检验磁盘的时间等其他文件系统的相关信息。Super Block的信息被破坏,可以说整个 文件系统结构就被破坏了


GDT,Group Descriptor Table:块组描述符,描述块组属性信息,有兴趣的同学可以在了解一下 块位图(BlockBitmap):Block Bitmap中记录着Data Block中哪个数据块已经被占用,哪个数据块没 有被占用


inode位图(inode Bitmap):每个bit表示一个inode是否空闲可用。


i节点表:存放文件属性 如 文件大小,所有者,最近修改时间等


数据区:存放文件内容


可以说super block时文件系统的控制块 — 代表整个分区(或者说整个文件系统)的情况 保存文件系统的所有属性信息 (很重要!)---- 多份super block 就是为了防止故障发生,整个分区都不可以使用,起备份的作用!同时每个分区又分为不同的块组(block group),每个块组中都存在超级块,块组描述符— 记录块组宏各个部分的位置和大小,如位图、inode表等;数据块位图 — 记录块组中哪些数据块已经被使用,哪些没被使用;inode位图 – 记录了哪些inode已经被使用,哪些没有; inode表 — 存放了文件的元数据信息,如inode号、大小、属性、时间等;以及数据块 —存放了文件的实际内容或者指向其他数据块的指针(当然数据块data blocks 占据块组的百分之九十九的内存)


inode bit map 和block bit map的关系是什么 ?并行关系 一个管理inode的属性 一个管理数据


查看inode ---- ls -il


怎么理解inode?


ac8f852fd3e44ec98df6675ac4f07e9f.png


touch一个新文件看看


将属性和数据分开存放的想法看起来很简单,但实际上是如何工作的呢?我们通过touch一个新文件来看看如何工作


[root@localhost linux]# touch abc
[root@localhost linux]# ls -i abc
263466 abc


d53f9f7a32ba4ae9af44ae6f569e5d96.png


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


存储属性

内核先找到一个空闲的i节点(这里是263466)。内核把文件信息记录到其中。

存储数据

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

记录分配情况

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

添加文件名到目录

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


inode表中的datablock数组


inode表中的datablock数组是一个指针数组,它用来存储文件的数据块的地址。datablock数组的长度和文件系统的类型有关,一般有12个或15个指针。


datablock数组中的指针分为以下几种类型:


直接指针:直接指向文件的数据块,一般有12个,可以存储48KB(假设块大小为4KB)的文件数据。

间接指针:指向一个间接块,间接块中存放了多个直接指针,一般有一个,可以存储4MB(假设块大小为4KB,每个指针占4字节)的文件数据。

双重间接指针:指向一个双重间接块,双重间接块中存放了多个间接指针,一般有一个,可以存储4GB(假设块大小为4KB,每个指针占4字节)的文件数据。

三重间接指针:指向一个三重间接块,三重间接块中存放了多个双重间接指针,一般有一个,可以存储4TB(假设块大小为4KB,每个指针占4字节)的文件数据。


这样的结构可以让inode表中的inode占用较少的空间,同时可以支持较大的文件。


63d6d2a184044001932e27aa66f7b61f.png



再次理解


如何理解文件名 ---- 在目录文件内,文件名和inode互为key值 即映射关系


bed78cca3c5d4be7bf8f8764dbeef368.png

如何理解文件访问 — 一个目录也是一个文件,也有inode


d91f8b23c51341f990b0195e7a8822d3.png


如何理解文件的增删查改

  1. 查就是通过目录文件的数据信息进行查找
  2. 怎么删除文件 — 为什么删除这么快 — 很简单,因为只是修改了inode位图


5586a0cb5c414f52b9f0f93b9d6a9d94.png


  1. inode 不会被删 只会被覆盖 ---- bit map 置0 即删除 等待下次覆盖

格式化是什么? 其实就是对属性信息做操作,如bit map清空,描述符初始化

6 理解软硬理解


软硬链接是Linux系统中的两种文件链接方式,它们可以为一个文件创建多个有效的路径名。


软链接(也叫符号链接)类似于Windows系统中的快捷方式,它是一个特殊的文件,其中包含了另一个文件的路径名。软链接可以跨文件系统,可以对目录或不存在的文件名进行链接,但是如果原文件被删除了,软链接就会失效。


硬链接是指为一个文件创建一个或多个文件名,它们都指向同一个索引节点(inode),也就是同一个数据块。 硬链接不能跨文件系统,不能对目录进行链接,也不能对不存在的文件名进行链接,但是如果原文件被删除了,硬链接仍然有效。


在Linux系统中,可以用ln命令来创建软硬链接。


创建软链接:ln -s 源文件 目标文件

创建硬链接:ln 源文件 目标文件

软链接是一个独立的链接文件,有自己的inode number ,所以必有自己的inode属性和内容


软连接应用场景 — 本质其实就相当于快捷方式


4134b3a483744e4299bc73a890396851.png

那软连接的属性我们知道了,它的内容放的是什么呢?就是指向源文件的地址字符串


45fd88f616524c7f912f9da756909600.png

其中ref count 引用计数器 — 代表有多少文件指向我 — 当为0时就代表文件已经被删掉

软链接文件是一个独立的文件,有自己的inode节点,这个文件数据中保存的是源文件路径,通过保存的路径访问源文件,因此源文件被删除则无法再访问,通过路径将找不到源文件,这时候软链接就会失效。


软链接文件是一个独立的文件有自己的inode节点,文件中保存了源文件路径,通过数据中保存的源文件路径访问源文件


硬链接是文件的一个目录项,与源文件共用同一个inode节点,直接通过自己的inode节点访问源文件(其实本质上来说与源文件没区别)


硬链接被删除,则inode中的链接数-1,并不会直接删除文件数据,而是等链接数为0的时候才会实际删除对应文件的inode,将所占用数据块置为空闲


db78bd9f56c841f9b7dcb9aa52c0a84e.png


相关文章
|
11天前
|
存储 缓存 Linux
Linux IO的奥秘:深入探索数据流动的魔法
Linux I/O(输入/输出)系统是其核心功能之一,负责处理数据在系统内部及与外界之间的流动。为了优化这一流程,Linux进行了一系列努力和抽象化,以提高效率、灵活性和易用性。🚀
Linux IO的奥秘:深入探索数据流动的魔法
|
28天前
|
存储 监控 Shell
【Shell 命令集合 备份压缩 】Linux 备份文件系统 dump命令 使用指南
【Shell 命令集合 备份压缩 】Linux 备份文件系统 dump命令 使用指南
35 0
|
28天前
|
存储 Shell Linux
【Shell 命令集合 磁盘维护 】Linux 创建DOS文件系统 mkdosfs命令使用指南
【Shell 命令集合 磁盘维护 】Linux 创建DOS文件系统 mkdosfs命令使用指南
31 2
|
28天前
|
存储 Shell Linux
【Shell 命令集合 磁盘维护 】Linux 创建Minix文件系统 mkfs.minix 命令使用教程
【Shell 命令集合 磁盘维护 】Linux 创建Minix文件系统 mkfs.minix 命令使用教程
33 0
|
28天前
|
存储 Shell Linux
【Shell 命令集合 磁盘维护 】Linux 建立ext2文件系统 mke2fs命令使用教程
【Shell 命令集合 磁盘维护 】Linux 建立ext2文件系统 mke2fs命令使用教程
30 2
|
28天前
|
安全 Shell Linux
【Shell 命令集合 磁盘维护】Linux 检查和修复Minix文件系统 fsck.minix命令使用教程
【Shell 命令集合 磁盘维护】Linux 检查和修复Minix文件系统 fsck.minix命令使用教程
13 0
|
28天前
|
存储 Linux Shell
【Shell 命令集合 磁盘维护 】Linux 创建MS-DOS文件系统 mkfs.msdos命令使用教程
【Shell 命令集合 磁盘维护 】Linux 创建MS-DOS文件系统 mkfs.msdos命令使用教程
27 0
|
28天前
|
存储 安全 Linux
【Shell 命令集合 磁盘维护 】Linux 在特定的分区上建立 linux 文件系统 mkfs命令使用教程
【Shell 命令集合 磁盘维护 】Linux 在特定的分区上建立 linux 文件系统 mkfs命令使用教程
25 0
|
10天前
|
Linux
Linux操作系统调优相关工具(三)查看IO运行状态相关工具 查看哪个磁盘或分区最繁忙?
Linux操作系统调优相关工具(三)查看IO运行状态相关工具 查看哪个磁盘或分区最繁忙?
20 0
|
24天前
|
存储 算法 Linux
【Linux系统编程】Linux 文件系统探究:深入理解 struct dirent、DIR 和 struct stat结构
【Linux系统编程】Linux 文件系统探究:深入理解 struct dirent、DIR 和 struct stat结构
36 0