【Linux】文件系统和软硬链接

目录

一、认识文件系统

二、认识磁盘

三、磁盘文件系统

[3.1 磁盘存储的抽象逻辑结构](#3.1 磁盘存储的抽象逻辑结构)

[3.2 磁盘文件系统图](#3.2 磁盘文件系统图)

[3.3 创建和删除文件](#3.3 创建和删除文件)

[3.4 如何理解目录?](#3.4 如何理解目录?)

[3.5 如何查找一个文件](#3.5 如何查找一个文件)

[3.6 查找文件的一般流程](#3.6 查找文件的一般流程)

[3.7 如何确定文件所在的分区](#3.7 如何确定文件所在的分区)

[3.8 总结](#3.8 总结)

四、软硬链接

[4.1 引入](#4.1 引入)

[4.2 软链接(Symbolic Link)](#4.2 软链接(Symbolic Link))

[4.3 硬链接(Hard Link)](#4.3 硬链接(Hard Link))


一、认识文件系统

我们之前对文件的学习都是内存级别的,那么在文件没有被进程打开之前,这个文件是什么样的状态?

不是所有的文件都会在OS内存中被打开(大部分文件都不是被打开的),这些没有被打开的文件在磁盘中保存。也要把这些文件安装一定规律管理好,方便用户进行及时查找、快速查找、方便查找,用户随时读取时要随时打开、随时进行把文件数据快速加载到内存。管理是为了解决快速定位问题。管理这些没有被打开的磁盘文件,就叫做文件系统。

例如我们身上只穿一套衣服,其他衣服也要在柜子里整理好,否则下次需要用到时查找效率特别低下。

综上,文件的管理工作:

  1. 对打开的文件进行管理
  2. 没有被打开的文件也要在磁盘中进行管理。

文件系统实现文件管理工作。文件系统核心工作之一:快速定位到文件(通过路径机制或管理机制等)

文件 = 内容 + 属性

  1. 文件的存储问题最终本质就是将文件内容和文件属性存储的问题。
  2. 文件存储在磁盘中,那么对于文件方便OS/用户就要进行磁盘级别的增删查改。

之前讲到 一切皆文件 的概念,即OS通过软件的方式,对底层硬件的差异化进行屏蔽,这种动作叫做逻辑抽象。逻辑抽象给OS提供了一个管理的统一视角,为OS管理磁盘做准备。

  • 磁盘 --- 硬件 --- 物理存储结构
  • 逻辑抽象 --- 逻辑存储结构

二、认识磁盘

磁盘的特点:

  1. 磁盘 --- 硬件 --- 物理存储结构。
  2. 磁盘容量大、便宜、企业可以大量使用。
  3. 通过磁头的摆动和盘片的旋转可以读取磁盘中的所有内容。
  4. 一个盘面可以有很多的同心磁道,一圈磁道可以有很多扇形的扇区
  5. 扇区是磁盘的最小存储单元 ---- 一般是512字节
    哪怕只需要访问1个比特位,磁盘也会读取512字节,所以磁盘是块设备。
    (支持随机存取,且有最小存储单元的设备是块设备)

如果我想向一个扇区写入,我们该如何寻址,定位?

(CHS定位法)

1.选择哪一面 --- 本质选择磁头(head)

2.选择该面上的哪一个磁道 (track / cylinder柱面)

3.选择在该磁道的哪一个扇区 (sector)

我们可以向一个扇区写入,就可以向任意一个/多个扇区写入,也连续多个扇区式的写入,当然也可以随机写入。

磁头左右摆动可以定位柱面/磁道,盘片旋转可以定位扇区。

三、磁盘文件系统

3.1 磁盘存储的抽象逻辑结构

为了方便操作系统统一管理磁盘,也为了对磁盘进行更好的逻辑抽象,进而实现各种各样的逻辑结果,所以就必须对磁盘的存储结构做抽象。

磁盘存储的逻辑抽象结构:

  1. 将磁盘盘片想象成线性空间
  2. 整个磁盘就是sector sec[ ],即以扇区为单位的数组。
    1~100000 第一面,100001~200000 第二面 ......
    1~10000 第一个磁道,10001~20000 第二个磁道 ......
  3. 对磁盘的管理,就变成了对数组的管理。就可以完成由数组下标转化成对应磁盘的CHS地址。

操作系统 可以按照扇区为单位进行存取,也可以基于文件系统,按照文件块为单位进行数据存取。(文件块 ------ 8个扇区,4KB,文件保存属性和内容的基本单元)

从此操作系统不需要关系扇区或者磁道,只要文件块起始地址,就能一次连续访问8个扇区(4KB)。这个起始地址叫做LBA地址(Logical Block Addressing逻辑块地址)。

将磁盘看作4KB block[n](4KB大小的文件块数组),每一个4KB都有它对应的LBA起始地址,从此OS对磁盘的管理、对文件系统的管理,就变成了对文件块数组的管理。

例如有500GB的磁盘要进行文件管理,可以先把它们分区,每个区100G,然后再对每个区分组(每个组包含多个块) ,把一个组的空间管理好,那么其他组也可以按照这个方法管理,最后实现对500GB的磁盘文件管理。(在每个分区上创建文件系统,并使用组(groups)来管理文件系统

3.2 磁盘文件系统图

以下是磁盘文件系统的一个分区

Boot Block:启动块,位于文件系统的最前端( 例如编号为0的磁头、编号为0的盘面、编号为0的磁道的第一个扇区),用于启动操作系统。 它包含了文件系统的基本信息,如文件系统类型、磁盘有多少区,每个区的开始和结束位置等。
Block group:文件系统中的数据块组,包含文件信息和用于文件管理的数据。文件内容和属性分开存储。
在使用磁盘之前把磁盘分区,使用分区之前要先让管理数据写入到块组当中,这个工作叫做格式化。(把管理数据恢复出厂设置等)

使用 ls -li 文件属性列表最前面多了一列,这一列数字就是inode编号。

  • 一般情况一个文件一个inode,每个文件都有inode。
  • inode编号在整个分区具有唯一性。
  • 在Linux内核中,识别一个文件与文件名无关,只与 inode 有关

Inode Table:节点表,包含了文件的属性信息, 如文件名、创建时间、修改时间、访问权限等。

每个inode固定128字节,在节点表中也容易定位,只需要inode编号即可。

inode节点里有一个blocks数组,数组保存这个inode对应文件的blocks块号。数组大小一般为15(前13个1级映射,第14个2级映射,第15个3级映射)(数据文件块也可以放索引)(跨区/组存储是通过索引连接的)

Data blocks:数据区,用于存储文件的实际数据内容。 包含很多4KB的文件块,每个文件块也有对应的编号。

查找文件内容只需要知道文件的inode编号,就能定位在哪个区,通过inode里面blocks数组的内容可以查找到文件的内容。

Inode Bitmap:inode位图,通过比特位记录每个inode的状态,即哪些inode被占用,哪些inode是空闲的。例如1字节(8bit)可以记录8个inode的状态

Block Bitmap:块位图,用比特位记录每个数据块的状态,即哪些块被占用,哪些块是空闲的。

3.3 创建和删除文件

在Linux文件系统中,创建文件时,涉及以下步骤和组件的工作:

  1. 分配inode:文件系统从inode位图中分配一个空闲inode。将对应比特位 置为1,通过偏移量可以找到对应的inode,填充inode中的数据。
  2. 分配数据块:如果文件有数据,存储文件需要一些块,文件系统从块位图中分配一个或多个数据块来存储文件内容。通过偏移量可以得到块号,再将块号更新到 inode 中的blocks数组中。
  3. 更新目录:文件系统在父目录的目录项中添加新文件的inode编号,使其在目录中可见。

**删除文件时,只需要更改位图。**根据inode中blocks找到块位图对应的比特并置为0,根据inode编号将inode位图对应的比特清为0。表示inode、Data blocks无效。

文件恢复,需要inode编号,就能把inode位图的对应比特置为1,根据blocks找到块组,将块位图对应比特位置为1.

Group Descriptor Table:块组描述符,位于super block之后,用于描述每个数据块组的信息,包括该组内的块数量、inode数量等。

**Super Block:位于block group 的起始位置,包含了文件系统本身的结构信息。**不一定每一个块组都有。记录的信息主要有:bolck 和 inode的总量, 未使用的block和inode的数量,一个block和inode的大小,最近一次挂载的时间,最近一次写入数据的时间,最近一次检验磁盘的时间等其他文件系统的相关信息。Super Block的信息被破坏,可以说整个文件系统结构就被破坏了。

以上的文件系统称作 Ext2 文件系统。

3.4 如何理解目录?

用户不需要知道inode编号,只知道文件名。目录也是文件,有自己的数据块,目录内部保存的是文件的文件名和 inode 的映射关系(文件可以是任何文件)。所以用户访问一个文件时,只要找到文件所在目录,就能根据文件名找到对应的 inode 编号,然后就能找到对应的inode和数据块。这也说明了为什么同一个目录不能存在同名文件。也说明了为什么一个目录中新建、删除、修改文件需要目录的 w 权限。(需要新增、删除或修改映射关系)

inode中没有文件名,Linux中文件名不属于文件属性,只有inode编号,文件名在目录中存放。

3.5 如何查找一个文件

查找文件,需要知道文件所在的目录,找到目录文件并打开,目录文件的内容中就有文件名和inode编号的映射关系,根据inode编号找到文件所在分组、inode Table,就能找到inode,并将它的所有属性加载到内存里。(从根目录开始找,需要路径结构,用函数打开路径时要提供路径信息,pwd环境变量也会提高路径信息)

Linux会把高频访问的路径放在缓存里。struct dentry目录项是Linux内核中定义的一个数据结构,用于表示文件系统的目录项。它不是一个用户空间可访问的结构,而是内核空间的一部分。(struct dentry的定义可以在Linux内核源代码的fs/namei.c文件中找到)

3.6 查找文件的一般流程

  1. 用户输入文件路径,如/home/user/document.txt。
  2. 操作系统使用getcwd()函数或pwd环境变量来获取当前工作目录。
  3. 从根目录(/)开始,使用open()或stat()系统调用来访问路径的各个组成部分。
  4. Linux内核使用struct dentry数据结构来构建路径树,每个struct dentry实例代表路径树中的一个节点。
  5. struct dentry包含了文件名和 inode 编号的映射关系,以及指向父目录和子目录的指针,方便OS查找。
  6. Linux内核会尝试在struct dentry缓存中查找路径。如果缓存中有对应的struct dentry实例,则直接使用该实例,避免了对磁盘的访问。
  7. 如果缓存中没有对应的struct dentry实例,内核会继续沿着路径树向下查找,直到找到对应的目录项。
  8. 在每个目录中,内核会查找包含文件名的struct qstr,并将其与路径中的文件名进行匹配
  9. 一旦找到对应的struct dentry实例,内核会根据inode编号在inode表中查找对应的inode。inode包含了文件的属性数据,如权限、所有者、大小、创建和修改时间等。
  10. 内核将找到的inode的所有属性加载到内存中,这样就可以了解文件的具体信息。
  11. 一旦文件被找到,用户就可以使用open()、read()、write()等系统调用来访问文件。

Linux内核会尽量减少对磁盘的访问,以提高性能。

3.7 如何确定文件所在的分区

访问文件的时候,最开始是要知道这个文件在哪一个分区里面。因为虽然inode编号在整个分区具有唯一性,但是其它分区也可能会有相同的inode编号。(之前的创建、删除、查找文件讨论的都是在同一个分区的情况,一个分区一个文件系统)

一个磁盘被分区格式化之后,Linux中要使用这个分区,要把这个分区进行挂载(mount)。挂载将一个分区关联到一个目录,使得访问该目录时就可以确定哪个分区被访问和使用。

每一个文件都有路径,可以通过路径的前缀判断出路径在哪一个分区下。

3.8 总结

cpp 复制代码
int fd = fopen("./log.txt", "r");

这个函数做了哪些事?

答:

  1. **打开文件:**进程执行该函数操作,打开了这个文件。函数提供了路径、文件名、打开方式。
  2. **路径和文件名:**进程有自己的cwd,结合传入的路径,可以定位到文件在磁盘的哪个位置。
  3. **定位分区、上级目录:**根据路径确定分区、上级目录。
  4. **目录文件中的映射关系:**根据目录文件中的文件名和inode编号的映射关系能找到文件名对应的inode编号。
  5. **找到inode和属性加载:**通过inode编号就能找到inode,可以获得文件的属性。将inode的所有属性加载到内存中,创建一个struct inode对象。。
  6. **构建struct file对象:**内核使用inode构建struct file对象来代表这个文件,与文件描述符表连接,分配文件描述符,用户空间通过文件描述符fd来访问这个struct file对象。
  7. **预加载Data blocks数据块:**根据inode找到对应的Data blocks数据块,内核可以预加载文件的数据块到内存中的缓冲区。
  8. **读取数据:**当用户空间需要读取数据时,内核将内存缓冲区的数据拷贝到应用层。应用层可以访问这些数据,并进行进一步的处理。

四、软硬链接

4.1 引入

在Linux文件系统中,硬链接(Hard Link)和软链接(Symbolic Link)是两种不同的链接方式,用于在文件系统中创建指向文件或目录的链接。

通过ln -s 创建 log 文件的软链接,ln 创建 hello 文件的硬链接。

发现软链接的inode编号与源文件不同,而且还有箭头指向源文件;硬链接的inode编号与源文件相同,但硬链接数变为2。

说明软连接是一个独立的文件,硬链接不是独立的文件,因为他没有独立的inode编号。

4.2 软链接(Symbolic Link)

软链接 ,也称为符号链接或快捷方式,是一个特殊的文件包含指向另一个文件或目录的路径

软链接具有以下特点:

  • 包含路径:软链接包含一个路径,指向另一个文件或目录。
  • 可以跨越文件系统:软链接可以跨越不同的文件系统。
  • 占用额外空间:软链接有自己的inode编号,本身是一个文件,所以会占用额外的磁盘空间。有自己的数据块,修改了inode bitmap和block bitmap等。
  • 删除原始文件会影响软链接:如果原始文件(或目录)被删除,软链接将无法访问。
  • 它不指向原始文件的inode编号,而是指向原始文件或目录的路径。

软链接创建一个指向常用目录或文件的快捷方式,以便快速访问。

创建软链接的命令是 ln,需要指定 -s 或 --symbolic 选项,例如:

bash 复制代码
ln -s original_file symbolic_link_name

4.3 硬链接(Hard Link)

硬链接不是独立的文件,是在指定目录内部的一组映射关系:文件名 <-> inode 的映射关系!

硬链接用于创建与原始文件相同的inode编号的另一个文件名。

硬链接具有以下特点:

  • 指向同一inode:多个硬链接指向同一个inode,所以它们都指向相同的文件数据。
  • 不跨越文件系统:硬链接不能跨越不同的文件系统。
  • 不能指向目录:不能对目录建立硬链接,只能指向文件。
  • 不占用额外空间:硬链接不会占用额外的磁盘空间,因为它们都指向相同的inode。
  • 删除原始文件不影响硬链接:删除原始文件(inode)不会影响硬链接,因为硬链接仍然指向同一个inode。但是会将目标文件的硬链接数减1。

硬链接数:

没有文件名和inode映射时,文件被真正删除。inode中包含一个引用计数字段ret_count,表明有几个文件名和它映射。文件名在目录文件中具有唯一性,类似于指针,指向对应的inode,每增加一个文件名指向inode,inode的引用计数加1,每删除一个指向inode的文件名,引用计数减1。该引用计数也对应着硬链接数。

新创建文件时,硬链接数为1;新创建目录时,硬链接数为2。

因为目录创建时会包含两个因此的文件: . (当前目录).. (上级目录)

当前目录(.)的inode 和 目录的inode是同一个。同理,新创建目录时,包含该目录的上级目录的硬链接数变为3。

硬链接用来进行路径切换,构建了Linux的整个路径结构,方便进行路径回退。

创建硬链接的命令是 ln,例如:

bash 复制代码
ln original_file hard_link_name
相关推荐
Johny_Zhao5 分钟前
K8S+nginx+MYSQL+TOMCAT高可用架构企业自建网站
linux·网络·mysql·nginx·网络安全·信息安全·tomcat·云计算·shell·yum源·系统运维·itsm
稳联技术20 分钟前
Ethercat转Profinet网关如何用“协议翻译术“打通自动化产线任督二脉
linux·服务器·网络
烟雨迷29 分钟前
Linux环境基础开发工具的使用(yum、vim、gcc、g++、gdb、make/Makefile)
linux·服务器·学习·编辑器·vim
Bruk.Liu1 小时前
Linux 上安装RabbitMQ
linux·服务器·rabbitmq
UpUpUp……1 小时前
Linux--JsonCpp
linux·运维·服务器·c++·笔记·json
Willis_m2 小时前
Linux 服务器用 SSH 拉取多个 Git 工程
linux·服务器·git·ssh
紫金修道2 小时前
【Linux】在Arm服务器源码编译onnxruntime-gpu的whl
linux·服务器·arm开发
xq5148633 小时前
Linux系统下安装mongodb
linux·mongodb
柒七爱吃麻辣烫3 小时前
在Linux中安装JDK并且搭建Java环境
java·linux·开发语言
孤寂大仙v4 小时前
【Linux笔记】——进程信号的产生
linux·服务器·笔记