[ linux-系统 ] 磁盘与文件系统

1.认识磁盘结构

机械键盘是计算机中唯一的机械设备,磁盘是外设,容量大,速度慢,价格便宜

物理结构:

  1. 磁头是一面一个,左右摆动,两个整体移动的,有磁头停靠点
  2. 磁头和盘面不接触,所以物理上不适用于笔记本,开机状态移来移去,磁头刮花了磁盘,属于硬件问题
  3. 机械磁盘要在无尘环境下,灰尘落上去可能会把数据都磨没了
  1. 所有的数据都在盘片上以二进制存储,磁头通过充放电写入
  2. 内存掉电易失设备,磁盘永久性存储介质
  3. 通过充放电/强弱/波,在磁盘上写入 01 数据,像吸铁石的 N S 级

存储结构:

磁盘被访问的最小基本单元是扇区--大小约为512字节,块设备

如何定位一个扇区呢?

CHS寻址:先定位磁头(header),确定磁头要访问哪一个柱面(磁道)(cylinder),定位一个扇区(sector)

逻辑结构:

我们可以把磁带拉直,形成线性结构

那么磁盘本质上虽然是硬质的,但是逻辑上我们可以把磁盘想象成为卷在⼀起的磁带,那么磁盘的逻辑存储结构我们也可以类似于 

 这样每⼀个扇区,就有了⼀个线性地址(其实就是数组下标)

这种地址叫做LBA(Logical Block Address)

 

假设是两片四面。尽管扇区大小有差异,但是每个扇区的内存大小都是一样的。每一面上都有很多扇区,最后就把磁盘抽象成数组 。
有了数组,就可以通过下标找到某个扇区,但是磁盘只认CHS,所以要通过算法将下标转换成CHS的地址。
找到下标后交给磁盘,磁盘内部会把线性地址转换成CHS的地址,进而定位到某一个扇区里。

 

注意:一般而言,OS未来和磁盘交互的时候,基本单位为4KB,而不是512字节(一个扇区512字节),因为一次读512字节太少了,因为要提高效率

所以4KB=8个连续的扇区,系统把这8个连续的扇区称为块大小(数据块)

8个扇区为一个块,块号*8 = 每一个块的第一个扇区的下标,连续往后读就能知道整个块的下标

对于OS而言:未来读取数据就能以块为单位了,这里的每一个块号的起始地址称作LBA (逻辑区块地址)

LBA和CHS转化(了解)

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

2.文件系统 

引入块的概念:

其实硬盘是典型的“块”设备,操作系统读取硬盘数据的时候,其实是不会⼀个个扇区地读取,这样
效率太低,⽽是⼀次性连续读取多个扇区,即⼀次性读取⼀个”块”(block)。

硬盘的每个分区是被划分为⼀个个的”块”。⼀个”块”的⼤⼩是由格式化的时候确定的,并且不可
以更改,最常⻅的是4KB,即连续⼋个扇区组成⼀个”块”。”块”是⽂件存取的最⼩单位。

 理解分区

其实磁盘是可以被分成多个分区(partition)的,以Windows观点来看,你可能会有⼀块磁盘并且将它分区成C,D,E盘。那个C,D,E就是分区。分区从实质上说就是对硬盘的⼀种格式化。但是Linux的设备都是以⽂件形式存在,那是怎么分区的呢?

假设磁盘的空间很大,需要分区管理,因此只要能管理好其中一个区,剩下的其他区就可以照搬它的管理方法,全部管理好。(分治思想)

如果这里管理其中一个区,这个区还是太大,就要在这个区里面继续分组。只要把一个组管理好了,这个区的每一个组就都能管理好了 

磁盘文件系统图 :

Linux文件系统特点:文件内容和文件属性 分开存储

Block Group:文件系统会根据分区的大小划分为数个Block Group。而每个Block Group都有着相同的结构组成
超级块(Super Block):存放文件系统本身的结构信息,描述的是整个分区整体的文件系统的情况
        1.记录的信息主要有:
                1.bolck 和 inode的总量
                 2.未使用的block和inode的数量
                3.一个block和inode的大小
                4.近一次挂载的时间
                5.最近一次写入数据的时间
                6.最近一次检验磁盘的时间等其他文件系统的相关信息
        2.Super Block 的信息被破坏,可以说整个文件系统结构就被破坏了
        3.超级块不止一个,可能有多个,在不同的块组里,这样可以让文件系统更稳定
