Linux:文件系统与磁盘

目录

文件系统 

文件的管理流程

文件的管理目的

文件的管理内容

磁盘

磁盘的结构和基本原理

磁盘的分区 

磁盘的索引原理 

磁盘的逻辑抽象引入


前言:

我们一直都在说打开的文件,磁盘中包含了上百万个文件,肯定不可能都是以打开的方式存在。其实文件包含打开的文件和普通的未打开的文件。我们知道打开的文件是通过操作系统被进程打开,一旦打开,操作系统就要维护多个文件,所以它是需要被操作系统管理的。也就是说这种方式,磁盘上和内存上都有这个文件,它们不是完全一样的,内存中的文件更强调的是属性和方法,磁盘中的文件更强调的是数据,它们是通过缓冲区关联的;而普通的未打开的文件在磁盘上,未被加载到内存中,它当然也要被管理;其中管理打开的文件和管理未打开的文件在操作系统中有一个功能模块叫做文件系统。之前我们谈过进程 VS 程序,一个被打开的程序就是进程,只不过我们在解释进程时不是严格地把它当作文件来解释,需要明白的是进程是要被加载到内存的,程序就是一个磁盘文件,打开的文件是进程,而普通未打开的文件是程序。那么正式进入话题:

文件系统 

文件的管理流程

通过前面章节的学习,我们总结一下这些知识点: 

如何理解操作系统管理文件这个过程呢? 

当程序执行文件操作时,会通过系统调用触发内核处理。操作系统通过进程控制块(PCB)中的文件描述符表(FD Table)管理进程所有打开的文件。每个文件描述符(FD)都是指向内核文件对象(通常对应磁盘上的inode节点)的指针,形成"用户空间→系统调用接口→PCB→FD Table→文件对象→磁盘文件"的关联链。这种层级结构使得操作系统仅通过FD即可高效管理文件资源。当发生重定向时(如stdout重定向),本质是将原FD表项替换为新文件的FD,后续对该描述符的操作自然指向新的文件对象,这正是基于文件描述符的"抽象层覆盖"原理实现的。 

如何理解一切皆文件?

在操作系统中,由于存在上述的体系,因此就存在这样的技术,可以将外部的硬件用描述文件的结构体表示出来,这样的技术也叫做虚拟文件系统,在这样的技术下,就可以实现了将每一个硬件的信息都用一定的文件描述的方法进行一些表示,这样在把文件加载到内存中后,就可以参与到上述所表示的文件系统的运作中,也就是说,虚拟文件系统就是将不同硬件的读写方式用相同的文件结构体来描述出来,在文件结构体中存在包括但不限于有读和写的方法,将不同硬件的读写方式分别录入到这样的文件系统中,就可以达到特定的想要的效果,也就能做到屏蔽不同的硬件带来的属性差异,而能在操作系统中用相同的方式实现文件接口的调用,来进行方便于文件的管理。

上述就是关于一切皆文件的理解,在这样的基础上,下一步是进行了关于缓冲区的概念:

如何理解缓冲区?

在Linux系统中,存在有两种意义的缓冲区,一种是语言类提供给我们的缓冲区,一种是操作系统向外部进行交互的时候使用的内核缓冲区,不管是什么样的缓冲区,它们的主要目的都是为了提升效率,使得只需要将请求传递给缓冲区,就能立刻拿到所需要的返回值信息,可能是返回成功也可能是返回的错误信息,至于后续的操作就不在用户的考虑范围内,如何将信息从缓冲区刷新到指定的位置就交由操作系统来完成。

基于上面所说的这几点理论,下面来对文件系统进行进一步的理解。

文件的管理目的

在磁盘中存在很多很多的文件,而实际上只有很少的一部分文件是要被打开的,换句话说,只有很少的文件是需要被加载到内存中的,大致上可以把文件分成两种文件:

  1. 已经打开的文件
  2. 大多数都是没有被打开的文件,它们存储在磁盘中

对于第一种文件来说,如何进行管理?答案是有操作系统在内存中对这些文件进行管理,那第二种文件需不需要管理呢?答案是肯定是需要的,管理的目的是为了快速查找,将这些文件进行管理起来,才能在需要的时候可以立刻定位到所需要的位置,进而进行调用或是其他的各种操作,那么初步的,将管理这些文件的目标设置为需要定位文件,提供一个合适的路径,进而可以在所需要的时候进行快速的定位。

文件的管理内容

