Linux操作系统(六):文件系统组件

news2024/11/24 18:51:02

参考资料:阿秀的笔记

文件系统

  • 1. 文件系统的基本组成
  • 2. 文件的使用
  • 3.文件如何存储
    • 3.1 目录怎么存储
  • 4.Linux继承于Unix系统的Unix文件实现方式
    • 4.1 Linux Ext 2/3 文件系统
    • 4.2 Linux Ext 4 文件系统
    • 4.3 磁盘空闲空间的管理机制
      • 4.3.1 空闲表法
      • 4.3.2 空闲链表法
      • 4.3.3 位图法(Linux系统使用的方法)
  • 5. 文件系统的结构
  • 6.文件怎么取别名
  • 7.文件怎么读写I/O
    • 7.1 缓冲与非缓冲 I/O
    • 7.2 直接与非直接 I/O
    • 7.3 阻塞与非阻塞 I/O VS 同步与异步 I/O

1. 文件系统的基本组成

Linux 「一切皆文件」不仅普通的文件和目录,就连块设备、管道、socket 等,也都是统一交给文件系统管理的。

在这里插入图片描述

如何唯一标识文件?索引节点 inode,记录了文件的元信息,比如 inode 编号、文件大小、访问权限、创建时间、修改时间、数据在磁盘的位置等等。存储在硬盘中占用磁盘空间

如何组织文件之间的关系?目录项directory entry,记录文件的名字、索引节点指针以及与其他目录项的层级关联关系。通过多个目录项的关联就能形成目录结构。目录项是由内核维护的一个数据结构,不存放于磁盘,而是缓存在内存

注意,一个文件可以有多个别名,所以目录项和索引节点的关系是多对一,即多个目录项中的索引节点可以指向同一个文件。

Linux中目录和目录项关系是什么?目录是个文件,持久化存储在磁盘,而目录项是内核一个数据结构,缓存在内存。由于查询目录频繁从磁盘读效率低,所以内核会把已经读过的目录用目录项这个数据结构缓存在内存,下次再次读到相同的目录时,只需从内存读就可以,大大提高了文件系统的效率。目录项可以视为一个表示目录的数据结构。

文件系统如何把文件存储在磁盘?磁盘读写的最小单位是扇区 512B,文件系统把多个扇区组成了一个逻辑块。Linux 中的逻辑块大小为 4KB。

磁盘为什么要分为三个储存分区?便于数据组织和管理,磁盘进行格式化时分成三个存储区域,分别是超级块、索引节点区和数据块区:

  • 超级块,用来存储文件系统的详细信息,比如块个数、块大小、空闲块等等;
  • 索引节点区,用来存储索引节点;
  • 数据块区,用来存储文件或目录数据。

超级块和索引节点区数据会在需要时加载到内存中:

  • 超级块:当文件系统挂载时进入内存;

  • 索引节点区:当文件被访问时进入内存

    文件系统的实现确实包含在内核中,但并不是所有文件系统信息都一开始就加载到内核空间中,而是根据需要进行加载和缓存,以提高性能和节省内存。文件系统首先要先挂载到某个目录才可以正常使用,比如 Linux 系统在启动时,会把文件系统挂载到根目录。

文件种类很多导致文件系统也很多,文件系统如何提供用户易用性?Linux系统会根据不同的需求和限制选择适合特定文件类型的文件系统,来更好地满足用户的需求,并提供更好的性能、可靠性和功能特性。

Linux 支持的文件系统也不少,根据存储位置的不同,可以把文件系统分为三类:

  • 磁盘的文件系统把数据存储在磁盘中,比如 Ext 2/3/4、XFS 等。
  • 内存的文件系统,数据占用内存空间,比如 /proc 和 /sys 文件系统,读写这类文件,实际上是读写内核中相关的数据。
  • 网络的文件系统,用来访问其他计算机主机数据的文件系统,比如 NFS、SMB 等等。

Linux为了对用户提供一个统一的接口,在用户层与文件系统层引入了中间层,虚拟文件系统(Virtual File System,VFS)。
在这里插入图片描述

2. 文件的使用

  VFS为不同的文件系统提供了一个抽象层次,隐藏了文件系统的具体实现细节。这使得内核可以支持多种不同的文件系统,而用户程序不需要关心文件系统的具体细节。VFS提供了文件描述符来进行读取、写入、关闭文件等操作。提供了虚拟的目录结构,用于管理所有已挂载的文件系统(Linux支持可插拔的文件系统模块,可以在运行时加载和卸载不同类型的文件系统,而不需要重新编译内核)。
  从用户角度来看文件的使用过程:
