【Linux取经路】文件系统——inode与软硬链接

news2024/9/24 1:25:35

在这里插入图片描述

文章目录

  • 一、前言
  • 二、认识硬件——磁盘
    • 2.1 磁盘的存储构成
    • 2.2 磁盘的逻辑抽象
  • 三、操作系统对磁盘的使用
    • 3.1 再来理解创建文件
    • 3.2 再来理解删除文件
    • 3.3 再来理解目录
  • 四、硬链接
  • 五、软链接
  • 六、结语

一、前言

在之前的【Linux取经路】文件系统之被打开的文件——文件描述符的引入一文中讨论了被打开的文件,今天讨论的话题则是没有被打开的文件。文件等于文件内容文件属性,没打开的文件一定是存储在磁盘上的,并且 Linux 是将文件的属性和内容分开存储文件内容以数据块的形式进行存储,文件属性以 inode 的形式进行存储

在这里插入图片描述

二、认识硬件——磁盘

我们这里说的磁盘指的是机械磁盘,并非我们现在我们笔记本上使用的 SSD。机械磁盘是计算机上唯一的一个机械设备,也是一个外设。
在这里插入图片描述
小Tips:磁头是一面一个,磁头与盘面不接触。磁头通过向盘面进行充放电来完成数据的写入。磁盘叫做永久性存储介质,内存叫做掉电易失性存储介质。

2.1 磁盘的存储构成

在这里插入图片描述
每一个盘面由多个磁道构成,一个磁道又有多个扇区构成。磁盘被访问的最基本单元是扇区,一般扇区的大小是 512 字节,有的是 4KB。要修改磁盘中 1 字节的数据,需要把该字节所在的扇区都加载到内存中。可以把磁盘看成是由无数个扇区构成的存储介质。要把数据存储到磁盘,第一个需要解决的问题就是如何定位一个扇区,首先需要定位盘面,也就是确定用哪个磁头,因为一个磁头对应一个盘面,接下来需要定位磁道,最后定位扇区。所有的磁头都是同步运动的,在某一时刻,从从上向下看去,以磁头所在点为半径的不同盘面上的磁道就会形成一个叫做柱面的结构。磁头运动主要是去定位磁道,盘面旋转主要是去定位扇区,磁头的定位是由硬件电路进行控制。由此可见,磁盘的读取效率取决于磁头、盘面的运动速度和运动次数,运动越少,效率越高;运动越多,效率越低。因此,在软件设计上要求设计者一定要有意识的将相关数据放在一起。

2.2 磁盘的逻辑抽象

在这里插入图片描述
最终一个磁盘可以看作是基于扇区的数组,每一个扇区都对应有一个下标来唯一标识。通过这个下标(LBA 逻辑扇区地址),再结合每一面磁道的个数和每一个磁道上扇区的个数就可以定位到该扇区在磁盘上的位置(CHS地址)。

小Tips:不仅 CPU 有寄存器,其它外设也有,磁盘中也有寄存器。比如:控制寄存器,用来存储 CPU 下发的读写指令;数据寄存器,存储要写入的磁盘的数据;地址寄存器,存储 CPU 传送来的 LBA 地址;状态寄存器,存储磁盘的状态,操作系统通过检查该状态寄存器去判断读写是否成功。

三、操作系统对磁盘的使用

