【Linux】磁盘文件系统(inode)、软硬链接

文章目录

  • 1. 认识磁盘
    • 1.1 磁盘的物理结构
    • 1.2 磁盘的逻辑结构
  • 2. 引入文件系统
    • 2.1 EXT系列文件系统的分区结构
    • 2.2 inode
  • 3. 软硬链接
    • 3.1 软链接
    • 3.2 硬链接

在这里插入图片描述

在讲过了内存文件系统后,我们可以知道文件分为两种:

  • 打开的文件(内存中)
  • 未被打开的文件(磁盘中)

今天我们主要来探讨未被打开的文件。

  • 当文件存储在磁盘中时,如果我要打开它,那我首先要能找到它(通过路径)
  • 既然是这样,那Linux中每一个文件都要有路径
  • 为了更好的进行磁盘级文件的管理,我们必须要有一个磁盘文件系统的东西

那么文件系统是怎么把没有被打开的文件在磁盘上管理起来的呢?

只要它管好了,就可以给我们提供正确的路径,那么我们就可以定位这个文件,在系统层面就可以打开这个文件,进而能够转化到内存中,进行内存文件的管理。

1. 认识磁盘

1.1 磁盘的物理结构

  • 磁盘的结构

在这里插入图片描述

磁盘在工作时,主轴会高速旋转,磁头也会左右摆动。

  • 磁盘的存储结构

在这里插入图片描述
一个盘片有两面,每一面都可以存数据。多个盘片,相同磁道之间自上而下形成一种逻辑结构:柱面。

  • 磁头在运动过程中不断摆动的本质是:定位磁道或柱面。
  • 磁盘在旋转的时候,目的是让磁道上不同的扇区处在磁头下方,本质是:定位扇区。(扇区是磁盘存储数据的基本单位,一般为512字节,读写时是以512字节为整体,构成一个“块”,所以磁盘也叫做块设备)

在linux系统也是可以查到扇区的

在这里插入图片描述

  • 磁盘每一个面上都有一个磁头,对应h0-h5;读写哪一个磁头,本质是读写哪一面。
  • 传动臂上的磁头是共进退的。

在这里插入图片描述

所以如何定位一个扇区呢?

  1. 先定位柱面(cylinder)
  2. 再定位磁头(head)
  3. 最后定位扇区(sector)

因此,这叫做CHS定址法。

由于文件 = 内容+属性,但它们都是数据,在磁盘中无非就是占据哪几个扇区的问题。那既然我们能定位一个扇区了,那能不能定位多个扇区呢?

1.2 磁盘的逻辑结构

在这里插入图片描述

磁带也是磁盘的一种,在磁带圈起来时,就类似一个盘面。将其拉直展开,就可以看成是由扇区为单位组成的数组。

我们可以将磁盘想象成卷起来的磁带,那么就可以将磁盘的某一个盘片上的某一个磁道抽象为线性结构,类似于数组:
在这里插入图片描述
这样,每一个扇区,就有了一个线性地址(数组下标)
在这里插入图片描述
所以,在系统使用文件的时候,只需要使用数组下标法(LBA),不用关心CHS,但是数组下标又是怎么得到的呢?

由于传动臂上的磁头是同进退的,所以在我们找磁道时,所有的磁头共同移动,对应就找到了一个柱面。
所以,磁盘虽然分了很多面,但是在我们看来,逻辑上磁盘是由n多个柱面组成的。

所以,磁盘的真实情况应该是:
在这里插入图片描述
在这里插入图片描述

所以,磁盘就可以抽象为一个”三维数组“,但是在我们看来,其实它还是一个一维数组

在这里插入图片描述
所以,每个扇区都有一个下标,我们叫做LBA(Logical Block Address),其实就是线性地址。

LBA与CHS之间可以互相转换(磁盘的工作)。

当磁盘告诉操作系统磁盘的总容量、扇区大小,那OS一瞬间就可以知道有多少个扇区了。

那么从今往后 ,在磁盘的使用者看来,根本不关心CHS地址,而是直接使用LBA地址,磁盘内部自己转换
所以,从现在开始,磁盘就是一个元素为扇区的一维数组,数组的下标就是每一个扇区的LBA地址。OS使用磁盘,就可以用一个数字访问磁盘的扇区了。

2. 引入文件系统

2.1 EXT系列文件系统的分区结构

有了上面的知识后,我们知道OS与磁盘进行IO时,就是访问数组下标所对应的扇区,但是扇区512字节有点少,即单次IO的数据量有点少。