在这里插入图片描述

3.文件如何存储

请添加图片描述
在这里插入图片描述

3.1 目录怎么存储

  目录是一个特殊的文件。每个文件在存储时都用一个inode表(相当于索引了)来存放文件元信息,包含文件地址(指向的是数据块)等。
  目录的数据块里面保存的是目录里面一项一项的文件信息。
在这里插入图片描述
  保存目录的格式改成哈希表,对文件名进行哈希计算,把哈希值保存起来,如果我们要查找一个目录下面的文件名,可以通过名称取哈希。如果哈希能够匹配上,就说明这个文件的信息在相应的块里面。

  Linux 系统的 ext 文件系统就是采用了哈希表,来保存目录的内容,这种方法的优点是查找非常迅速,插入和删除也较简单,不过需要一些预备措施来避免哈希冲突。

  目录查询是通过在磁盘上反复搜索完成,需要不断地进行 I/O 操作,开销较大。所以,为了减少 I/O 操作,把当前使用的文件目录缓存在内存,以后要使用该文件时只要在内存中操作,从而降低了磁盘操作次数,提高了文件系统的访问速度。

4.Linux继承于Unix系统的Unix文件实现方式

  本节中的4.1和4.2讲述了Linux文件的存储如何实现,本质是针对已经写入数据的数据块的组织和管理。4.3讲述空闲空间管理,针对数据块应该放在硬盘上的哪个位置?最简单的思想就是将硬盘所有的区扫描一遍,找个空的地方随便放,但这样显然效率低下,所以引入了针对磁盘的空闲空间也是要引入管理的机制。

4.1 Linux Ext 2/3 文件系统

在这里插入图片描述
  在实际中采用了多级组合方式:
  第一级组合相当于索引:文件头中的inode(索引节点) 是一个数据结构,记录了文件在文件系统中的基本信息,包括文件的物理位置。从效果上相当于一个索引数据块,存放指向文件数据块的指针列表。
  通过第一级索引块来存放第二级索引块

  • 10 个指向数据块的指针;(如果存放文件所需的数据块小于 10 块,则采用直接查找的方式)
  • 第 11 个指向索引块的指针;(如果存放文件所需的数据块超过 10 块,则采用一级间接索引方式)
  • 第 12 个指向二级索引块的指针;(如果前面两种方式都不够存放大文件,则采用二级间接索引方式)
  • 第 13 个指向三级索引块的指针;(如果二级间接索引也不够存放大文件,这采用三级间接索引方式)

优点:解决大文件的存储
缺点:对于大文件的访问,需要大量的查询,效率比较低。

4.2 Linux Ext 4 文件系统

对Ext3文件系统的改进和扩展:

  • 支持更大的文件大小(最大16TB)和更大的分区大小(最大1EB),这使得Ext4更适合于处理大型文件和存储设备。
  • 改进的文件分配算法和数据结构,以提高文件的分配和管理效率。例如,采用了多级索引、延迟分配等技术来减少磁盘碎片化,并优化了空闲块管理算法。

       延迟分配(Delayed Allocation)是一种文件系统优化技术,旨在减少磁盘碎片化并提高文件写入性能。它的基本思想是推迟文件系统实际分配磁盘空间的时间,直到需要写入数据时才进行实际的分配。这种技术在磁盘写入过程中可以使得文件系统更有效地组织数据,从而提高文件系统的性能。

4.3 磁盘空闲空间的管理机制

4.3.1 空闲表法

在这里插入图片描述

  针对连续空间存放的文件存储方法,可以使用空闲表法:为所有空闲空间建立一张表,表内容包括空闲区的第一个块号和该空闲区的块个数。
  当请求分配磁盘空间时,系统依次扫描空闲表里的内容,直到找到一个合适的空闲区域为止。当用户撤销一个文件时,系统回收文件空间。这时,也需顺序扫描空闲表,寻找一个空闲表条目并将释放空间的第一个物理块号及它占用的块数填到这个条目中。
  使用场景:建立连续文件。少量的空闲区。

4.3.2 空闲链表法

在这里插入图片描述
  空闲链表法只要在主存中保存一个指针,令它指向第一个空闲块。当创建文件需要一块或几块时,就从链头上依次取下一块或几块。反之,当回收空间时,把这些空闲块依次接到链头上。

  其特点是简单,但不能随机访问,工作效率低,因为每当在链上增加或移动空闲块时需要做很多 I/O 操作,同时数据块的指针消耗了一定的存储空间。空闲表法和空闲链表法都不适合用于大型文件系统,因为这会使空闲表或空闲链表太大。

