磁盘
电脑中存在非常多的文件,被打开的文件只是少量的。
没有被打开的文件,在磁盘中放着,那么文件是如何存取?
看看物理磁盘
计算机只认识二进制:什么是0,1?
0,1在物理上会有不同的表现(比如有无、高低电频等)
磁盘里面的结构:
磁盘的存储结构
磁盘是一个机械设备,是外设。交互效率很慢。
小时候玩过的磁铁,比如S表示0、N表示1。通过磁头改变磁盘的磁性
每个扇区都是512字节,靠圆心近的,512字节密集,远的稀疏。
如何找到一个扇区?(CHS定址法)
1.先找到哪个磁头(Header)。
2.找到指定的磁道(Cylinder)。
3.找到指定的扇区(Sector)。
磁盘中的盘片为什么要旋转?
定位扇区。
磁头要左右摆动?
定位磁道。
磁盘文件 == 文件 = 内容 + 属性 = 都是二进制数据
文件存储在磁盘 -> 文件在磁盘中占据几个扇区
对磁盘的储存进行逻辑抽象
如果OS直接使用CHS定址法,耦合度太高。磁盘结构一改,OS也得跟着更改。
以磁带为引例:
假设磁盘有800G的内存,2个盘片组成。前200GB就是一面。
这个工作是磁盘内部做的,以500号下标为例子计算一下CHS
500/100 = 0;第一个盘面
500%1000 = 500;
500/100 = 5;第6个磁道
500%100 = 0;第一个扇区
文件 = 很多个sector的数组下标
保存一个文件,比如要用到100个扇区,只要记录100个sector都交给磁盘!
内存和外设进行IO交互时,512字节小不小?
一般而言,OS未来和磁盘交互的时候,基本单位:4 KB(可以更改,改了OS得大改)。一次性读8*sector,连续的8个扇区。
把4KB称为一个块
这样管理LAB block[N]数组就可以了。
对于800G的磁盘来说,但只要把200GB(一个盘面)管理好,就能把800GB管理好
把800GB进行分区,跟电脑上分盘是一个道理(我这里没分)
一块区如何管理好?
分组:只要管理好一个组,那么就能管理好每一个组。
文件 = 内容 + 属性(也是数据) 0KB是内容为0 属性不为0
文件在磁盘储存,本质是:文件的内容 + 文件的属性数据
Linux文件系统特点:文件内容和文件属性 分开储存。
先搭起文件系统的框架,再谈细节:
通过ll -il
就能看见inode号
那我们怎么知道inode占据哪些Data blocks里面的块?
inode结构体里面有datablocks[N],保存着该文件用了哪几个块。
GDT (Group Descriptor Table):块组描述符,描述块组属性信息(块有多大、有多少inode Table被使用了)。
比如块组还剩下1GB的空间,要写入2GB的文件,写不下。
超级块(Super Block):存放文件系统本身的结构信息。记录的信息主要有:bolck 和 inode的总量,未使用的block和inode的数量,一个block和inode的大小,最近一次挂载的时间,最近一次写入数据的时间,最近一次检验磁盘的时间等其他文件系统的相关信息。Super Block的信息被破坏,可以说整个文件系统结构就被破坏了。
Super Block描述的是整个分区,一个组里面可以有多个Super Block,也可以没有,一个区每个组中的Super Block内容都是一样的。(多个防止某个Super Block被损坏,若损坏可以通过其他组的Super Block进行修复)
格式化:在磁盘中重新写入文件系统!
综上所述:我们寻找文件的时候,必须先得到文件的inode号
inode号
inode编号是以分区为单位分配的,一个分区的inode号是不能重复的。两个分区是可以重复,所以不能跨分区访问。
开始的时候,Super Block与GDT会记住inode的范围[start_inode,end_inode]
以寻找inode==50为例子:
关于inode属性中的datablocks[N]谈论下:
我们目前讲述的都是ext2文件系统,常用的是ext3、ext4。ext3、ext4比ext2多了日志安全等功能。
不同的文件系统,文件属性的大小不一定相同。下面都是以128KB为例:
如果文件大小为20GB,大于分区的10GB的可以吗?
答案是可以的,因为Data blcoks的编号是以分区为单位的,可以指向其他分组。但非常不建议,一旦跨组的,就代表磁针和磁盘要进行其他寻址(本来指向0组,现在要指向其他组)。
现在只要找到了inode编号,就能找到文件。但如何找到inode编号?我们平时访问时都用的文件名
文件名 -> inode
以目录入手:Linux一切皆文件,所以目录也是文件,那么目录也有他自己的inode
目录 = 文件属性 + 文件内容
目录的属性与普通文件的属性做对比:属性的类型一样,值不一样。
目录内容放的是:文件名和inode编号的映射关系
综上所述:1.一个目录下不能建立同名文件(因为映射关系)
2.查找文件的顺序,文件名 -> inode 编号 (目录里面保存着文件名,所以inode属性里面不用保存文件名)
3.进入目录需要x权限。
目录的r权限:本质是是否允许我们读取目录的内容,拿到文件名与Inode的文件关系!
目录的w权限:新建文件的本质,最后一定是想要向当前所在处的目录内容中写入文件与inode的映射关系
一个文件新建的过程:
首先向特定的分区当中申请一个inode,Super Block会记录该分配哪个inode,分配一个就++,根据inode确定在哪个分组里。然后在inode Bitmap找位图,从低向高找,看哪个为0,给我们分配的新的偏移量+新分配的inode编号就是新的inode,根据新的inode号在inode Table里把属性一写。在Blcok Bitmap里面申请位图,把Data blocks里面申请的块往inode Table里面一写,建立映射关系,返回inode编号,再与文件名建立起映射关系,就新建一个文件了。
删除一个文件:
根据文件名,找到inode编号,遍历datablocks数组,根据数组内容把Block Bitmap中的数据依次清成0。然后找到把inode在位图的位置由1->0就删掉了,inode Table和Data blocks里的数据不用动。
这就是为什么我们在电脑里,下载内容要很长时间,删除很快。
在Linux中文件被误删了,是可以恢复的,找到相应的位图由0->1就可以恢复。不过前提是文件不能被覆盖。
windows的回收站本质是一个目录,rm -> mv
Linux内核在被使用的时候,一定存在大量的解析完毕的路径,要对访问到的路径做管理->先描述,在组织
源码:
以上都是确定分区才有效
判断文件在哪个分区
云服务器一般都只有一个盘vda,vda对应的vda1一个分区
一般要访问一个分区,要把一个分区进行挂载,要将磁盘分区和文件目录进行关联,进入磁盘分区其实是进入指定的目录
下面就是挂载到/dev/vad1中的根目录,所以在根目录写的内容全在/dev/vda1的内容里