存储基石:深度解读Linux磁盘管理机制与文件系统实战

Linux系列


文章目录

  • Linux系列
  • 前言
  • 一、磁盘
    • 1.1 初识磁盘
    • 1.2 磁盘的物理结构
    • 1.3 磁盘的存储结构
    • 1.4 磁盘的逻辑结构
  • 二、文件系统
    • 2.1 系统对磁盘的管理
    • 2.2 文件在磁盘中的操作


前言

Linux 文件系统是操作系统中用于管理和组织存储设备(如硬盘、SSD、USB 等)上数据的一种核心机制。本篇我们将操作系统如何对未打开的文件进行管理的。


一、磁盘

磁盘是是计算机硬件中的唯一的机械设备,被广泛的运用于企业级存储,学习磁盘对数据的存储,对我们学习操作系统的文件系统有很大帮助。

1.1 初识磁盘

随着计算机行业的发展,磁盘由于存储效率较低,慢慢的在我们的私人电脑中被固态硬盘所替代,但是在企业中,磁盘依旧是存储的主流。这是因为:
1、相较于固态硬盘来说,磁盘的成本较低。
2、磁盘虽然效率低,但是容量较大,在企业中往往存在海量的不常访问数据需要保存,所以磁盘就成了比较适合的选择,
3、固态硬盘在存储和删除数据是对自身会有一定损耗,长时间的使用会有数据丢失的风险。

1.2 磁盘的物理结构

在这里插入图片描述
一个磁盘会包含好几个盘片,每个盘片具有两个盘面,这两个盘面都会进行数据存储,每个盘面都会配有对应的磁头,在工作时,磁盘会在主轴的带动下开始旋转,磁头则会在磁臂的带动下开始水平摆动,这个过程磁头并不会和磁盘接触。

1.3 磁盘的存储结构

下面我们来对一个磁面进行分析:
在这里插入图片描述
在一个磁面中,以主轴为圆心,向外会分成多个同心园,我们称这些同心圆为磁道,这些磁道又会被等分为多分弧段,这些弧段就叫做扇区,在磁盘进行数据的读写时就是以扇区为最小单位,每个扇区一般为512字节,从主轴向外扇区的长度是不同的,为了保证存储空间一致,设计规定离主轴越远数据的存储密度越小。

拓展: 磁盘在工作时,主轴带动磁盘旋转,磁头通过摆动来确定数据在哪个磁面、磁道,当确定磁道后,磁头停止摆动,此时磁盘继续旋转完成数据读写工作。

为了对方便管理,我们磁面、磁道、扇区进行编号,当我们要对磁盘数据进行访问时,就可以通过编号快速完成,具体怎么进行的我们下面介绍。

1.4 磁盘的逻辑结构

在这里插入图片描述
由于磁盘的大小相同,且磁臂是被固定的,这时再将磁盘划分磁道,我们就会得到一个由磁道组成的柱面结构,当我们对磁盘进行访问时,我们就可以先确定在哪一个柱面(cylinder),也就是磁盘,然后再确定再哪一个盘片(platter),由于每个盘片都配有一个磁头,所以我们是通过 磁头(head) 来确定的,再确定磁道(track),最后确定扇区(sector) 我们称这种定位方法为 CHS定位法。为了将它于操作系统建立联系,我们需要将它进一步抽象。

不知到大家有没有接触过磁带,来看下图:
在这里插入图片描述
左侧图片是磁带卷起的样子,会呈现出一个圆类似于盘面,当我们将它展开就会呈现出右侧有宽度的带子,我们可以依据这个特性将盘面中的磁道抽象为一个,条带子:

在这里插入图片描述
这里我们就可以将所有盘面全部抽象为一个线性结构(当成数组也可以,为了方便这里仅画出了一个盘),这时我们对磁盘的访问,就变为了对线性结构的访问,当操作系统要定位一个扇区时,我们只需要知道这个扇区的地址就可以完成对扇区的访问了,如要查找扇区编号为:355
在这里插入图片描述
由于是从0开始编号,所以计算时只需要向下取整即可。
这样我们就成功定位到了扇区,而我们将这种编号称为LBA地址,定位过程就是LAB地址转化为CHS地址的过程。