4.3.3 位图法(Linux系统使用的方法)

  在 Linux 文件系统就采用了位图的方式来管理空闲空间,不仅用于数据空闲块的管理,还用于 inode 空闲块的管理,因为 inode 也是存储在磁盘的,自然也要有对其管理。
  位图法利用二进制的一位来表示磁盘中一个盘块的使用情况,磁盘上所有的盘块都有一个二进制位与之对应。当值为 0 时,表示对应的盘块空闲,值为 1 时,表示对应的盘块已分配。它形式如下:

1111110011111110001110110111111100111 ...

5. 文件系统的结构

  数据块的位图是放在磁盘块里,一个块 4KB,每位表示一个数据块,共可以表示 4 ∗ 1024 ∗ 8 = 2 15 4 * 1024 * 8 = 2^{15} 410248=215个空闲块,,由于 1 个数据块是 4K 大小,那么最大可以表示的空间为 2 1 5 ∗ 4 ∗ 1024 = 2 27 2^15 * 4 * 1024 = 2^{27} 21541024=227 个 byte,也就是 128M。

提到 Linux 是用位图的方式管理空闲空间,用户在创建一个新文件时,Linux 内核会通过 inode 的位图找到空闲可用的 inode,并进行分配。如果采用「一个块的位图 + 一系列的块」,外加「一个块的 inode 的位图 + 一系列的 inode 的结构」能表示的最大空间也就 128M。

  所以Linux系统引入了块组结构。下图给出了 Linux Ext2 整个文件系统的结构和块组的内容,文件系统都由大量块组组成,在硬盘上相继排布:
在这里插入图片描述Ext2 文件系统的结构和块组的内容中

  • 引导块(boot block)是指存储引导加载程序(boot loader)的区域。
  • 块组(Block Group):结构
    • 超级块,包含的是文件系统的重要信息,比如 inode 总个数(每个文件都对应一个 Inode)、块总个数(存储文件内容的区域个数)、每个块组的 inode 个数(文件系统将 Inode 分为若干块组,每个块组包含一定数量的 Inode)、每个块组的块个数等等。
    • 块组描述符,包含文件系统中各个块组的状态,比如块组中空闲块和 inode 的数目等,每个块组都包含了文件系统中「所有块组的组描述符信息」。
    • 数据位图和 inode 位图, 用于表示对应的数据块或 inode 是空闲的,还是被使用中。
    • inode 列表,包含了块组中所有的 inode,inode 用于保存文件系统中与各个文件和目录相关的所有元数据。
    • 数据块,包含文件的有用数据。

6.文件怎么取别名

硬链接(Hard Link) :多个目录项中的「索引节点」指向一个文件,也就是指向同一个 inode,但是 inode 是不可能跨越文件系统的,每个文件系统都有各自的 inode 数据结构和列表,所以硬链接是不可用于跨文件系统的。
在这里插入图片描述由于多个目录项都是指向一个 inode,那么只有删除文件的所有硬链接以及源文件时,系统才会彻底删除该文件。

软链接(Symbolic Link):软链接相当于重新创建一个文件,这个文件有独立的 inode,但是这个文件的内容是另外一个文件的路径,所以访问软链接的时候,实际上相当于访问到了另外一个文件,所以软链接是可以跨文件系统的,甚至目标文件被删除了,链接文件还是在的,只不过指向的文件找不到了而已。
在这里插入图片描述

7.文件怎么读写I/O

7.1 缓冲与非缓冲 I/O

指在进行输入/输出(I/O)操作时数据的处理方式不同。
  缓冲 I/O 是指在进行 I/O 操作时,系统会先将数据从磁盘读取到内存缓冲区中,然后再从缓冲区中读取或写入数据到文件。这样的方式可以减少实际 I/O 操作的次数,提高效率。

例如,C/C++ 中的标准 I/O 函数(如 fread()、fwrite()、fgets()、fputs() 等)都是采用缓冲 I/O 的方式。

  非缓冲 I/O 是指在进行 I/O 操作时,数据直接从磁盘中读取或写入到目标文件,没有经过缓冲区的中间处理。如在通信领域或一些特殊的硬件操作中。

例如,Unix/Linux 中的 read() 和 write() 等系统调用就是非缓冲 I/O 的方式。

7.2 直接与非直接 I/O

关于数据传输时是否涉及的中间缓冲区
  直接 I/O 是指数据在进行输入/输出操作时,数据可以直接从用户空间(例如应用程序)直接传输到设备或文件系统,而无需经过内核缓冲区的中转。

