突破教材,简单聊聊《文件系统》

文章目录

  • 前言:
  • 文件系统的引入:
    • 认识物理磁盘:
  • 对磁盘的存储进行逻辑抽象:
    • LBA逻辑区块地址:
  • 🚀文件系统的理解:
    • 理解各个区段:
    • 🛹深入理解 inode:
      • inode和文件名?
      • 如何确定inode在哪个分区?
        • 为什么路径那么重要?
        • 目录和分区的关系?

前言:

​ 我们在前面的学习中学习诸如:C语言打开操作文件、通过系统调用打开操作文件甚至说是对文件的重定向操作。对于上述的操作,我们本质是先将文件打开,再对其进行处理。打开文件的操作本质是在内存中申请空间,创建文件描述符,再创建struct file结构体用来管理磁盘中的文件内容,最后通过映射关系,可以对一个文件进行读和写的操作。
​ 那么我们之前学习的都是对打开的文件进行处理的,那对于那些没打开的文件呢?要知道,打开的文件是少数,而哪些没被打开的文件可是大量的!而这些没被打开的文件均在磁盘或者说是硬盘中存储着呢(硬盘我们今天不谈),所以我们以前要打开一个文件其实是要先在磁盘中通过文件路径 + 文件名找到。那到底磁盘是怎么存储的呢?怎么构建整个文件系统的呢?所以本章我们要来好好聊聊一个文件在未被打开的时候,都在磁盘中做了什么呢?又或者说哪些“家伙”对这些文件做了什么呢?

文件系统的引入:

认识物理磁盘:

image-20240902154416860

俯视着看只能看个大概的情况,而整个磁盘最核心的部分其实就是磁盘和和磁头那一块像CD一样的结构,他其实不止含有一个磁头也不仅仅含有一个磁盘片。
image-20240902154818864

我们的在磁盘中存储的未打开的文件,就存储于该结构上,具体的位置就是盘片上的每一个小小的连续的扇区(sector)中
image-20240904083646274

其实我们那些未打开的文件,在磁盘中存储就是在每一个盘片上对应的扇区中,进行数据的存储一般都是用一个个连续的扇区来进行存储,通过二进制的方式来进行写入
那为什么是二进制呢?————因为计算机只认识二进制
我们都知道,二进制里面的数字不是0就是1的,那究竟什么是0、1呢?
————其实0和1只是一个个代表,真正的体现就体现在物理层面的不同。

而在磁盘中,对于扇区(sector)中,编写二进制的本质其实是通过磁铁来改变每个扇区每个bit位的南北极,可能1就是北极,0就是南极。通过这种来实现数据的存储,所以我们的数据约等于是被刻在上面的,然后需要查找时候就去找对应的那个磁片,磁片的哪个面,磁片中的哪一个磁道(柱面)(cylinder),再在柱面中找到对应的一串扇区(sector)

对于磁盘更详细的介绍,可以观看视频:
磁盘是如何工作的
你的硬盘是如何存储数据的

所以我们上述所讲解的,如何找到一个指定位置的扇区:

  1. 找到指定的磁头 —— Header
  2. 找到指定的磁道(柱面) —— Cylinder
  3. 找到指定的扇区 —— Sector

这就是我们的 CHS定址法

对磁盘的存储进行逻辑抽象:

​ 我们都知道,对软硬件资源做管理的就是操作系统,那么磁盘属于硬件,那么操作系统又该如何管理呢?谈及管理永远六个字 —— “先描述, 再组织”
​ 既然是管理,那你的意思就是我可以直接用OS来实现CHS定址法,然后在磁盘中找到文件咯?当然这是不对的,磁盘有着很多不同版本和型号,磁盘一旦更新,操作系统对应管理的软件也会进行更新,一两个软件还好,但是一旦涉及到成千上万个软件那就没有必要了,耦合度太高。所以其实操作系统是通过**LBA(逻辑区块地址)**来进行管理的。
image-20240904092912396