在这里插入图片描述
上图为 Linux ext2 磁盘文件系统图(内核内存映像肯定有所不同),磁盘是典型的块设备,操作系统首先会对磁盘进行分区,就如我们电脑中的 C 盘和 D 盘。接着,磁盘分区被划分为若干个块组(Block group),每个块组中有许多块(block),一个 block 的大小是由格式化的时候确定的,并且不可以更改,常见的是 4KB,即 4096字节。

  • Boot Block:通常存储操作系统启动的相关信息,比如:操作系统在什么位置、当前磁盘一共被划分成了多少个分区等。这些信息一般存储在磁盘的最前面,当然为了防止意外,这些内容在其它地方也会有备份。

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

  • Super Block:存放文件系统本身的信息,这里面记录了整个分区的信息。例如:整个分区有多大、该分区里面每组的起始位置、每个组的大小、每个组的 inode 数量、每个组的 block 数量、每个组的其实 inode 编号、block 和 inode 的总量,未使用的 block 和 inode 的数量,一个 block 和 inode 的大小、文件系统的类型与名称、最近一次挂载的时间、最近一次写入数据的时间、最近一次检验磁盘的时间、该文件系统所拥有的字段以及字段的存储顺序和起始位置(也就是规定了一个组的空间划分)等其它文件系统的相关信息。Super Block 的信息被破坏,可以说整个文件系统结构就被破坏了。该字段并不是在每一个分组中都有,而是在部分组里面有,防止意外发生,操作系统通过“魔数”来判断是否是 Super Block。

  • Group Descriptor Table:块组描述符,存储块组属性信息,例如:当前分组的大小、使用情况、下一个文件描述符应该从哪开始。

  • Block Bitmap:块位图,将比特位的位置和块号映射起来,里面记录着 Data Block 中哪个数据块已经被占用,哪个数据块没有被占用。

  • inode Bitmap:每个 bit 表示一个 inode 是否空闲可用。

  • inode Table:一组 inode。每一个 inode 用来存放单个文件的所有属性,如:文件大小、所有者、最近修改时间等。每个 inode 的大小一般是 128字节,且每一个 inode 都有唯一的编号。一般而言,一个文件一个 inode。

  • Data block:数据区,存放文件内容。以块的形式呈现,常见块的大小是 4KB。每个块都有自己独一无二的块号。

小Tips:操作系统在访问磁盘的时候,会以块为基本单位进行访问。

格式化:每个组的前四个字段存储的都是一些文件系统的属性信息或者分组的使用情况信息,这些内容应该在我们使用磁盘之前都准备好。所以,每一个分区在被使用前,都必须将部分文件系统的属性信息提前设置进对应的分区中,方便后续对分区和分组的使用,这个动作就叫做格式化。

在 Linux 中,文件的属性里面是不包含文件的名称在 Linux 系统里面标识文件用的是 inode 编号。一个 inode 表示一个文件的所有属性,文件名并不属于 inode 内的属性。

在这里插入图片描述
一个 inode 与 数据块的对应关系:

在这里插入图片描述
其中直接索引对应的块中存储的就是文件内容,二级索引对应的块中存储的不是文件内容而是块号。假设块的大小是 4KB,块号用 4字节。那么一个块就可以存储 1024 个块号,这 1024 个块号对应的块里面存储的是文件的内容,三级索引同理。这样做的目的是在 inode 里面用较少的空间就可以映射出更多的数据块。

小Tips:inode 编号是以分区为单位进行统一分配的,而且不能跨分区,即每个分区中的 inode 编号都是从 0 开始,且一个分区中的 inode 个数是有上限的,因此可能会存在一下情况:一个分区中的 inode 被用完了,但是数据块还没有被用完,这种情况对应的就是创建了非常多的文件,但是每个文件的内容非常小;一个分区中的数据块被用完了,但是 inode 还没有被用完,这种情况就是创建的文件并不多,但是每个文件的大小非常大。

3.1 再来理解创建文件

首先创建文件一定是在一个路径下(目录)进行创建,这个路径就会帮我们定位到一个分区,然后去从第一个分组开始查看当前分组的 GDT 字段,看该分组中 inode 的使用情况,若当前分组中的 inode 还有剩余,接着去读取 inode_Bitmap,获取最近一个未被使用的 inode 编号,然后拿着 inode 编号去 inode_Table 里面找到对应的 inode,将文件的属性信息一填。如果有文件内容,先拿着 inode 编号找到对应的分组,根据写入内容的大小去 Block_Bitmap 中找出对应数量未被使用的块号,然后将这些块号写入到 inode 对应的属性里面,然后拿着块号去 Data blocks 中进行写入。

3.2 再来理解删除文件