例如在 Linux 中可以使用 O_DIRECT 标志来指示直接 I/O。程序直接将数据从用户空间写入到文件系统的某个位置,跳过内核空间的缓冲区,直接写入磁盘。

  非直接 I/O 是指数据在进行输入/输出操作时,数据必须先从用户空间复制到内核空间的缓冲区中,然后再从内核空间的缓冲区传输到设备或文件系统。

大多数操作系统默认采用非直接 I/O 的方式。内核可以更好地管理数据的传输,因此可能更加稳定可靠。

7.3 阻塞与非阻塞 I/O VS 同步与异步 I/O

阻塞与非阻塞 I/O:描述了程序在进行 I/O 操作时是否会暂停执行

  • 阻塞 I/O 是指程序在进行 I/O 操作时,如果无法立即得到结果,程序会暂停执行(阻塞),直到得到结果为止。
  • 非阻塞 I/O 是指程序在进行 I/O 操作时,如果无法立即得到结果,程序不会暂停执行,而是会立即返回一个状态指示暂时无法完成操作,然后程序可以继续执行其他任务。

    与异步 I/O 不同的是,非阻塞 I/O 下的程序并不会主动等待 I/O 操作完成的通知或结果。 相反,它会立即返回一个状态,告诉程序当前的 I/O 操作是否完成,然后程序可以根据这个状态继续执行其他任务,或者进行其他操作,而不需要等待 I/O 操作完成。

  • 阻塞 I/O 的优点是简单易用,但可能会造成程序在等待 I/O 完成时浪费大量的时间。非阻塞 I/O 则可以让程序更加灵活地处理 I/O 操作,但需要额外的代码来处理返回的状态。

同步与异步 I/O:述了程序在发起 I/O 操作后是否需要等待操作完成。

  • 同步 I/O 是指程序在发起 I/O 操作后,需要等待操作完成才能继续执行后续的任务,即发起 I/O 操作的线程需要主动等待 I/O 操作完成。
  • 异步 I/O 是指程序发起 I/O 操作后,不需要等待操作完成,而是可以继续执行后续的任务,当操作完成后会得到通知,或者由另一个线程来处理完成的操作。
  • 同步 I/O 的优点是编程模型简单,易于理解和控制,但可能会造成程序在等待 I/O 操作完成时浪费大量的时间。异步 I/O 则可以让程序更加高效地利用系统资源,但需要额外的处理机制来处理操作完成的通知。

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

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

相关文章

网易云歌曲评论抓取

网易云歌曲评论爬取 步骤1.找到一首歌曲2.按下F12键打开开发者模式,对其进行抓包3.查找获得评论数据的接口4.对获得评论数据接口进行分析5.构建加密函数方法一方法二运行结果全部代码使用Js文件只使用python新的代码小结与展望这次的任务是获取网易云音乐下面的评论,涉及的知…

安卓四大组件——Service篇

1.作用 长时间位于后台(无界面)完成用户指定操作 1.1两类状态 (a)started(启动):当应用程序组件(如activity)调用startService()方法启动服务时,服务处于sta…

HJ1 字符串最后一个单词的长度(字符串,import java.util.HashSet;)

import java.util.Scanner;// 注意类名必须为 Main, 不要有任何 package xxx 信息 public class Main {public static void main(String[] args) {Scanner sc new Scanner(System.in);// 注意 hasNext 和 hasNextLine 的区别int num sc.nextInt();boolean[] in new boolean[…

设计模式学习笔记 - 设计模式与范式 -行为型:8.状态模式:游戏、工作流引擎中常用的状态机是如何实现的?

概述 本章学习状态模式。在实际的开发中,状态模式并不是很常用,但是在能够用到的场景里,它可以发挥很大的作用。从这一点上看,它有点像我们之前讲到的组合模式。 状态模式一般用来实现状态机,而状态机常用在游戏、工…

✌2024/4/3—力扣—整数反转

代码实现: int reverse(int x) {long num 0;while (x ! 0) {num num * 10 x % 10;x x / 10;}if ((int)num ! num) {return 0;}return (int)num; }

使用手动连接,将登录框中的取消按钮使用qt4版本的连接到自定义的槽函数中,在自定义的槽函数中调用关闭函数

使用手动连接,将登录框中的取消按钮使用qt4版本的连接到自定义的槽函数中,在自定义的槽函数中调用关闭函数 将登录按钮使用qt4版本的连接到自定义的槽函数中,在槽函数中判断ui界面上输入的账号是否为"admin",密码是否为…

Houdini笔记操作技巧_集锦

个人记录下,谨防遗忘。同时丰富下Hou的中文搜素环境。 1、自定义启动界面 ① 设置完界面后,保存自定义界面(Save Current Desktop As...) ② Edit-->Preferences-->General UIInterface-->Startup in Desktop&#xff1…