相信我们都见过磁带,他们可以卷在一起形成圈,也可以散开形成一条线,所以,我们抽象就是将这几面盘面的大小抽象成一个线性数组。每一个磁道(cylinder)都有很多个扇区,将同一个磁道上的全部扇区“拉”成一条:

image-20240904093453571

这样我们可以暂时抽象理解为查找扇区的位置,就是通过下标来进行查找。

这个只是我们逻辑抽象的概念,那其实操作系统想要实现管理但又不能直接使用CHS定址法,操作系统又是通过什么算法使得硬件实现CHS呢?
假设一个磁盘上面的磁有1000个扇区和10个磁道。那么1000 / 10 = 100 就代表着1个磁道有100个扇区
但是如果我们的操作系统知道了某个文件target的下标(index),我们就可以知道这个文件他是在哪个面、磁道和扇区

  1. 因为一个面有1000个扇区,那么第一个面扇区我们可以抽象理解为一个下标从 0 ~ 999 的数组,第二个下标就是 1000 ~ 1999 的数组。所以假设我的index == 3456,我们 index / 1000 == 3,就可以得知该文件是在哪个磁片(也就是找到了磁头Header)

    image-20240904102102349

  2. 对应该磁头找到对应的磁片后,我们需要来确定我们的index在哪个磁道上。现在我们知道一个磁面上有10个磁道,所以最后的磁道肯定是1号磁道到10号磁道[1, 10]的,而一个磁道有100个扇区,所以最后你的扇区下标肯定是在[0, 99]之间的。所以我们先来确定磁带:3456 % 100 == 456,这个是排除磁面后的数据,再 456 / 100 == 4得到再第4号磁道上,这一步是依据你的磁道只能是在[1, 10]上的。
    image-20240904103159171

  3. 接下来我们就要确定扇区位置,其实现在我们就很好理解了,那么扇区的位置只要对我们刚刚处理好的456在模上100就好了,因为扇区的下标只能在[0, 99]之中,这样456 % 100 == 56,就能确定扇区是在56号下标开始。
    image-20240904103801562

LBA逻辑区块地址:

​ 现在我们知道了磁盘对文件数据存储的逻辑抽象,其实文件里面的内容和属性 == 很多个扇区(sector)的数组的下标。一般而言,OS未来和磁盘交互的时候,基本单位:4KB
​ 而一个sector的大小默认为512字节,所以一个OS在从磁盘读取文件的时候,是基于8个连续的扇区(sector)来读取的!

所以我们就可以将上述逻辑抽象出来的数组进行分区块来描述
image-20240904105617379

而这些分好出来的几号几号“块”,这就是我们的**LBA(逻辑区块地址)**。

假设像上述一样给每个“块”进行编号,就有如上0号块、1号块、2号块等等…
那么通过编号我们就能知道对应”块“的起始下标:0 * 8 == 0,1 * 8 == 8,2 * 8 == 16。像0、8、16就是对应0号块、1号块、2号块的起始下标。

1、所以现在,我们只要知道了你当前的文件处于哪一个“块”,那我们就一定能找到这个块的位置,块找到了那么在这个连续的数组上,我对应的扇区(sector)在哪里就知道了
而你的一个一个的磁道是同心圆,那么你一条路一直走下去,你肯定可以走到头的,所以你这个磁道有多少个扇区(sector)你就肯定可以知道!因此只要你能找到磁道,一个磁道有多少个扇区你肯定可以知道

2、假设你知道一个磁片上全部扇区有多少,那么你又由上述知道了一个磁道上有多少个磁片,那么你当然可以知道一个磁面上有多少个磁道。

所以只要你知道了一个块号和磁盘的总扇区大小(一共有多少个块),就可以知道全部信息,包括有多少个磁道啦、多少个扇区啦,甚至说每个扇区的对应的每个块号,以及对应的CHS地址!

🚀文件系统的理解:

​ 基于上面了理解,可以总结出操作系统对于文件的管理是分组区块进行管理的!但是你看像我们的磁盘,它可是800GB左右甚至更高的容量来存储的,对于这么大的数据量,你还在那8个sector8个sector的数,那你得多累?而且更重要的是,对于这么大的数据操作系统也不好管理呀!