为了增加单次IO的数据量,OS与磁盘进行交互时,是以1KB、2KB、4KB、8KB等数据块为单位进行IO的,Linux中选择4KB数据块,一个数据块由8个扇区构成。

所以,在文件系统层面上,它才不管扇区,它IO的基本单位是数据块。
数据块转LBA地址:块号*8 + [1,8]
在这里插入图片描述
那么我们的磁盘就被抽象成了以块位单位的数组。
在这里插入图片描述
如果直接对块进行管理的话,成本太高了。因此将众多块又划分为一个分区,最终磁盘被划分为N个分区,分区之间各自独立。

分区中又划分出了组
分完组之后,只需要对组进行管理就可以。
一个组又分为如下几个区域:
在这里插入图片描述

2.2 inode

由于文件 = 内容+属性,属性也是数据,是以结构体的方式构建出来的,该结构体叫做inode(文件对应属性的集合,一般是128字节),所以在磁盘的一个4KB块中,会有32个inode。
在这里插入图片描述
在Linux中可以使用ls - i 选项查看一个文件的inode,下方显示出来的信息起始就是inode struct中的内容。
在这里插入图片描述

在一个组中,会存在非常多的inode,所以组中就存在一张inode Table,存放组中所有inode,方便管理每一个文件。

Data Blocks中,全都是划分好的4KB块,存放的是文件的内容

所以,在Linux下,文件的属性和内容是分开存储的。

那通过inode找到文件的属性后,内容是怎么找到的呢? - - 在inode中,存在一个block数组,记录当前inode所占用的data block块,后面讲。

一个组中的区域分布如下:

  • inode table(节点表):存储了每个inode的详细信息,包括文件的大小、权限、时间戳、数据块位置等
  • Data blocks(数据区):存放文件内容,全都是划分好的4KB块
  • inode Bitmap(inode table位图):每个bit位表示inode table中的inode是否被占用。 inode号在inode table中早就设置好了,只是有没有被使用的问题。inode bitmap中的位置与inode table中的位置是一一对应的。
  • Block Bitmap(块位图):Block Bitmap中记录着Data Block中哪个数据块已经被占用,哪个数据块没有被占用
  • Group Descriptor Table:块组描述符,描述块组属性信息。例如:每个组的起始inode与block编号。
  • 超级块(Super Block):存放当前分区文件系统本身的结构信息。记录的信息主要有:bolck 和 inode的总量,未使用的block和inode的数量,一个block和inode的大小,最近一次挂载的时间,最近一次写入数据的时间,最近一次检验磁盘的时间等其他文件系统的相关信息。
    Super Block的信息被破坏,可以说整个文件系统结构就被破坏了。Super Block有多份拷贝,可在损坏时进行修复。

分区格式化的本质:写入空的文件系统。将组中的super block、GDT、data bitmap、block bitmap置为空即可。

在这里插入图片描述
关于inode

  1. inode是以分区为单位的,一个分区一套inode。因此不同分区可以有相同inode
  2. inode在分配时,只需要确定当前组起始inode即可

关于block

  1. 块号也是以分区为单位的
  2. 块号在分配时,也只需要确定当前组的起始block编号

在一个组中,我们是如何分配一个inode的呢?

  • 由于inode bitmap的存在,我们只需要在bitmap中找一个可用位置,然后加上当前组inode的起始编号即可。 由于组起始inode的存在,我们就在不同组的起始inode之间就形成了一个区间,所以我们就可以分配为全局且唯一的inode

在一个组中,我们是如何分配一个block的呢?

  • 由于block bitmap的存在,我们只需要在blockmap中找一个可用位置,然后加上当前组block的起始编号即可。 在整个区间中,block号也是全局且唯一的。 当一个组中存储大文件,块不够用时,可以跨组!inode中记录了所有存储文件内容的块

当知道一个inode号或者block块时,只需要在GDT中比对每一个组的起始编号,定位组;然后使用提供的inode号或者block号减去该组的起始编号,即可在位图中找到对应的位置,然后就可以确定inode在inode table的位置。
所以我们就可以确定任意一个块、任意一个组了。


那inode和block是怎么映射的呢?inode中block数组是多大呢?
在这里插入图片描述
在ext系列的文件系统中,block数组的大小是15,可是一个块才4KB,总共才60KB,那怎么能行呢?
前12个确实直接指向数据块;后三个则不是,它们3个存的是数据块的编号。
在这里插入图片描述
当前组的data block不够用时,是可以跨组的。但不建议这么做,因为一旦跨组访问了,意味所有的块不连续了,磁盘寻址效率也会大大降低。


