【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


相关文章
|
2月前
|
安全 Linux 测试技术
Intel Linux 内核测试套件-LKVS介绍 | 龙蜥大讲堂104期
《Intel Linux内核测试套件-LKVS介绍》(龙蜥大讲堂104期)主要介绍了LKVS的定义、使用方法、测试范围、典型案例及其优势。LKVS是轻量级、低耦合且高代码覆盖率的测试工具,涵盖20多个硬件和内核属性,已开源并集成到多个社区CICD系统中。课程详细讲解了如何使用LKVS进行CPU、电源管理和安全特性(如TDX、CET)的测试,并展示了其在实际应用中的价值。
|
2月前
|
Ubuntu Linux 开发者
Ubuntu20.04搭建嵌入式linux网络加载内核、设备树和根文件系统
使用上述U-Boot命令配置并启动嵌入式设备。如果配置正确,设备将通过TFTP加载内核和设备树,并通过NFS挂载根文件系统。
137 15
|
3月前
|
Ubuntu Unix Linux
Linux网络文件系统NFS:配置与管理指南
NFS 是 Linux 系统中常用的网络文件系统协议,通过配置和管理 NFS,可以实现跨网络的文件共享。本文详细介绍了 NFS 的安装、配置、管理和常见问题的解决方法,希望对您的工作有所帮助。通过正确配置和优化 NFS,可以显著提高文件共享的效率和安全性。
332 7
|
3月前
|
存储 运维 监控
Linux--深入理与解linux文件系统与日志文件分析
深入理解 Linux 文件系统和日志文件分析,对于系统管理员和运维工程师来说至关重要。文件系统管理涉及到文件的组织、存储和检索,而日志文件则记录了系统和应用的运行状态,是排查故障和维护系统的重要依据。通过掌握文件系统和日志文件的管理和分析技能,可以有效提升系统的稳定性和安全性。
77 7
|
3月前
|
算法 Linux
深入探索Linux内核的内存管理机制
本文旨在为读者提供对Linux操作系统内核中内存管理机制的深入理解。通过探讨Linux内核如何高效地分配、回收和优化内存资源,我们揭示了这一复杂系统背后的原理及其对系统性能的影响。不同于常规的摘要,本文将直接进入主题,不包含背景信息或研究目的等标准部分,而是专注于技术细节和实际操作。
|
3月前
|
存储 缓存 网络协议
Linux操作系统的内核优化与性能调优####
本文深入探讨了Linux操作系统内核的优化策略与性能调优方法,旨在为系统管理员和高级用户提供一套实用的指南。通过分析内核参数调整、文件系统选择、内存管理及网络配置等关键方面,本文揭示了如何有效提升Linux系统的稳定性和运行效率。不同于常规摘要仅概述内容的做法,本摘要直接指出文章的核心价值——提供具体可行的优化措施,助力读者实现系统性能的飞跃。 ####
|
3月前
|
缓存 监控 网络协议
Linux操作系统的内核优化与实践####
本文旨在探讨Linux操作系统内核的优化策略与实际应用案例,深入分析内核参数调优、编译选项配置及实时性能监控的方法。通过具体实例讲解如何根据不同应用场景调整内核设置,以提升系统性能和稳定性,为系统管理员和技术爱好者提供实用的优化指南。 ####
|
3月前
|
监控 算法 Linux
Linux内核锁机制深度剖析与实践优化####
本文作为一篇技术性文章,深入探讨了Linux操作系统内核中锁机制的工作原理、类型及其在并发控制中的应用,旨在为开发者提供关于如何有效利用这些工具来提升系统性能和稳定性的见解。不同于常规摘要的概述性质,本文将直接通过具体案例分析,展示在不同场景下选择合适的锁策略对于解决竞争条件、死锁问题的重要性,以及如何根据实际需求调整锁的粒度以达到最佳效果,为读者呈现一份实用性强的实践指南。 ####
|
6月前
|
Java 大数据 API
Java 流(Stream)、文件(File)和IO的区别
Java中的流(Stream)、文件(File)和输入/输出(I/O)是处理数据的关键概念。`File`类用于基本文件操作,如创建、删除和检查文件;流则提供了数据读写的抽象机制,适用于文件、内存和网络等多种数据源;I/O涵盖更广泛的输入输出操作,包括文件I/O、网络通信等,并支持异常处理和缓冲等功能。实际开发中,这三者常结合使用,以实现高效的数据处理。例如,`File`用于管理文件路径,`Stream`用于读写数据,I/O则处理复杂的输入输出需求。
362 12
|
7月前
|
Java 数据处理
Java IO 接口(Input)究竟隐藏着怎样的神秘用法?快来一探究竟,解锁高效编程新境界!
【8月更文挑战第22天】Java的输入输出(IO)操作至关重要,它支持从多种来源读取数据,如文件、网络等。常用输入流包括`FileInputStream`,适用于按字节读取文件;结合`BufferedInputStream`可提升读取效率。此外,通过`Socket`和相关输入流,还能实现网络数据读取。合理选用这些流能有效支持程序的数据处理需求。
90 2