于是我们的操作系统就会告诉用户,你可收到以进行磁盘分区啦!
image-20240904132026248

这就是我们在windows上进行分区之后的结果,分为了C、D、E盘。不仅仅可以对数据进行区别,也可以方便操作系统进行更方便的管理
image-20240904132407111

现在我们拿到了所谓的区块,但是我们想要管理好每一个分区,我们还需要对分区进行分组:
image-20240904133840592

如此一来,我们对分区的管理就又可以继续往下细分管理了。但是,这只是我们所描述的,我们这么描述只是更方便了些,可是操作系统考虑到的东西可不仅仅是方便喔,操作系统还要对这个分区进行管理喔。所以操作系统肯定也会对磁盘进行分组,但是它考虑的东西就多得多
image-20240904134334998

这才是操作系统对磁盘管理的真正样子,而计算机和人不一样,如果它能将一个分区细分出这么组,那么其它分区也可以细分出这么多组,如果一个组能被操作系统管理好,那么其它组也能被操作系统管理好,所以整个文件系统它终将会被管理好!

但是这是针对于Linux的!因为我们知道文件 = 属性 + 内容,而在linux中,文件内容和文件属性是分开存储的!我们的文件内容就存放于Data blocks中,而文件属性则存放于inode Table中!下面我们就来介绍介绍这几个小玩意。

理解各个区段:

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

  • Data blocks(数据区):存放文件内容,实际上该区间特别大,有很多很多的数据块(大小为4KB)
    image-20240904135408973

  • Block bitmap(块位图):记录者Data block中那个数据块被占用了,哪个没有被占用。
    image-20240904140111442

  • 🧨inode Table(i节点表):存放文件属性,存放文件属性 如 文件大小,所有者,最近修改时间等

    Linux中文件的属性是一个大小固定的集合体。

    struct inode // 文件属性
    {int size;int time;int inode_number;int datablocks[N];
    };
    

    image-20240904140624706

    一个正常的文件都对应着一个inode集合。
    我们可以通过输入指令:ls -li 查看当前目录文件下的inode number

    image-20240904141048669

    在inode内部,我们不包含文件名!从内核层面上来看,每一个文件都要有inode number

  • inode Bitmap(inode位图):每一个bit表示一个inode是否空闲可用,比特位的位置表示第几个inode(inode number),比特位是0还是1表示是否被占用。

  • Super Block (超级块):存放文件系统本身的结构信息。记录的信息主要有:bolck 和 inode的总量,
    未使用的block和inode的数量,一个block和inode的大小,最近一次挂载的时间,最近一次写入数据的
    时间,最近一次检验磁盘的时间等其他文件系统的相关信息。Super Block的信息被破坏,可以说整个
    文件系统结构就被破坏了 。
    Super Block 为了使文件系统稳定,会在部分组里出现super block,记录当前盘的全部inode的信息等。这个作用就是假设未来我们出现了文件损毁,系统会提示我们是否要进行修复。本质上是一个租的superblock坏了,要将其它的super block的内容复制到损坏的super block中,所以各个super block中的数据必须要保持一致。

对每一个分区内部分组(这就叫==“格式化”==),为了以后能够写入文件系统的管理和数据

🛹深入理解 inode:

  • 创建新文件时,怎么通过 inode number 定位 inode Bitmap 对应的位置?

​ 我们在寻找文件的时候,都必须先的到文件的 inode在inode Table中的位置号,inode 是以“分区”为单位的,即以各个盘为单位的(不能跨分区访问)!

​ 我们在刚开始创建新文件的时候,super block 和 Group Description table 会确定 inode number 的范围。然后拿着新文件的 inode number 在当前分区中(不可跨分区访问),一个一个比对从而可以发现该文件属于哪个组,找到该组后,通过新文件的 inode number 减去前该组的 start_inode ,得到的数就是对应 inode Bitmap 和 inode Table 的位置。
image-20240904165244736