在上面对文件的所有操作中,都是以inode为前提的,但是inode是怎么得到的呢?我们平时操作文件使用的都得文件名呀!

所以inode是通过文件名找到的,我们在struct inode中也并没有看到文件名的存在,那文件名存在哪里呢?

  • 要弄清楚上面的问题,我们首先要知道,文件有普通文件和目录文件,我们之前谈论的全部都是普通文件,那目录文件又是如何呢?
  • 上面我们已经从文件系统角度认识文件了,所以目录文件也要有属性和内容,那内容中也要有对应的数据块。
  • 目录文件的数据块中存的是什么呢? - - 存文件名和inode的映射关系,二者互为映射
  • 所以,文件名存放在文件所属的目录的数据块中

此时,我们就可以更清楚的认识目录的权限:

  • r:没有读权限,就无法读取目录的data block,也就得不到文件名和inode的映射关系,拿不到inode,你怎么访问文件。
  • w:没有写权限,无法把文件名和inode的映射关系保存到目录的data block中

那我们的文件名又是怎么找到的呢?

要找到一个文件名,首先要打开当前目录,访问当前目录的data block;
可是目录也是文件,也有文件名呀?所以还需要继续向上找,直到根目录。根目录的data block中固定存储了文件名与inode的映射关系。

但是在系统中并不是逆向的,而是正向的。
因为任何一个文件都有路径,在最开始时,系统就按照路径进行查找。

当我访问在同一个目录下的另一个文件时,系统还需要从头再访问一遍磁盘的文件系统吗? - - 不需要了,Linux系统中,会对所访问过的路径进行缓存!会以一个多叉树的结构,将路径缓存在内存中,该结构在内核中叫做 dentry树

所以,系统在查找一个文件时

  1. 先按照路径找到文件所在的目录
  2. 在目录的data block块中,获得文件名与inode的映射关系
  3. 拿着inode,对比磁盘分区的GDT,确定该inode在哪一个分组
  4. 确定分组后,用inode减去该分组的起始inode,确定inode的位置n
  5. 通过inode bitmap核实 n 位置,然后找到inode table中的n位置对应的inode
  6. 通过inode中的block数组,访问对应的数组块。

那inode和进程、文件描述符之间又有什么关系呢?
在这里插入图片描述

此时,我们的进程和文件就关联起来了。

那整体上我们应该怎么理解呢?
在这里插入图片描述

3. 软硬链接

在这里插入图片描述

  • Access 最后访问时间
  • Modify 文件内容最后修改时间
  • Change 文件属性最后修改时间

在之前的学习中,我们直到使用ls -l 命令可以查看文件的属性,可是在文件权限后面的那一列数字,代表的是什么呢?

3.1 软链接

建立软链接的方式:

ln -s 被链接的文件名  链接后的文件名

在这里插入图片描述

下面我们将它们的inode也显示出来

在这里插入图片描述

发现二者的inode并不相同,软链接有自己独立的inode,因此,软链接本质是一个独立的文件。

当我们对被链接的文件与链接后的文件操作时,发现它俩操作的是同一个文件。

在这里插入图片描述

删除一个软链接的方式:

unlink 链接后的文件名

在这里插入图片描述

3.2 硬链接

建立硬链接的方式:

ln 被链接的文件名  链接后的文件名

在这里插入图片描述
此时我们发现,file-hard.link与file.txt两个文件的inode相同,并且权限后面的那一列数组变成了2,这是什么情况呢?而且如果将file-hard.link删掉,那一列数字又变成了1,那一列数字到底是什么意思呢?

首先,既然二者的inode相同,那么硬链接本质上不是一个独立的文件。

了解软硬链接的创建后,那么该如何理解软硬链接呢?为什么要有软硬链接呢?

  • 理解软硬链接

软链接

  1. 软链接有独立的inode,那么它就有内容和属性。
  2. 内容中,它保存的是目标文件的路径,等同于快捷方式

硬链接

  1. 硬链接不是独立的文件,它本质存储的是指向文件inode的引用,通过共享inode来实现对同一文件数据的访问

文件权限后面对应的那一列数字是什么意思呢?

首先我们知道,文件名并不在inode中保存,它保存在文件所属目录的内容(data block)中,这也就意味着会有多个文件名映射到同一个文件上。
换句话说,一个文件在什么时候才能被系统真正的删除呢?- - 没有任何文件名映射到当前文件的inode时。
在inode内部,存在一个引用计数,来统计有多少个文件名映射到当前inode。
那一列数字,对应的就是当前inode的引用计数的个数,即硬链接

  • 为什么要有软硬链接呢?应用场景是什么?

