目录
学前补充
磁盘的存储结构
OS如何对磁盘的存储进行逻辑抽象
细节内容
学前补充
问题:计算机只认二进制,即0、1,什么是0、1?
解释:0、1在物理层面可能有不同的表现,0、1是数字逻辑,可以表示高低电平....
问题:什么是磁盘?
解释:磁盘本质是一个机械设备,由盘片、磁头、主轴电机、控制器板组成,盘片是可读可写可擦除,一篇两面都可写,一面一个磁头
磁盘的存储结构
基本概念:磁盘是一个机械设备,是外设,数据的存取速度慢,但是性价比高,用很少的钱就可以买到一个数据存储的硬件设备,于其它更昂贵的数据存储设备相比,对数据的读取速度是相差10^n(跟越nb的相比n就越大)
扇区:磁盘读写的基本单位,大小是512字节
- 1磁盘 = n 个磁道
- 1磁道 = m 个扇区
注意事项:一般情况下计算机系统中,磁盘和内存之间的数据传输是以块为单位进行的,块大小通常是512字节或更大。如果只需要修改一个比特位,也要讲整个块的512字节加载到内存中,在内存中对一个比特位进行修改后再将整块写入磁盘中(其实也可以通过“原子写入”技术避免块在传入内存时出现部分要修改+部分不要修改的情况)
问题:如何找到一个指定位置的扇区?
解释:CHS定址法:(在一个 CHS 定址系统中,“0/0/1”表示第 1 个扇区位于第 0 柱面、第 0 磁头和第 1 扇区处)
- 确认指定的磁头:Header
- 找到指定的磁道(柱面):Cylinder
- 找到指定扇区:Sector
补充:盘片旋转是为了定位扇区,磁头左右摆动是为了定位磁道,此外磁盘还分为民用的桌面级磁盘和企业用的企业级磁盘
结论:文件 = 内容 + 属性,它们都是数据,从更本质上将讲都是二进制数据,文件在没有被打开时在磁盘中存放是磁盘文件,即文件其实就是在磁盘中占有几个扇区(512字节)的问题
OS如何对磁盘的存储进行逻辑抽象
基本概念:OS会对磁盘这样的硬件设备进行管理和抽象,这是因为如果OS直接使用CHS对磁盘进行管理,耦合度太高,不希望OS可以直接拿到硬件设备的一些参数,同时也是为了方便实现内核并进行磁盘管理
问题:如何进行逻辑抽象?
解释:将磁盘的圆形结构抽象成一个线性结构:
此外,由于一个扇区512字节太少了,从磁盘读取一个8KB大小的数据需要访问磁盘十六次,因此虽然访问磁盘的基本单位是一个扇区512字节,但一般情况下,OS与磁盘交互时,会一次访问4KB即8个扇区(规定),我们将这八个扇区统称为数据块,该数据块就是OS层面读取磁盘时的基本单位
- 块就是LBA,即逻辑区块地址
- 磁盘总大小 / 4 = 磁盘中块的个数
磁盘中的多个扇区组成一个LBA类型的数组LBA blocks[N],此时OS对磁盘的管理就变成了对LBA数组的管理(用数字来描述,用数组进行组织),用一个数字就可以描述一个块的位置进而知道该块中扇区的CHS地址
- 一个800GB的磁盘太大了,我们可以将它分成多份,即分区,只要我们总结好一个200GB分区的管理方法,就可以将该方法复刻到其它分区
物理层面(原来):磁盘 —> 面 —> 磁道 —> 扇区
虚拟层面(现在):磁盘 —> 多个LAB数组 —> 多个LAB —> 扇区
结论:文件 = 很多个LBA地址
分区中的一个组中又会有多个磁盘级文件系统:
- Group Descriptor Table:块组描述符GDT,获取块组的属性信息
- Super Block:超级块,存放一个分区中的文件系统的信息(当前分区中block和inode的总量,未使用的block和inode的数量,一个block和inode的大小,最近一次挂载的时间等),如果它被破坏则整个分区的文件系统结构就被破坏了,因此为了保证系统的健壮性,它会被下放至分区中的个别分组中(没必要每个分组都有,保证效率),这样即使它对应的某个物理扇区被损毁后也可以从其它分组中的超级块中拷贝一份信息
- GDT记录的是一个分组中的信息,每个分组都有
- SB是记录一个分区中的信息,位于个别的分组中
格式化:为每个分区分组后,写入文件系统的管理数据(本质就是在磁盘中写入文件系统)
细节内容
1、inode number是以分区为基本单位划分的,一个分区中的inode number不能重复,两个分区中的inode number可能重复
2、GDT记录当前组的start inode number和end inode number,SB记录整个分区中inode的所属情况
- (inode number= 10000,通过SB找到inode属于哪个分组,再用10000减该分组的start inode,从而确定在该分组的具体位置,再在该分组的inode bitmap中从右向左数找到并查看该位置上的比特位是0还是1,如果为0则该10000不是一个合法inode,如果合法则在inode table数组中找到索引为10000-start inode的inode,此时就找到了文件的属性,即inode = 10000所对应的文件的属性是第n个分组中的第m个i节点表中的内容,然后就可以通过结点表中的文件属性找到daba block中文件的内容)
3、不同的文件系统inode结构体的大小可能不同
4、inode结构体中的datablock[]数组大小一般是15,通过数组下标[0,11]中存放的是可以直接寻址到data blocks中的数据块,即直接寻址;而[12,13]是一级间接寻址,[14]是二级间接寻址(实际情况更复杂,了解实际寻址的时候有这种一级、二级、甚至三级映射的概念即可,这种寻址方式解决了文件大小问题,保证可以存放更大的文件)
5、目录是一种特殊的文件,利用指令对比普通文件和目录的信息
6、目录 = 文件属性 + 文件内容,目录的文件内容中存放的是文件名和inode编号的映射关系(获取目录中的文件时,会先依据文件名找到该文件的inode编号,然后再将该编号告诉OS,由OS负责寻找)
- 因此同一目录下不能创建同名文件(二者互为键值)
- 查找文件顺序是:文件名 -> inode number,文件名属性位于目录的数据块中而不是在inode结构体中这是为了保证inode结构体大小固定(如果结构体中还有文件名的话大小不固定,不便于管理)
- 目录r权限的本质是是否允许读取文件名和inode number的映射关系
- 目录w权限的本质是是否允许向目录中新增文件名和inode number的映射关系
问题:我们一直在用文件名访问文件,但是系统要的是inode number,为什么我们通过文件名就能访问到文件?
解释:正常情况下,我们在访问文件时一定位于某个目录下,那么我们仅通过文件名就可以基于该目录中存放的文件与inode number映射关系,告诉OS我们想要找的是一个inode number为多少多少的文件,然后由OS替我们去寻找
7、删除文件并不删除文件的内容和属性,而是将文件的inode bitmap由1变为0,这时虽然没有删除文件的内容和属性但是存放它们的值可以被其它文件的内容和属性覆盖了(Linux中误删文件后最好什么都别做,因为这可能导致被误删文件的内容和属性被覆盖,可以通过查找日志或是专业修复软件来恢复误删软件,但最好还是别误删文件)
24、2:00处文件增删改查的本质
8、windows的回收站本质是一个目录,删除文件的本质就是将该文件复制到该目录下,将linux中的rm指令功能修改为mv并令mv指向一个自定义的回收站就可以实现linux的回收站功能(这也是为什么回收站中的内容仍然是占据磁盘空间的)
问题:打开dir目录中的.txt文件就要找到该文件与inode number的映射关系,但是如何找到dir呢?
解释:要找到dir就要去存放dir的目录中寻找该目录中文件名dir与inode number的映射关系,要找到存放dir的目录就要去更上一层的目录寻找映射关系(逆向的路径解析,由OS完成,这也是为什么我们在linux中,定位一个文件在任何时候都要有路径的原因),直到根目录时才会利用映射关系一层层的向下找去(根目录在系统启动时就存好了默认设置好的映射关系),linux会进行路径结构的缓存便于我们下次更快的找到文件
问题:已经知道通过inode number可以在当前分区中找到文件所在的分组,那么如何确定文件在哪个分区?
解释:根据文件所在完整路径的前缀,因为每个分区的名字都不同
9、任何一个分区在使用时,该分区曾经一定会被写入文件系统(格式化)然后该分区会挂载到指定的目录下,当我们在访问一个分区时,只有进入该目录才能在该分区中进行文件操作
终极结论:对文件的所有操作(open等方法对文件进行操作时可能仅有"文件名"没有路径)一定涉及路径(为了逆向解析),因为只有通过文件所在路径才能知道该文件所在分区(每个进程的cwd中都会记载文件当前所在的路径,该路径 + 文件名就可以拼成一个完整的路径,然后由OS进行逆向解析,解析到该路径的前缀就可以确定文件所属分区,然后一层层的拿到文件与inode number的映射关系,直到进入文件所在分区)最后在该分区对文件进行操作,没有路径确定文件的具体位置,那么对文件的各种操作就是无法落地的一纸空文(即找到路径->确定分区->文件操作,注意!!!这是OS层面的内容,在用户看来是直接在当前目录下创建的文件)
这篇文章也可以:详细讲解,Linux内核——文件系统(建议收藏) - 知乎 (zhihu.com)
~over~