删除文件只要拿着该文件的 inode 编号,在 inode Table 中找到对应的 indoe,获取到里面的 blocks,即拿到该文件对应的所有块号,然后根据这些块号将 Block Bitmap 中对应的比特位置0(假设 0 表示对应的块未被使用)。最后再根据 inode 编号到 inode Bitmap 中将该 inode 对应的比特位置为0,至此,一个文件就被删除啦。可以发现从头到尾并没有去修改块中的内容,这也是为什么拷贝 4G 的文件很慢,删 4G 的文件很快。所以在理论上,一个被删除的文件,可以根据 inode 将其恢复出来。

总结:删文件就是去修改 inode_Bitmap 和 Block_Bitmap 中的字段。在计算机领域的删除并不等于清空,大部分情况下,删除都表示可覆盖。因为清空会导致效率大大下降。

3.3 再来理解目录

上面说的所有对文件的操作都离不开 inode 编号,但是我们作为普通用户平时好像也并没有关注过 inode 编号,我们一般是直接使用文件名,此时就必须再来理解一下目录了。目录也是文件,也有自己的 inode,目录也有属性。目录也有(数据块),目录的数据块里面存放的是这个目录下的所有文件名和该文件名对应的 inode 编号的映射关系,这是一种 key-value 结构,这就是为什么一个目录里面不允许出现同名文件。与此同时,和目录有关的一些历史问题也得到了解决,对于一个目录,没有 w,我们无法在该目录下创建文件,本质就是我们不能向目录对应的数据块中写入文件名和 inode 的对应关系;没有 r,无法产看该目录下的文件,本质就是不能读取目录文件的数据块。因此我们在查找一个文件时,首先需要知道该文件所在目录的 inode,要知道目录文件的 inode 编号,就需要知道目录文件所在目录的 inode 编号,如此递归一直到根目录,这就是为什么我们在操作一个任何一个文件的时候都需要知道它的绝对或者相对路径。如果每操作一个文件都要去这样递归一层层的查找,那么效率是非常低的。因此在 Linux 操作系统中有一个叫做 dentry 缓存(目录项缓存),里面记录了该用户经常访问的文件名和 inode 编号之间的映射关系。

四、硬链接

// 创建硬链接的指令
ln test.txt hard-link

在这里插入图片描述
硬连接不是一个独立的文件,因为它没有独立的 inode。所谓建立硬连接,本质其实就是在特定目录的数据块中新增文件名和指向的文件的 inode 编号的映射关系。上图也可以证明文件名不是 inode 中的属性,因为一个 inode 编号对应一个 inode,如果文件名是 inode 中的属性,那么上图中编号 1978740 的文件不可能对应两个文件名。

小Tips:任意一个文件,无论是目录,还是普通文件,都有 inode,每一个 inode 内部,都有一个叫做引用计数的计数器,这个计数器记录了有多少个文件名“指向”该文件(由硬链接可以得知,在 Linux 中可以让多个文件名对应于同一个 inode)。完整的删除文件过程就是先将特定目录数据块中的文件名与 inode 的映射关系删除,然后根据 inode 的编号,将对应 inode 中的引用计数减减,最终看其是否减到零,减到零再执行 3.2 小结的步骤。此外,创建一个普通文件,它的硬链接数默认是1。

创建目录文件的默认链接数为什么是 2 ?

在这里插入图片描述
硬链接数为2,说明与该文件 inode 编号有关的映射关系有两个,其中一个映射关系保存在 dir 所在目录文件的数据块,即 2023-11-06 目录文件中的数据块中,另外一个保存在 dir 目录自身的数据块中。

在这里插入图片描述
根目录的硬链接数减2就是根目录下创建的目录个数。根目录稍微有一点特殊,根目录中的 ... 文件名对应的 inode 编号是一样的,都是根目录。除去这俩文件名和 inode 编号的映射关系外,剩下的硬链接数就表示根目录下创建的目录个数,剩下的 18 个就是根目录中所有目录文件中 .. 与根目录 inode 编号的链接关系。可以这样计算的本质原因就是,根目录下所有目录中的 .. 都一定是指向根目录的,对应根目录的 inode 编号(也就是上图中的 2 )。这种计算方法也可以推行到其它任意目录。

总结:建立硬链接就是给一个已存在的文件创建别名,硬链接通常用来进行路径定位,采用硬链接,可以进行目录间切换。