软链接的作用

  1. 通过创建一个指向目标文件或目录的软链接,可以简化对目标文件或目录的访问路径。用户可以通过软链接名来访问目标文件或目录,而不需要输入完整的路径。
  2. 软链接类似于一个文件系统中的“快捷方式”,如果目标文件或目录被删除或移动,软链接将变成“死链接”(dangling link),即指向一个不存在的文件或目录。

在这里插入图片描述
当我创建了一个目录时,为什么它的硬链接数是2呢?
在这里插入图片描述
当我在empty目录中又创建了一个目录时,它为什么又变成3了呢?

因为有以下三个硬链接指向它

  • empty
  • empty/.
  • empty/dir/. .

在这里插入图片描述

所以,这就是为什么一个文件创建时,默认有两个隐藏目录 .. .,为了方便找路径

硬链接的作用

  1. 数据冗余和备份:通过创建硬链接,你可以在不同的目录或同一目录中拥有文件的多个访问路径。如果原始文件被删除,硬链接仍然可以访问文件数据。这就意味着,在linux中,如果对文件进行备份,只需要建立硬链接!
    在这里插入图片描述
  2. 节省磁盘空间:硬链接不会创建文件的副本,而是共享相同的物理数据块。因此,它们可以节省磁盘空间,特别是在需要多个文件副本的情况下。
  3. 文件恢复:如果文件被误删除,但文件系统中仍然存在指向该文件的硬链接,那么文件数据仍然可以恢复。这提供了一种额外的数据保护机制。

注意:Linux中,不允许对目录新建硬链接。因为硬链接后的目录,也是可以进入的,那么就会产生环状路径。

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何提高英语口语表达能力?

提高英语口语表达能力是一个逐步积累和实践的过程。 1. 自我练习方法 录音与回听 录音:用手机或其他设备录下自己的口语练习,比如描述一天的活动、讲述一个故事或复述一篇文章。 回听:仔细听录音,找出发音、语法和流利度方面的问…

【设计模式-状态模式】

状态模式(State Pattern)是一种行为设计模式,它允许一个对象在内部状态改变时改变它的行为。换句话说,这种模式让对象在不同的状态下能够表现出不同的行为,而不需要修改对象的代码。状态模式通过将对象的行为与状态进行…

node集成redis (教学)

文章目录 前言一、安装redis二、可视化界面测试连接1.vscode安装插件 三、node代码编写1.先安装两个库(redis和ioredis)2.测试连接 (前提是你的redis服务器要启动起来) 总结 前言 在Node.js中集成ioredis是一个常见的做法&#x…

vscode配色主题与图标库推荐

vscode配色主题推荐:Andromedavsocde图标库: vscode-icons Andromeda Dark theme with a taste of the universe 仙女座:一套宇宙深空体验的哑暗色主题; 高对比度,色彩饱和; Easy Installation Open the extensions sidebar on Visual Studio CodeSear…

【LeetCode:263. 丑数 + 数学】

在这里插入代码片 🚀 算法题 🚀 🌲 算法刷题专栏 | 面试必备算法 | 面试高频算法 🍀 🌲 越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨ 🌲 作者简介:硕…

apply call bind 简介

Function.prototype.call(thisArg [, arg1, arg2, …]) call() 简述 call() 方法 调用一个函数, 其具有一个指定的 this 值和分别地提供的参数(参数的列表)。当第一个参数为 null、undefined 的时候, 默认 this 上下文指向window。 call() 简单实例 const name …

【项目复现】——DDoS-SDN Detection Project

文章目录 概要整体架构流程1. 系统和网络配置2. SDN控制器配置3. 流量生成4. 数据采集5. DDoS检测机制6. 机器学习模型训练7. 实时检测部署 前期准备复现流程第一步:系统和网络配置1.1 安装和设置操作系统1.2 安装VirtualBox和Mininet1.3 创建SDN网络拓扑 第二步&am…

探索现代软件开发中的持续集成与持续交付(CI/CD)实践

探索现代软件开发中的持续集成与持续交付(CI/CD)实践 随着软件开发的飞速进步,现代开发团队已经从传统的开发模式向更加自动化和灵活的开发流程转变。持续集成(CI) 与 持续交付(CD) 成为当下主…

w~自动驾驶合集6