二、文件系统

2.1 系统对磁盘的管理

我们可以确切的感受到,在我们的计算机中,磁盘是非常大的,如果操作系统直接对他进程管理,效率是非常低的,那么该如何让操作系统对它进行管理呢?对于这个问题,我们的工程师采用了分治思想,将整个磁盘划分为小块空间,通过对所以小块空间的管理,达到对整个磁盘的管理。

在这里插入图片描述
这样操作系统只需要完成对每个组的管理,就可以达到对整个磁盘的管理。
每个组又会被划分为以下几个区:
在这里插入图片描述

具体如何管理我们结合文件在磁盘中的存储,进行分析:
我们知道文件=内容+属性,而在Linux中文件的内容和属性是分开进行存储的,那么两者分开存储是如和建立联系的呢?或者说是如何管理的呢?

存储属性信息: 在Linux中每个文件都会对应一个inode结构体,这个结构体(对象)的大小是固定的,通常为128字节,文件的所有信息都存储在这个结构体对象中,其中并包含文件名,这是因为,Linux并不通过文件名进行查找文件,每个inode都会有一个编号,操作系统通过编号进行查找。上图的inode Table就是inode表(inode集合,下面会再次解释)。

存储文件内容: 在Linux文件内容是存储在上图Data blocks区域中的,而这个区域被划分为块(这些块也是会被分配编号的),操作系统在访问磁盘时是以块为单位进行访问的,块中包含多个扇区,通常块的大小为4KB,此处可以理解为对读取性能的优化,因为当计算机要访问一段数据是,这段数据周围的数据也有很大可能被访问,所以直接读取4KB,这是一种以空间换时间的方法。(这个块大小是可以修改的,感兴趣的可以去了解)

属性与内容建立联系:inode对象中会存在,一个数组,数组中存储的是该文件内容存储块的编号。

在这里插入图片描述

这样我们就大概的知道了,存储逻辑了,下面我们解释一下,组中各个模块的含义。
在这里插入图片描述
Boot Block:引导块,引导操作系统启动,我们不做研究。

Super Block:超级块,存储文件系统的整个信息(整个分区信息),包含bolckinode的总量,未使用的量,一个bolckinode的大小,文件系统状态(是否干净卸载)等。

Group Descriptor Table:块组描述符,描述块组的属性信息。

Block Bitmap:块位图,记录Date bolck中的块是否被使用,通过块编号映射,相信学过位图的都可以理解。

inode Bitmapinode位图,标识inode是否被使用。

复习的时候再看看超级块-----这句话给作者看的

2.2 文件在磁盘中的操作

我通过对文件的增、删、查、改,带领大家熟悉上面知识。

查看文件的inode编号:

ls -li

在这里插入图片描述
还可以使用stat 文件名查看更多信息,大家自己去了解一下。

创建文件:

创建文件时,将文件存储在哪个分区,路径会帮助我们,这里我们就不关心了,首先操作系统根据,超级块中的信息,剩余inodebolck较多的组,遍历该组的inode Bitmap,得到未被使用的inode编号,找到该inode将文件属性存储,并将对应位置位图置1,再遍历Block Bitmap得到未被使用的块编号,找到对应块,将文件内容存储,并将对应位置位图置1,再将对应的块编号,存入该文件inode的数组中。

读取文件:

读取文件首先查找文件,拿到该文件的inode编号,根据编号找到对应的分组(LBA->CHS),找到inode中存储块编号的数组,那到块编号,读取块数据。

修改文件:

首先拿到该文件的inode编号,根据编号找到对应的分组(LBA->CHS),找到inode中存储块编号的数组,那到块编号,修改数据。

删除文件:

首先拿到该文件的inode编号,根据编号找到对应的分组(LBA->CHS),找到inode中存储块编号的数组,那到块编号,使用块编号,将块位图对应位置置0(表示未被使用),通过inode编号将inode位图置0

通过上面的方法我们就可实现文件的增、删、查、改了,但是我们还面临一个问题,操作系统该如何来获取文件的inode编号呢?

我们首先来看这样一个问题:
在这里插入图片描述
上面我们说,操作系统在磁盘访问文件不通过文件名,是通过inode进行的,但现在为什么操作系统不认识它呢?
要回答这个问题我们就得思考一下,目录文件在磁盘中存储的内容是什么了,在磁盘中目录文件存储的其实是,该目录下的文件名与文件inode编号的映射关系,当在用户访问文件时,操作系统就会根据当前目录的inode编号,找到当前目录的内容,从而通过映射关系找到对应文件的inode编号,这样就可以得到用户要访问文件的inode,但是当前目录文件的inode又从哪来呢,当然是通过它的上级目录了,就像这样一直索引,知道找到操作系统启动时固定的,目录inode编号,然后逐级返回。这个过程为路径解析,但是由于太过复杂影响效率,所以操作系统会将常用路径解析后缓存在dentry缓存

在这里插入图片描述
这样我们就将这个问题完美解决了。

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

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

相关文章

本节课课堂总结