在这里插入图片描述
小Tips:Linux 系统不允许用户对目录文件建立硬连接。只要是为了避免在文件搜索的时候发生环路问题,系统在搜索文件的时候并不会搜索 ...,如果允许用户为目录文件创建硬链接,那么操作系统在进行文件搜索的时候就无法避免环路问题。

五、软链接

// 创建软链接的指令
ln -s file.txt soft-link

在这里插入图片描述
软链接是一个独立的文件,有独立的 inode,也有独立的数据块,它的数据块里面存的是指向文件的路径。软链接非常像 Windows 中的快捷方式。软链接的使用场景:一般发布的可执行程序可能存在一个较深的路径下面,要执行它的话就需要带很长一串路径,显得十分麻烦,此时我们就可以创建一个软链接指向该可执行文件,之后要想运行该可执行程序就直接去执行软链接即可。

在这里插入图片描述
在这里插入图片描述
小Tips:可以对任意类型的文件创建软链接。

// 删除软硬链接都可以用 unlink 指令
unlink soft-link

六、结语

今天的分享到这里就结束啦!如果觉得文章还不错的话,可以三连支持一下,春人的主页还有很多有趣的文章,欢迎小伙伴们前去点评,您的支持就是春人前进的动力!

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1487221.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【学习心得】响应数据加密的原理与逆向思路

一、什么是响应数据加密? 响应数据加密是常见的反爬手段的一种,它是指服务器返回的不是明文数据,而是加密后的数据。这种密文数据可以被JS解密进而渲染在浏览器中让人们看到。 它的原理和过程图如下: 二、响应数据加密的逆向思路 …

go并发模式之----使用时顺序模式

常见模式之二:使用时顺序模式 定义 顾名思义,起初goroutine不管是怎么个先后顺序,等到要使用的时候,需要按照一定的顺序来,也被称为未来使用模式 使用场景 每个goroutine函数都比较独立,不可通过参数循环…

Linux入门到入土