GDT,Group Descriptor Table:块组描述符,描述块组属性信息
块位图(Block Bitmap):Block Bitmap中记录着Data Block中哪个数据块已经被占用,哪个数据块没有被占用
inode位图(inode Bitmap):每个bit表示一个inode是否空闲可用。
inode表:存放文件属性 如 文件大小,所有者,最近修改时间等
数据区:存放文件内容
inode Table里面存的是文件的属性Data blocks里面存的是文件的内容


Linux中文件的属性是一个大小固定的集合体,也就是inode结构体

结构体里面没有文件名。内核层面,每一个inode都有inode number,通过inode号标识一个文件。通过inode号找到inode后,inode里面还有一个数组,可以映射到对应数据块

 

理解inode

在linux文件系统中, inode(索引节点)是一个非常重要的概念。每个文件和目录在Linux文件系统中都有一个对应的 inode ,它包含了除文件名之外的所有元信息(文件属性)

文件内容与inode映射

inode结构中除了有编号属性外,还有一个属性,这个属性是存储指向data Blocks中指定数据块的指针,其有四种分类:

1.12个直接映射指针,每个指针直接指向每一个存储内容的数据块,一共可以存储4kb * 12 = 48kb的数据,对于小文件非常有效
2.一级指针,指向一个数据块,一个4kb的数据块中每4个字节存储其他块的索引,此时有4 * 1024 / 4 * 4 * 1024 = 4MB个存储空间
3.二级指针,指向一个数据块,一个4kb的数据块中每4个字节存储与一级指针指向的数据块相同的数据块,此时有4 * 1024 / 4 * 4 = 4096MB = 4GB个存储空间
4.三级指针,指向一个数据块,一个4kb的数据块中每4个字节存储与二级指针指向的数据块相同的数据块,此时有4 * 1024 / 4 * 4 = 4096GB = 4TB个存储空间

inode的定义

inode 是文件系统中的一个数据结构,用于存储文件的元数据(即文件的属性信息)
每个文件或目录都有一个唯一的 inode 号,注意:一个文件inode是有可能有多个目录项的,比如给一个文件创建多个硬链接,因此文件 和 inode 不是 一一对应
inode 编号是以分区为单位的,一个分区内 inode 号不能重复,两个分区间可以,所以 inode 不能跨分区访问。

inode包含的信息

文件类型:普通文件、目录、符号链接等
权限:文件的读、写、执行权限
所有者:文件的所有者和组
时间戳:文件的创建时间、修改时间和访问时间
文件大小:文件的实际大小
指向数据块的指针:文件数据在磁盘上的位置
硬链接数:指向该inode的目录项数量


inode的作用


唯一标识: inode 号是文件系统的唯一标识符,即使文件名改变, inode 号也不会改变。
元数据管理: inode 存储了文件的所有重要元数据,使得文件系统可以高效地管理和检索文件。
硬链接支持:多个目录项可以指向同一个 inode ,这就是硬链接的基础。

inode与文件名的关系 


文件名实际上是目录中的一个条目,指向相应的 inode

可以有多个文件名(硬链接)指向同一个 inode

删除一个文件名并不会删除 inode ,只有当所有的硬链接都被删除时,inode 才会被释放

查看inode信息

可以使用一些命令来查看inode信息:

ls -i:显示文件和目录的 inode 号。
stat :显示文件的详细信息,包括inode号和其他元数据。
df -i:显示文件系统的 inode 使用情况。

inode限制 

每个文件系统有一个固定的 inode 数量上限,这在创建文件系统时确定

如果文件系统中的 inode 用尽,即使还有可用的磁盘空间,也无法再创建新的文件或目录

 

Inode 、Inode Table 、Data Blocks 三者关系

Inode 是一个数据结构,用于存储文件的元数据(即文件的属性信息)。每个文件和目录都有一个唯一的 inode
Inode Table 是文件系统中存储所有inode 的一个区域。它是一个固定大小的数组,每个 inode 占用固定的大小。作用如下:
        Inode Table 存储了文件系统中所有文件和目录的元数据

        每个 inode 在 Inode Table 中有一个唯一的编号(inode号)

        当文件系统创建时,Inode Table 的大小是预先分配好的,这意味着文件系统中可以存储的文件和目录数量有一个上限