匿名子类: 说明 和 Java 一样,可以通过包含带有定义或重写的代码块的方式创建一个匿名的子类。 单例对象(伴生对象) Scala语言是完全面向对象的语言,所以并没有静态的操作(即在Scala中没有静态的概念&a…

I²C、SPI、UART、CAN 通信协议详解

一、协议基本特性对比 特性ICSPIUARTCAN通信类型同步、半双工同步、全双工异步、全双工异步、多主多从信号线SDA(数据)、SCL(时钟)MOSI、MISO、SCK、SS(片选)TX(发送)、RX&#xff…

【diffusers 进阶(十五)】dataset 工具,Parquet和Arrow 数据文件格式,load dataset 方法

系列文章目录 【diffusers 极速入门(一)】pipeline 实际调用的是什么? call 方法!【diffusers 极速入门(二)】如何得到扩散去噪的中间结果?Pipeline callbacks 管道回调函数【diffusers极速入门&#xff0…

第十三章:持久化存储_《凤凰架构:构建可靠的大型分布式系统》

第十三章 持久化存储 一、Kubernetes存储设计核心概念 (1)存储抽象模型 PersistentVolume (PV):集群级别的存储资源抽象(如NFS卷/云存储盘)PersistentVolumeClaim (PVC):用户对存储资源的声明请求&#…

以太网安全

前言: 端口隔离可实现同一VLAN内端口之间的隔离。用户只需要将端口加入到隔离组中,就可以实现隔离组内端口之间的二层数据的隔离端口安全是一种在交换机接入层实施的安全机制,旨在通过控制端口的MAC地址学习行为,确保仅授权设备能…

跨域问题前端解决

由于浏览器的同源策略,前后端分离的项目,调试的时候总是会遇到跨域的问题,这里通过修改前端代码解决跨域问题。 首先先查看前端代码的根目录下,有没有vue.config.js文件, 若有,使用方法1,若没有此文件&…

Elasticsearch 报错index_closed_exception

index_closed_exception 是 Elasticsearch 中的一个异常类型,它通常发生在尝试对一个已经被关闭(closed)的索引执行搜索、写入或其他操作时。在 Elasticsearch 中,索引是用来存储和检索数据的逻辑命名空间,可以将其类比…

LearnOpenGL-笔记-其九

今天让我们完结高级OpenGL的部分: Instancing 很多时候,在场景中包含有大量实例的时候,光是调用GPU的绘制函数这个过程都会带来非常大的开销,因此我们需要想办法在每一次调用GPU的绘制函数时尽可能多地绘制,这个过程就…

PDF预览-搜索并高亮文本

在PDF.js中实现搜索高亮功能可以通过自定义一些代码来实现。PDF.js 是一个通用的、基于Web的PDF阅读器,它允许你在网页上嵌入PDF文件,并提供基本的阅读功能。要实现搜索并高亮显示文本,你可以通过以下几个步骤来完成: 1. 引入PDF…

二叉树——队列bfs专题

1.N叉树的层序遍历 我们之前遇到过二叉树的层序遍历,只需要用队列先进先出的特性就可以达到层序遍历的目的。 而这里不是二叉树,也就是说让节点的孩子入队列时不仅仅是左右孩子了,而是它的所有孩子。而我们看这棵多叉树的构造,它…

Python高级爬虫之JS逆向+安卓逆向1.1节-搭建Python开发环境

目录 引言: 1.1.1 为什么要安装Python? 1.1.2 下载Python解释器 1.1.3 安装Python解释器 1.1.4 测试是否安装成功 1.1.5 跟大神学高级爬虫安卓逆向 引言: 大神薯条老师的高级爬虫安卓逆向教程: 这套爬虫教程会系统讲解爬虫的初级&…

Windows 安装和使用 ElasticSearch

SpringBoot3 整合 Elasticsearch 1. ElasticSearch 1.1 ES (1)ES 是一个开源的分布式搜索和分析引擎,专为处理大模型数据而设计,它能够实现近乎实时的数据检索、分析和可视化,广泛用于全文搜索、日志分析和监控&…

matplotlib初探

库引入 import matplotlib.pyplot as pltpyplot.figure 创建新图形或激活现有图形

NVM 多版本Node.js 管理全指南(Windows系统)

🧑 博主简介:CSDN博客专家、全栈领域优质创作者、高级开发工程师、高级信息系统项目管理师、系统架构师,数学与应用数学专业,10年以上多种混合语言开发经验,从事DICOM医学影像开发领域多年,熟悉DICOM协议及…

实验室预约|实验室预约小程序|基于Java+vue微信小程序的实验室预约管理系统设计与实现(源码+数据库+文档)

实验室预约小程序 目录 基于微信小程序的实验室预约管理系统设计与实现 一、前言 二、系统功能设计 三、系统实现 1、微信小程序前台 2、管理员后台 (1)管理员登录 (2)实验室管理 (3)公告信息管理…

SpringBoot底层-数据源自动配置类

SpringBoot默认使用Hikari连接池,当我们想要切换成Druid连接池,底层原理是怎样呢 SpringBoot默认连接池——Hikari 在spring-boot-autoconfiguration包内有一个DataSourceConfiguraion配置类 abstract class DataSourceConfiguration {Configuration(p…

面试算法高频03-递归

认识递归 递归的概念与特性:递归本质类似循环,是通过函数体进行的循环操作。借助电影《盗梦空间》类比,递归如同主角在不同梦境层穿梭,向下进入不同递归层,向上能回到原来一层,每一层环境和周围元素相似&a…

linux Gitkraken 破解

ubuntu 安装 Gitkraken 9.x Pro 版本_gitcracken.git-CSDN博客

设计模式简述(十一)装饰器模式

装饰器模式 描述基本使用使用 描述 装饰器模式是一种功能型模式 用于动态增强对象的功能 这么一说感觉上和代理模式有些类似 抽象装饰器 要实现原有业务接口,并注入原有业务对象 至于对原有业务对象的调用,可以采用private业务对象 实现业务接口方法的…

【NetCore】ControllerBase:ASP.NET Core 中的基石类

ControllerBase:ASP.NET Core 中的基石类 一、什么是 ControllerBase?二、ControllerBase 的主要功能三、ControllerBase 的常用属性四、ControllerBase 的常用方法2. 模型绑定与验证3. 依赖注入五、ControllerBase 与 Controller 的区别六、实际开发中的最佳实践七、总结在 …