我自己的原文哦~ https://blog.51cto.com/whaosoft/12286744 #自动驾驶的技术发展路线 端到端自动驾驶 Recent Advancements in End-to-End Autonomous Driving using Deep Learning: A SurveyEnd-to-end Autonomous Driving: Challenges and Frontiers 在线高精地图 HDMa…

iOS AVAudioSession 详解【音乐播放器的配置】

前言 在 iOS 音频开发中,AVAudioSession 是至关重要的工具,它控制着应用的音频行为,包括播放、录音、后台支持和音频中断处理等。对于音乐播放器等音频需求强烈的应用,设计一个合理的 AVAudioSession 管理体系不仅能保证音频播放…

三周精通FastAPI:16 Handling Errors处理错误

官网文档:https://fastapi.tiangolo.com/zh/tutorial/handling-errors 处理错误 某些情况下,需要向客户端返回错误提示。 这里所谓的客户端包括前端浏览器、其他应用程序、物联网设备等。 需要向客户端返回错误提示的场景主要如下: 客户端…

FastAPI、langchain搭建chatbot,langgraph实现历史记录

环境:openEuler、python 3.11.6、Azure openAi、langchain 0.3.3、langgraph 0.2.38 背景:基于FastAPI、langchain实现一个QA系统,要求实现历史记录以及存储特征信息 时间:20241022 说明:在历史记录的存储中&…

R语言机器学习算法实战系列(十四): CatBoost分类算法+SHAP值 (categorical data gradient boosting)

禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍CatBoost的原理CatBoost的步骤教程下载数据加载R包导入数据数据预处理数据描述数据切割设置数据对象调节参数训练模型预测测试数据评估模型模型准确性混淆矩阵模型评估指标ROC Curv…

mysql 通过GROUP BY 聚合并且拼接去重另个字段

我的需求: 我想知道同一个手机号出现几次,并且手机号出现在哪些地方。下面是要的效果。 源数据: CREATE TABLE bank (id bigint(20) unsigned NOT NULL AUTO_INCREMENT,user_id int(11) NOT NULL DEFAULT 0,tel varchar(255) COLLATE utf8mb4_unicode_…

【自然语言处理】BERT模型

BERT:Bidirectional Encoder Representations from Transformers BERT 是 Google 于 2018 年提出的 自然语言处理(NLP)模型,它基于 Transformer 架构的 Encoder 部分。BERT 的出现极大提升了 NLP 任务的性能,如问答系…

Python | Leetcode Python题解之第509题斐波那契数

题目&#xff1a; 题解&#xff1a; class Solution:def fib(self, n: int) -> int:if n < 2:return nq [[1, 1], [1, 0]]res self.matrix_pow(q, n - 1)return res[0][0]def matrix_pow(self, a: List[List[int]], n: int) -> List[List[int]]:ret [[1, 0], [0, …

自动化部署-02-jenkins部署微服务

文章目录 前言一、配置SSH-KEY1.1 操作jenkins所在服务器1.2 操作github1.3 验证 二、服务器安装git三、jenkins页面安装maven四、页面配置自动化任务4.1 新建任务4.2 选择4.3 配置参数4.4 配置脚本 五、执行任务5.1 点击执行按钮5.2 填写参数5.3 查看日志 六、查看服务器文件七…

51单片机STC8G串口Uart配置

测试环境 单片机型号&#xff1a;STC8G1K08-38I-TSSOP20&#xff0c;其他型号请自行测试&#xff1b; IDE&#xff1a;KEIL C51&#xff1b; 寄存器配置及主要代码 STC8G系列单片机具有4个全双工异步串行通信接口&#xff1b;本文以串口1为例&#xff0c;串口1有4种工作方式…

java疫苗发布和接种预约系统源码(springboot)

项目简介 疫苗发布和接种预约系统实现了以下功能&#xff1a; 疫苗发布和接种预约系统的主要使用者分为&#xff1a; 管理员对公告信息&#xff0c;医院信息&#xff0c;疫苗信息&#xff0c;医生信息&#xff0c;用户信息&#xff0c;论坛帖子信息以及预约接种信息等信息进行…

C语言程序设计:现代设计方法习题笔记《chapter5》下篇

第七题 题目分析&#xff1a;求最大最小值转换为条件判断问题&#xff0c;最大值有四种可能&#xff0c;最小值相应有三种情况&#xff0c;给出下列代码。 示例代码&#xff1a; #include <stdio.h>int main() {int num1, num2, num3, num4; // 定义四个变量来存储输入…