Data Blocks 是实际存储文件内容的磁盘空间。文件的数据被分割成多个块,并存储在这些数据块中。作用如下:
        文件的实际内容存储在Data Blocks中

        Inode中的指针指向这些数据块的位置

        数据块的大小通常是固定的,例如4KB或8KB,具体取决于文件系统的配置

三者的关系
        Inode 存储文件的元数据,并包含指向数据块的指针。
        Inode Table 是存储所有inode 的区域,每个inode 在其中有一个唯一的编号。
        Data Blocks 存储文件的实际内容,通过inode 中的指针来访问。

 

格式化

操作系统在建立完分区之后就需要对当前分区进行分组,而这个过程也被称为格式化分区,本质上就是向Group Descriptor TableSuper Block中写入数据,既然要写入数据,就需要先获得到对应的数据,操作系统会根据一定的比率分配inode Tabledata blocks,所以整个分区的大小都是固定的,这就会导致出现inode用完,但是data Blocks没有用完。所以前面说「可以确定起始值是因为组内每一个字段以及大小都是固定的」

需要注意,同时也存在出现inode没用完,但是data Blocks用完的情况

实际上,如果一个分区不进行格式化,那么这个分区就无法被用户使用,除了因为制定的分组信息没有填写外,还存在没有给当前分区建立目录索引的原因。这个原因在接下来的内容中会提及

如何查找文件 

前面提到每一个文件有对应的属性,而属性存储在inode结构中,操作系统为了查找一个文件首先就需要对应文件的inode结构的编号成员,接着根据这个编号减去当前分组的inode Table的起始值就可以算出一个偏移量,在inode Bitmap中根据这个偏移量判断指定inode编号是否有效,即判断这个编号在inode中的对应位置是否为1,如果为1,证明指定文件存在。

因为每一个分组的起始值不同,导致inode Tableinode编号的偏移量加上对应的起始值就不会相同,所以就可以解释为什么inode不会相同

接着在该inode结构中根据数据区指针指向的数据块在block Bitmap中判断是否有效,如果有效,就找出对应的文件内容即可

如果现在这个文件非常大,其内容不仅在当前组中存在,也存在于其他组,此时就需要不同组之间的Data Blocks进行连接,所以实际上,Data Blocks在Linux中是可以跨分组的,但是不可以跨分区,因为不同的分区可能使用的文件系统不同

对于其他的「如何删除文件」、「如何修改文件」以及「如何新增文件」都涉及到「如何查找文件」,所以基本思路都是一致的

对于删除文件来说,本质上就是先进行查找文件的操作,而删除的过程就是将对应的inode Bitmapblock Bitmap对应位置置为0,此时就表示指定的文件内容和属性无效,新的文件或者已有的文件可以使用对应的数据块

正是因为有上面的删除机制,所以删除的文件理论上是可以被恢复的,但是恢复的难度很大

对于修改文件,依旧是先查找文件,再修改文件对应的数据块的内容即可

对于新增文件,之所以要先查找,是因为需要防止出现文件冲突,如果没有发生冲突,就需要先在inode Bitmap申请一块空间将指定位置记为1),在根据这个位置加上指定inode Table的起始值就可以找到一个位置存储inode节点,再将inode节点中的编号属性赋值即可

文件与目录

前面提到「如何查找一个文件」是通过获取到的inode编号,但是现在的问题是,系统如何拿到的inode编号。换句话说,在使用Linux命令行操作时,用户输入的文件名或者目录名都是字符串,系统是如何知道指定文件对应的inode编号的?

在inode结构中不存储着文件名,但是系统能根据文件名获取到其对应的inode编号,主要原因是文件所在路径,为了更好理解下面的内容,先讨论目录文件:

对于底层磁盘硬件来说,不论是目录还是普通的文件,它们都是由二进制组成,而系统要找到某一个目录就需要根据当前目录的所在路径从根路径开始解析(根路径是系统加载时一定会被固定加载的),直到进入到当前目录的数据块,而在目录中的数据块存储着当前目录中所有文件名字符串和其inode编号的映射关系