在磁盘中管理的文件,管理的本质是什么?

从前面的知识体系中,有这样的基本认知:文件 = 内容 + 属性,所以管理文件的本质就是管理的是文件的内容和文件的属性,也就是说是目的是为了方便用户进行文件的增删查改,换句话说是为了便利与操作系统对于文件的增删查改。

文件的内容是被放置到哪里的?

文件的内容当然是存储在了磁盘中,换句话说是存储在了一个硬件,一个物理的存储结构中。

文件要在哪里被管理?

文件的管理当然要被放置在操作系统中进行管理了,操作系统本质上来说是内存中的管理,也就是一种逻辑的存储结构。

因此现在的问题是,如何将文件的管理从硬件的物理存储结构转换成逻辑抽象的逻辑存储结构呢?这就是本篇要讨论的核心问题,这对于理解操作系统管理磁盘,和理解文件系统来说是至关重要的,进而会延伸到软硬链接的问题。

磁盘

磁盘的结构和基本原理

 

  • 内存 -- 掉电易失存储介质
  • 磁盘 -- 永久性存储介质 -- SSD、U盘、flash卡、光盘、磁带

众所周知,磁盘分为机械硬盘(HDD)和固态硬盘(SSD),现在很多的电脑都是机械硬盘和固态硬盘组合使用,但服务器上大多都是机械硬盘,只有一些高效率的存储集群会用到固态硬盘。机械硬盘和固态硬盘在存储技术上肯定是不同的,而我们主要了解机械硬盘,因为它多用于服务器上,其次虽然固态硬盘要比机械硬盘快不少,但在 CPU 看来,两者都很慢,我们这里就了解最慢的。虽然磁盘的盘面看起来很光滑,但是它上面有一些同心圆,这些同心圆用圆白线划分,每一圈叫做磁道,数据写在这些有颜色的区域上。实际上你并不是把一圈的空间都用完,所以这里还使用了一些直白线划分,被圆白线和直白线划分出来的区域叫做扇区。所以当盘片在旋转、磁头摆动就可以找到这个盘片的任何一个扇区进行读写。 实际磁头和盘面并不是接触的,它们之间的距离就像一架飞机在离平地 1 米的距离滑行,所以如果笔记本摔了或者是在开机状态下总被搬来搬去,磁头就容易与盘片接触,此时就有可能会刮花盘片,电脑就可能会发生蓝屏等。

磁盘的分区 

盘面是有两面的,且两面都是同心圆,数据只能写在同心圆(磁道)上,根据配置不同,有些磁盘可能还有多组盘片,我们可以从上至下的分为不同的盘面,也叫做你是第几个盘面。

虽然在 C 语言中访问内存的基本单位是 1byte ,但是在操作系统的角度认为内存的基本单位一般是 4kb,在操作系统看来,内存就是一个数组,每一个元素是 4kb。

之前在谈进程地址空间时也说过它叫做页框,4kb 是页帧,所以操作系统申请内存时是按 4kb 为单位进行分配和加载的,语言层面上并不关心底层是怎么做的,比如你要 malloc 1byte,那么操作系统也不可能直接给你 4kb,有可能 C 语言本身就缓冲了一部分空间让你去使用,如果超出这一部分空间,操作系统再重新分配。

磁盘存储的最小基本单位是一个扇区,它是磁盘读取的最小单元,大部分磁盘的一个扇区是 512byte,但你会发现虽然这里好像越靠近圆心,扇区越小,其实它们都是 512byte,原因是越靠近圆心的虽然扇区越小,但是比特位也相对外圈更密集。内存和磁盘之间也是有交互的,它们之间的交互我们称为 output、input,也叫做 IO,一般内存和磁盘之间 IO 交互时,不是纯硬件级别的交互,而是要通过文件系统完成,也就是通过操作系统。

这里用户和内存之间交互的基本单元大小是 1byte,一般内存和磁盘之间交互时的基本单元大小是 4kb,所以文件系统在往磁盘读数据时,要读 8 个扇区,这就是数据由磁盘加载到内存的过程。

磁盘的信息是如何存储的?结论肯定是经过一定的区域划分才能进行数据的存储,而划分的方式就是通过上图进行划分的。对于单个磁片来说,可以划分为很多个磁道,而每一个磁道又会组成一个一个的扇区,而扇区就是最小的存储单元,对于不同的扇区来说存储的数据密度肯定是不相同的,这也就能保证虽然离中心点近的扇区区域小,但是依旧可以保证存储的空间和外部的扇区存储的空间是相同的。