qt打包程序打包之跨平台

本文讲的是linux系统中的程序打包,首先我们创建一个简单的程序,我的程序叫做debtest 然后设置qmake来源,这个直接决定了程序依赖的qt库的位置,如果我们需要指定qt标准库的位置,那么qt环境就需要在那个位置。 修改前&am…

C# 如何修改项目名称

目录 背景具体步骤1、Visual Studio中修改项目名和程序集名称以及命名空间2、修改项目文件夹名3、修改解决方案里项目的路径4、再次打开解决方案,问题解决步骤总结 名词解释解决方案(Solution)项目(Project)程序集&…

【操作系统】CentOS7入门级安装

下载镜像 CentOS镜像下载Download (centos.org) 我们选择第一个 X86_64 CentOS Mirrors List 版本描述X86_X64带64位的32位扩展版(一般安装这个)ARM64 (aarch64)嵌入式。适用于微端(树莓派、机械臂、机械中控)IBM Power (ppc64le)专用于IBM POWER服务器 选择一个合适的链接 …

DSL - Wire 实现-ApiHug101

🤗 ApiHug {Postman|Swagger|Api...} 快↑ 准√ 省↓ GitHub - apihug/apihug.com: All abou the Apihug apihug.com: 有爱,有温度,有质量,有信任ApiHug - API design Copilot - IntelliJ IDEs Plugin | Marketplace docs/ha…

javaScript手写专题——防抖/节流/闭包/Promise/深浅拷贝

目录 目录 一、 防抖/节流/闭包/定时器 编写一个组件,在input中输入文本,在给定的数据中查找相关的项目,并渲染搜索结果列表 1.新增InputSearch.vue组件 key的作用 2.新增 InputView.vue 3.添加路由 4.效果演示 follow up加上防抖怎么处理 1.…

如何从头开始编写LoRA代码,这有一份教程

ChatGPT狂飙160天,世界已经不是之前的样子。 新建了免费的人工智能中文站https://ai.weoknow.com 新建了收费的人工智能中文站https://ai.hzytsoft.cn/ 更多资源欢迎关注 作者表示:在各种有效的 LLM 微调方法中,LoRA 仍然是他的首选。 LoRA&…

机器学习-随机森林算法预测温度

文章目录 算法简介解决问题获取数据集探索性数据分析查看数据集字段信息查看数据集综合统计结果查看特征值随时间变化趋势 数据预处理处理缺失数据字符列编码数据集分割训练集、验证集、测试集数据集分割 构建模型并训练结果分析与评估进一步优化实际使用经验总结 算法简介 随…

基于遗传优化的SVD水印嵌入提取算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 基于遗传优化的的SVD水印嵌入提取算法。对比遗传优化前后SVD水印提取性能,并分析不同干扰情况下水印提取效果。 2.测试软件版本以及运行结果展示 MA…

深度学习实践(一)基于Transformer英译汉模型

本文目录 前述一、环境依赖二、数据准备1. 数据加载2. 构建单词表程序解析(1)将列表里每个子列表的所有单词合并到一个新列表(没有子列表)中。(2)Counter()-- 统计迭代对象各元素出现…

【Spring AOP】@Aspect结合案例详解(一): @Pointcut使用@annotation + 五种通知Advice注解(已附源码)

文章目录 前言AOP与Spring AOPAspect简单案例快速入门 一、Pointcutannotation 二、五种通知Advice1. Before前置通知2. After后置通知3. AfterRunning返回通知4. AfterThrowing异常通知5. Around环绕通知 总结 前言 在微服务流行的当下,在使用SpringCloud/Springb…

Mogdb双网卡同步最佳实践

大家都知道Oracle数据库无论是单机还是RAC集群在进行生产部署实施时,我们都会对网卡做冗余考虑,比如使用双网卡,比如public、心跳网络。这样的目的主要是为了安全,避免淡点故障。当然也网卡Bond不仅是可以做主备还可以支持负载均衡…

redis分布式锁+redisson框架

目录 🧂1.锁的类型 🌭2.基于redis实现分布式 🥓3. 基于redisson实现分布式锁 1.锁的类型 1.本地锁:synchronize、lock等,锁在当前进程内,集群部署下依旧存在问题2.分布式锁:redis、zookeeper等…

OLAP介绍

OLAP OLAP介绍 Rollup OLAP(在线分析处理)的上下文中,"Rollup"是一个重要的概念,它指的是在多维数据集中自动地聚合数据到更高的层次或维度的过程。这种操作通常用于快速计算和展示汇总数据,以便于用户进…