​ 假设一个新文件的 inode number 是1030,那么该文件就存在于 group B。
​ 为了确定该文件的 inode Bitmap 和 inode Table 的位置,将1030 - 1000 == 30号,该30号就是该组中 inode Bitmap 中对应位图的号,而这个时候OS就会在inode Bitmap的30号位置的bit位设置为1,对应的inode Table的30号也会出现于一个结构体inode,记录了这个新文件的各种信息。不仅仅是创建,我们在查找的时候,OS也是这么去查找的!

  • 那如何定位 blocks Bitmap呢?
    我们在讲解inode的时候,发现inode结构体里面有一个成员变量:int datablock[N]
    image-20240904172243321
    那么这个东西其实就是一个数组了,里面存放着文件内容对应的 Data blocks 中的号码,而这些号码会从block Bitmap中去读取,然后指向对应的号码。
    但是在linux中一般只有15个元素那么一个文件只能存60KB?前12个元素确实如此,但是第13,14个元素并不是单纯的映射,15个更是重量级。
    image-20240904173516507

    蓝色的就代表第12、13、14号元素是一级映射,第15号是二级映射,当然图只是简单的描述,现实肯定更复杂!

    我们是有能力存大文件的!甚至跨组,但是不建议,因为这样磁头与盘片又会旋转重新寻址,造成效率低下!

inode和文件名?

问题来了,我们在上层使用的都是文件名啊,可是系统都是用inode编号进行标识,那么怎么进行联系呢?

  • 首先我们来谈谈目录
    目录本身就是一个文件,目录 = 文件属性 + 文件内容(内容包含文件名inode编号的**映射关系**)
    所以我们在上层不用inode编号,使用文件名即可对文件进行各种操作。
    1. 因为一个文件名只有一个对应的inode 和 inode number,所以一个目录下不能建立同名文件。
    2. 我们查文件的信息,靠的是文件名和inode number之间映射关系找到inode,再通过inode number找到对应的组别和当中的inode table的所以属性
    3. 关于目录的r权限,本质就是是否允许我们读取目录的内容,与inode和文件名的映射有关。
      关于w权限也相似
    4. 如何理解一个文件的增删查改
      ▷创建新的inode,再通过 inode bitmap 在 inode table 写入对应的属性,最后在data block中写入数据。
      删除
      ▷删除其实很好理解,我们只需将inode bitmap 和 block bitmap 对应的 ’1‘ 改为 ’0‘即可,属性那一块可以不用处理,因为属性那一块迟早会被覆盖,这也就解释了为什么拷贝文件要很久,而删除文件也就一瞬间就删除完了!

如何确定inode在哪个分区?

为什么路径那么重要?

通过上面的介绍,关于存储文件可以组织成以下:

找到指定的文件 -> 找到该文件的目录 -> 打开目录 -> 找到inode与文件名映射关系 -> 找到inode进而找到属性与内容。

​ 可是我们在这一串关系中仔细一些会发现一个奇怪的现象,找到该文件的目录,我们如果需要实现这一条件也需要找到目录的目录呀。
​ 想要找到某个文件,就要找到这个文件夹,找到这个文件夹就要找到文件夹的文件夹… 如此我们最后只能找到根目录时我们才会停下来。

根目录是系统规定出来的,在我们OS开机时就要知道根目录在哪里,所以我们要找到一个文件需要逆向的文件路径解析—OS自己做的

所以,为什么我们在定位一个文件,无论在什么时候,都需要路径的!

所以我们在ls时本质是这样的!可是有人会说我们在执行ls这样的命令就没有带路径啊
这是因为我们的ls是个进程,进程有自己的cwd(当前路径)

那么这样次次会不会太麻烦呢?
不用担心,我们的系统会缓存常用路径结构。

如果路径太多了是不是也需要管理呢?
那是不是就需要先描述再组织?

所以我们文件还有一个内核结构体struct dentry用来描述文件路径。
所以我们的struct除了有指向方法表与缓冲区,现在又多了一个指向路径解析的结构体,这个结构体是内核层面,而不是磁盘级层面的。

目录和分区的关系?