一般来说,这个映射关系是相互映射

所以系统获取一个文件的inode编号只需要根据其所在路径按照路径解析进入到其所在目录找到映射关系就可以获取到

但是,如果同一个目录有很多个文件,对每一个文件都进行路径解析,那么系统整体的效率就会受到影响,为了尽可能提升系统效率,在Linux中还存在一个多叉树结构dentry,这个结构的根节点就是根路径,剩下的节点就是按照文件路径中的目录构成的一个一个节点。与进程PCB结构一样,dentry结构也是内存级的结构

有了上面的概念,所以在一个程序中之所以可以使用open打开一个文件本质就是因为进程的CWD给出了当前程序的路径,即根据这个路径找到该进程要打开的文件

至此,系统获取到文件的inode编号的方式就已经基本确定,现在也就可以基本解释在前面权限部分提到rwx三个权限为什么缺失时目录会用相应的效果:

缺失r权限,无法读取目录中的内容:本质就是无法获取到目录中的文件名和inode编号的映射关系
缺失w权限,无法修改目录中的文件:本质就是无法向目录的数据块写入
缺失x权限,无法进入目录:本质就是无法进入到目录的数据块中

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

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

相关文章

Spring AI RAG

目录 Spring AI 介绍 Spring AI 组件介绍 Spring AI 结构化输出 Srping AI 多模态 Spring AI 本地Ollama Spring AI 源码 Spring AI Advisor机制 Spring AI Tool Calling Spring AI MCP Spring AI RAG Spring AI Agent 一、技术架构与核心流程‌ 检索增强生成 (RA…

深入Linux开发核心:掌握Vim编辑器与GCCG++编译工具链

文章目录 一、Vim:终端环境下的编辑艺术1.1 Vim设计哲学:模态编辑的终极实践1.2 高效导航:超越方向键的移动艺术1.3 定制化开发环境:从基础到专业IDE1.4 调试集成:Vim作为调试前端 二、GCC/G:Linux编译基石…

阿里云-spring boot接入arms监控

目标:在ecs中启动一个java应用,且携带arms监控 原理:在java应用启动时,同时启动一个agent探针,时刻监控java应用变化(如:接口调用、CPU、线程池状态等) 1.arms接入中心添加java应用…

昆泰芯3D霍尔磁传感器芯片在汽车零部件中的应用

HUD即抬头显示系统(Head-Up Display),HUD 是一种将重要的车辆或飞行等相关信息(如速度、导航指示、警告信息等)投射到驾驶员或操作员前方视野范围内的透明显示屏或直接投射到风挡玻璃上的技术。 HUD即抬头显示系统(Head-Up Display)&#xff…

new Vue() 的底层工作原理

当你调用 new Vue() 时,Vue.js 会执行一系列复杂的初始化过程。让我们深入剖析这个看似简单的操作背后发生的事情: 1. 初始化阶段 (1) 内部初始化 function Vue(options) {if (!(this instanceof Vue)) {warn(Vue is a constructor and should be cal…

最简安装SUSE15SP7导致大部分命令缺失

我嘞个去~~~明明选择Enable了ssh,结果也没给装。 俺习惯使用NetworkManager管理网络,没给装,用不了nmcli和nmtui。不高兴归不高兴,最简安装的话,也情有可原。我嘞个去去~~连ping、vi都没有装,这也太简了。…

Vue-14-前端框架Vue之应用基础嵌套路由和路由传参

文章目录 1 嵌套路由1.1 News.vue1.2 Detail.vue1.3 router/index.ts2 路由传参2.1 query参数2.1.1 News.vue(传递参数)2.1.2 Detail.vue(接收参数)2.2 params参数2.2.1 router/index.ts(需要提前占位)2.2.2 News.vue(传递参数)2.2.3 Detail.vue(接收参数)2.3 props配置2.3.1 r…

Python网安-ftp服务暴力破解(仅供学习)

目录 源码在这里 需要导入的模块 连接ftp,并设置密码本和线程 核心代码 设置线程 源码在这里 https://github.com/Wist-fully/Attack/tree/cracker 需要导入的模块 import ftplib from threading import Thread import queue 连接ftp,并设置密码…

ES6数组的`flat()`和`flatMap()`函数用法

今天给大家分享ES6中两个超实用的数组函数:flat()和flatMap(),学会它们能让数组处理变得更轻松! 1. flat()函数 1.1 基本介绍 flat()用于将嵌套数组"拍平",即将多维数组转换为一维数组。 1.2 语法 const newArray …

upload-labs靶场通关详解:第15-16关

第十五关 getimagesize函数验证 一、分析源代码 function isImage($filename){$types .jpeg|.png|.gif;if(file_exists($filename)){$info getimagesize($filename);$ext image_type_to_extension($info[2]);if(stripos($types,$ext)>0){return $ext;}else{return false…

【Linux】基础IO流

好的代码自己会说话,清晰的逻辑与优雅的结构,是程序员与世界对话的方式。 前言 这是我自己学习Linux系统编程的第五篇笔记。后期我会继续把Linux系统编程笔记开源至博客上。 上一期笔记是关于进程: 【Linux】进程-CSDN博客https://blog.csdn…

【C语言】学习过程教训与经验杂谈:思想准备、知识回顾(二)

🔥个人主页:艾莉丝努力练剑 ❄专栏传送门:《C语言》、《数据结构与算法》、C语言刷题12天IO强训、LeetCode代码强化刷题 🍉学习方向:C/C方向 ⭐️人生格言:为天地立心,为生民立命,为…

AD8021ARZ-REEL7【ADI】300MHz低噪声运放放大器,高频信号处理的性价比之选!

AD8021ARZ-REEL7(ADI)产品解析与推广文案 1. 产品概述 AD8021ARZ-REEL7 是 Analog Devices Inc.(ADI) 推出的一款 高速、低噪声运算放大器(Op-Amp),属于 ADI的高性能放大器系列,专为…

WPF学习笔记(11)数据模板DataTemplate与数据模板选择器DataTemplateSelector

数据模板DataTemplate与数据模板选择器DataTemplateSelector 一、DataTemplate1. DataTemplate概述2. DataTemplate详解 二、DataTemplateSelector1. DataTemplateSelector概述2. DataTemplateSelector详解 总结 一、DataTemplate 1. DataTemplate概述 DataTemplate 表示数据…

【V6.0 - 听觉篇】当AI学会“听”:用声音特征捕捉视频的“情绪爽点”

系列回顾: 在上一篇 《AI的“火眼金睛”:用OpenCV和SHAP洞察“第一眼缘”》 中,我们成功地让AI拥有了视觉,它已经能像一个严苛的“质检员”一样,评判我视频的画质和动态感。 但我的焦虑并没有完全消除。因为我发现&a…

(5)pytest-yield操作

1. 简介 上一篇中,我们刚刚实现了在每个用例之前执行初始化操作,那么用例执行完之后如需要清除数据(或还原)操作,可以使用 yield 来实现。fixture通过scope参数控制setup级别,既然有setup作为用例之前前的操…

C++中的cmath库

在C编程中,数值计算是科学计算、工程应用及算法开发的基础。cmath库作为C标准库的重要组成部分,提供了丰富的数学函数和工具,能够高效处理各种数值计算任务。本文将全面解析cmath库的核心功能,并通过实战案例展示其强大威力。 一…

python包管理工具uv VS pip

在 Python 中,uv 和 pip 都是包管理工具,但它们的定位和特性有所不同。以下是主要区别: 1. pip(传统工具) 定位:Python 官方的包安装工具,是 Python 生态中最基础的包管理器。特点:…

OpenCv基础(C++)

1.图像读取与显示 #include<opencv2/opencv.hpp> using namespace cv;Mat src imread("C:/Users/16385/Desktop/new/photo/1.jpg");//读取图像 Mat src imread("C:/Users/16385/Desktop/new/photo/1.jpg",IMREAD_GRAYSCALE); //将读取的图像转为灰…

MySQL非阻塞创建索引的方法

文章目录 1. Online DDL (MySQL 5.6)2. pt-online-schema-change 工具3. gh-ost 工具4. 对于MySQL 8.0注意事项 在MySQL中创建大型表索引时&#xff0c;传统方式会阻塞表的写操作&#xff0c;影响生产环境使用。以下是几种非阻塞创建索引的方法&#xff1a; 1. Online DDL (My…