Linxu Linux 简介 Linux 内核最初只是由芬兰人林纳斯托瓦兹(Linus Torvalds)在赫尔辛基大学上学时出于个人爱好而编写的。 Linux 是一套免费使用和自由传播的类 Unix 操作系统,是一个基于 POSIX(可移植操作系统接口&#xff09…

常用的电阻、电容的种类和应用场合?

电阻的 a.按阻值特性:固定电阻、可调电阻、特种电阻(敏感电阻),不能调节的,我们称之为固定电阻,而可以调节的,我们称之为可调电阻.常见的例如收音机音量调节的,主要应用于电压分配的,我们称之为电位器. b.按制造材料:碳膜电阻、金属膜电阻、线绕电阻,捷…

ElasticSearch开篇

1.ElasticSearch简介 1.1 ElasticSearch(简称ES) Elasticsearch是用Java开发并且是当前最流行的开源的企业级搜索引擎。能够达到实时搜索,稳定,可靠,快速,安装使用方便。 1.2 ElasticSearch与Lucene的关…

从0开始回顾Mysql --- MySQL初体验

大白话从0开始回顾MySQL,去除了一些繁琐的操作的演示以及内容,如MySQL安装等,本篇文章适合复习MySQL语法,学习MySQL语句,对MySQL不太熟练的同学,希望对大家有一些帮助。 MySQL初体验 首先,我将…

Linux内核MMC框架

1.mmc的概念 1.MMC MultiMedia Card,多媒体存储卡, 但后续泛指一个接口协定(一种卡式),能符合这接口的内存器都可称作mmc储存体,工作电压:高电压为2.7~3.6 V,低电压为1.65&#xf…

Python——桌面摄像头软件(附源码+打包)

目录 一、前言 二、桌面摄像头软件 2.1、下载项目 2.2、功能介绍 三、打包工具(nuitka) 四、项目文件复制(我全部合到一个文件里面了) 五、结语 一、前言 看见b站的向军大叔用electron制作了一个桌面摄像头软件 但是&#x…

【应用多元统计分析】--多元数据的直观表示(R语言作图)

例1.2 为了研究全国31个省、市、自治区2018年城镇居民生活消费的分布规律,根据调查资料做区域消费类型划分。 指标: 食品x1:人均食品支出(元/人) 衣着x2:人均衣着商品支出(元/人) 居住x3:人均居住支出(元/人) 生活x4…

ssh无法直接登入Linux超级用户root(23/3/3更新)

说明:不允许ssh用超级用户的身份登入是为了安全性,如果只是学习使用对安全性没啥要求可以按以下操作解除限制 以普通用户登录到服务器后,执行以下命令以编辑 SSH 服务器配置文件 /etc/ssh/sshd_config sudo nano /etc/ssh/sshd_config 此时会…

二极管原理及典型应用电路、三极管基本结构及类型状态

目录 二极管原理及典型应用电路 二极管的工作原理 二极管保护电路 二极管整流电路 二极管稳压电路 三极管基本结构及类型状态 三极管基本结构和类型 三极管的 3 种工作状态 二极管原理及典型应用电路 如下图,二极管长成这样。它们通常有一个黑色圆柱体&am…

【大厂AI课学习笔记NO.60】(13)模型泛化性的评价

我们学习了过拟合和欠拟合,具体见我的文章:https://giszz.blog.csdn.net/article/details/136440338 那么今天,我们来学习模型泛化性的评价。 泛化性的问题,我们也讨论过了,那么如何评价模型的泛化性呢? …

论文精读--GPT3

不像GPT2一样追求zero-shot,而换成了few-shot Abstract Recent work has demonstrated substantial gains on many NLP tasks and benchmarks by pre-training on a large corpus of text followed by fine-tuning on a specific task. While typically task-agnos…

二十四、剖析 ArrayDeque

文章目录 剖析 ArrayDeque3.1 循环数组3.2 构造方法3.3 从尾部添加 addLast(E)3.4 从头部添加 addFirst(E)3.5 从头部和尾部删除3.6 查看长度 size()3.7 检查给定元素是否存在3.8 toArray3.9 ArrayDeque 特点分析 剖析 ArrayDeque 本文为书籍《Java编程的逻辑》1和《剑指Java&…

Unity UGUI之Slider基本了解

在Unity中,Slider(滑动条)是一种常用的用户界面控件之一,允许用户通过拖动滑块来选择一个数值。常常应用于调节数值(如调节音量、亮度、游戏难度等)、设置选项等。 以下是Slider的基本信息和用法: 1、创建…

Neoverse CSS N3:实现市场领先能效的最快途径

区分老的架构 从云到边缘,Arm Neoverse 提供无与伦比的性能、效率、设计灵活性和 TCO 优势,正在颠覆传统基础设施芯片。 我们看到云和超大规模服务运营商正在推动更高的计算密度。随着 128 核心 CPU 设计上市(Microsoft Cobalt、阿里巴巴 Y…

工作微信统一管理(还带监管功能)

1.会话页面(可统一管理多个微信号、聚合聊天、手动搜索添加好友、通过验证请求、查看好友的朋友圈等) 2.聊天历史(可查看 所有聊天记录,包括手机.上撤回、删除的消息) 3.群发助手(可以一 -次群发多个好友和群,还可以选择定时发送,目前还在内测…

postman传参与返回值切换为左右显示的操作

目录 第一步 点击“Settings”,在下拉框选择“Settings” 第二步 在默认打开的General页面,参照下图改动两处 第一步 点击“Settings”,在下拉框选择“Settings” 第二步 在默认打开的General页面,参照下图改动两处 附上修改后…

Mysql深入学习 基础篇 Ss.02 详解四类SQL语句

我亲爱的对手,亦敌亦友,但我同样希望你能成功,与我一起,站在人生的山顶上 ——24.3.1 一、DDL 数据定义语言 1.DDL —— 数据库操作 查询 查询所有数据库 show databases; 查询当前数据库 select database(); 创建 create databa…

Linux:kubernetes(k8s)部署CNI网络插件(4)

在上一章进行了node加入master Linux:kubernetes(k8s)node节点加入master主节点(3)-CSDN博客https://blog.csdn.net/w14768855/article/details/136420447?spm1001.2014.3001.5501 但是他们显示还是没准备好 看一下…