​ 我们在对以上进行分析的时候,都是以某一个确定的分区为前提,可是inode编号在不同分区内可能会一样啊,我们怎么确定自己是在那个分区呢?
我们可以先来查看我linux系统下的分区: 输入 ls /dev/vda
image-20240904180718053
我们可以看到我们有一个磁盘vda和一个分区vda1.

那我们再看看它们的属性叭,输入df -h
image-20240904180933533

这里有这么一行代码:/dev/vda1 40G 4.4G 33G 12% /
这个意思就是将这个分区 ==挂载==到了根目录,
挂载的意思就是将一个设备(通常是存储设备)挂接到一个已存在的目录上。访问这个目录就是访问该存储设备。

所以我们在根目录下进行操作时就已经代表我们在那个确定的分区了!

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

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

相关文章

动态化-鸿蒙跨端方案介绍

一、背景 👉 华为在2023.9.25官方发布会上宣布,新的鸿蒙系统将不再兼容安卓应用,这意味着,包括京东金融APP在内的所有安卓应用,在新的鸿蒙系统上将无法运行,需要重新开发专门适用于新鸿蒙系统的专版APP。 …

Windows安装使用Docker

配置Dorker环境 启用或关闭windows功能 安装wsl 以管理员身份打开windows PowerShell,安装相关配置 下载docker应用程序 Releases tech-shrimp/docker_installer (github.com) 安装Docker 指定安装位置 默认双击程序就开始安装了,要安装在指定位置…

iOS P8证书推送测试

最近在配合服务端人员调试相关的 APNS auth key 推送的问题,相比于苹果的P12证书的推送,P8证书的推送显得方便很多,P8的优势在于简单,安全 容易生成 最重要的是不会过期。 现在我们来看下测试具体流程: 方法一 地址…

ESP-DL部署魔改MobilenetV1—3. 模型部署

在完成模型训练和模型量化后,就可以开始我们的模型部署了。这部分的关键在于Model类中层的初始化以及build和call的实现。 环境依赖 esp-idf > 5.0esp-dl 模型定义 在模型定义时,我们需要用到量化时输出的层信息、cat_vs_dog_coefficient.hpp&…

分析源码学习c++(srs中http客户端)

文章目录 背景基础知识c标准库虚函数虚函数使用方法 虚析构函数 HTTP客户端使用方法TCP传输层分析使用方法结构分析连接函数读写函数 协议层分析初始化函数发送请求响应数据解析 背景 通过阅读源码,编写分析笔记来学习C是一种非常有效且深入的方法,能帮助…

论文解读 | ACL2024 Outstanding Paper:因果指导的主动学习方法:助力大语言模型自动识别并去除偏见...

点击蓝字 关注我们 AI TIME欢迎每一位AI爱好者的加入! 点击阅读原文观看作者直播讲解回放! 作者简介 孙洲浩,哈尔滨工业大学SCIR实验室博士生 概述 尽管大语言模型(LLMs)展现出了非常强大的能力,但它们仍然…

数据源10min自动断开连接导致查询抛异常(未获取可用连接)

由于个人能力有限,本文章仅仅代表本人想法,若有不对请即时指出,若有侵权,请联系本人。 1 背景 工作中引入druid来管理数据源连接,由于数据源每隔10分钟强制管理空闲超过10分钟的连接,导致每隔10分钟出现1…

Web攻防之应急响应(二)

目录 前提 🍔学习Java内存马前置知识 内存马 内存马的介绍 内存马的类型众多 内存马的存在形式 Java web的基础知识: Java内存马的排查思路: 🍔开始查杀之前的需要准备 1.登录主机启动服务器 2.生成jsp马并连接成功 …

【Linux】多线程:线程概念,线程与进程的区别与联系,多线程相较于多进程的优势

目录 一、进程基本属性回顾 二、线程概念 三、操作系统为什么要引入线程—多进程和多线程的区别 为什么多线程比多线程调度效率更快? 四、线程的优点 五、线程的缺点 六、线程异常 一、进程基本属性回顾 在学习线程之前,我们先来回顾一下进程的基…

注册安全分析报告:熊猫频道