基于上述的这个原理,可以做出一些初步的总结:

  1. 一个盘面可以有多个同心的轨道
  2. 一圈磁道可以有多个扇形的扇区组成
  3. 扇区是磁片的最小存储单元,通常是512字节或是4kb

为什么操作系统(文件系统)和磁盘不以 512byte 为单位呢? 

太小了,可能会导致多次 IO,进而导致效率的降低。如果操作系统使用和磁盘一样的大小,万一磁盘的基本大小发生改变,那 OS 的源代码要不要改呢?那岂不是将硬件和软件(OS)进行解耦。

磁盘的索引原理 

上图展示的是磁盘的一个立体的图片,一个磁盘是由多个磁片所组成的,这是可以看出的,因此也就包括了磁道,扇区,和柱面这样的组成部分。

现在的问题是:当需要对于磁盘中某个特定的位置进行写入,如何具体的定位呢?

  1. 选择某一面,本质上来说是选择一个合适的磁头
  2. 选择这个面上的吗,某个轨道
  3. 选择这个磁道上的某个扇区

这样的过程就叫做CHS定位法,通过这样的三个步骤,就可以定位到所需要的某个扇区,进而进行数据的读和写,这样就可以向任意一个或者多个的连续扇区中进行写入,也可以进行随机写入。

磁盘的逻辑抽象引入

磁盘的外部结构已经基本理解了,那么操作系统自然是需要得到磁盘中的信息的,那么操作系统是如何读取和存储关于磁盘的信息的呢?是直接存储这些物理结构吗?答案是否定的,在操作系统内部,会把整个磁盘想象成一个数组,不断的拉长拉长再拉长,这样就能把这样的磁盘抽象成数组,也就是把磁盘的存储的逻辑抽象结构描述了出来

将磁盘想象成一个线性的空间:

通过上述的这个过程,就可以把整个磁盘用一个数组来表示起来,这样就能像访问数组一样进行访问磁盘,进而进行数据的增删查改等等行为…

例如给定一个字符的下标是123,那么假设下标1-100000是第一面磁盘,下标1-10000是第一个磁道,那么就可以有如下的定位计算方式:

1234 / 100000 = 0 表示现在是第一个磁片
1234 / 10000 = 0 表示现在是第一个磁道
123 % 10000 = 123 表示现在是123所在的扇区

在实际的映射计算中可能比上述的计算要复杂的多,但是基本原理已经从上述的计算中可以看的出来,的确通过这样抽象出来的数组可以找到磁盘中对应的位置。

操作系统,可以按照扇区为单位进行存取,也可以基于文件系统,按照文件块为单位进行数据的存储,一般来说选择后者进行数据的存储,这里按照八个扇区为一个文件块,因此就可以把扇区又进行划分,每八个扇区为一个文件块。

LBA地址:全称叫做logical block address,LBA作为地址,可以对应到CHS地址,也就是通过操作系统内部抽象出来的逻辑结构的地址,可以与外部的磁盘的实际地址做出一个对应,这样就完成了初步的目标。

到这里,就把存储设备的管理,在操作系统层面转换成了对数组的增删查改。

如何理解删除文件?

计算机中删除一个文件并不是真正的删除,而是把那块空间标识为无效,就像拷贝一部电影到 U 盘需要 1 分钟,但是删除 U 盘上的电影只需要短暂的一两秒;亦或是盖一个房子需要 1 年,而销毁一个房子只需要在墙上写上拆 。而现在理解的是不用把 inode 属性清空,不用把 inode 对应的数据块清空,只需要把两个位图中对应的比特位由 1 到 0,再把所在的目录下中的对应的映射关系去掉,此时空间就是无效的,当下一次再新建文件时,就可以直接把无效的空间覆盖。

按上面这样说,删除后的文件当然可以恢复,Windows 下的回收站就是一个目录,当你删除时就是把文件移动到回收站目录下,然后把其它目录下数据块中的映射关系移动到回收站目录下的数据块中。Windows 下就算把回收站的内容删除也是能恢复的,Linux 下如果要恢复删除的文件是有一些恢复工具的,但有可能在恢复过程中创建各种临时文件,可能就会把想恢复的文件的信息覆盖掉。如果想自己恢复删除的文件,就需要更深入的了解文件系统原理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值