前言 由于网站注册入口容易被黑客攻击,存在如下安全问题: 暴力破解密码,造成用户信息泄露短信盗刷的安全问题,影响业务及导致用户投诉带来经济损失,尤其是后付费客户,风险巨大,造成亏损无底洞…

【Rust】007-包管理与模块管理

【Rust】007-包管理与模块管理 文章目录 【Rust】007-包管理与模块管理一、包管理器:Cargo1、简介Cargo 官方文档仓库 2、项目初始化3、写一个小程序任务目标寻找合适的库添加库到我们的项目中代码实现cargo run运行 二、模块管理1、概述2、文件作为模块第一步&…

前端模拟面试:如何检查JavaScript对象属性是否存在?

你正在参加一场关键的前端开发面试,面试官提出了一个经典的JavaScript问题:“在JavaScript中,如何检查对象是否包含某个属性?请你详细介绍几种不同的方法,并解释它们的区别。” 这个问题不仅考验你对JavaScript的基础掌…

怎样在公司将手机屏幕(远程)投屏到家里的大电视上?

我不住家里,前几次回去都会替老爸老妈清理手机。这两个星期没空回去,老爸吐槽手机用几天就又卡了,其实就是清理一些手机缓存的问题。 我说我远程控制他的手机,给他清理一下。他一听“控制”就不喜欢,说我大了&#xf…

sM4040B科学级显微制冷相机特性

sM4040B科学级显微制冷相机特性 sM4040B搭载了 GSENSE4040BSI 3.2 英寸图像传感器,针对传感器固有的热噪声,专门设计了高效制冷模块,使得相机传感器的工作温度比环境温度低达 35-40 度。针对制冷相机常见的低温结雾现象设计了防结雾机制&…

【Python百日进阶-Web开发-音频】Day707 - 时域处理 librosa.autocorrelate

文章目录 一、时域处理1.1 librosa.autocorrelate1.1.1 语法与参数1.1.2 例子1.1.2.1 计算完全自相关y1.1.2.2 计算长达 4 秒的起始强度自相关 一、时域处理 1.1 librosa.autocorrelate https://librosa.org/doc/latest/generated/librosa.autocorrelate.html 1.1.1 语法与参…

哪款宠物空气净化器能更好的清理浮毛?希喂、352、IAM测评分享

家里这三只可爱的小猫咪,已然成为了我们生活中不可或缺的家庭成员,陪伴我们度过了说长不长说短不短的五年时光。时常庆幸自己当年选择养它们,在我失落的时候总能给我安慰,治愈我多时。 但这个温馨的背后也有一点小烦恼&#xff0…

记一种常用的实时数据同步方案:Canal+Kafka+Flume

记一种常用的实时数据同步方案:CanalKafkaFlume 在当今数据驱动的业务环境中,数据同步是确保系统间数据一致性的关键环节。一种高效、稳定且可扩展的数据同步方案对于支撑企业的数据处理和分析需求至关重要。本文将介绍一种结合了Canal、Kafka和Flume的…

IOS 20 发现界面(UITableView)歌单列表(UICollectionView)实现

发现界面完整效果 本文实现歌单列表效果 文章基于 IOS 19 发现界面(UITableView)快捷按钮实现 继续实现发现界面歌单列表效果 歌单列表Cell实现 实现流程: 1.创建Cell,及在使用UITableView的Controller控制器上注册Cell&#x…

STM32F103C8----GPIO(跟着江科大学STM32)

一,GPIO简介 GPIO(General Purpose Input Output)通用输入输出口 可配置为8种输入输出模式 引脚电平:0V~3.3V(0V),部分引脚可容忍5V 输出模式下可控制端口输出高低电平,用以驱动…

AI-Talk开发板之LED

一、说明 AI-Talk开发板上有一颗用户LED,连接在CH32 PA2管脚,低电平亮,高电平灭。 相关电路图如下: 需要提前给CH32V003烧录特定的固件才能将CH32作为CSK6011A的exmcu,参考AI-Talk开发板更新CH32固件。​​​​​​​…