一、了解磁盘
磁盘是计算机主要的存储介质,可以存储大量的二进制数据,并且断电后也能保持数据不丢失。下面,我们来简单了解一下磁盘的结构👇
1.磁盘的物理结构
磁盘是外设并且是我们计算机中唯一的机械结构(机械结构相对较慢)
磁盘的盘片/盘面就像光盘一样(盘面上存储数据),两面都有。而像刀子一样的是磁头(每一面都有一个磁头),磁头和盘面并没有接触,磁盘必须防止抖动。中间有马达,一旦盘片加电之后,盘片旋转,磁头摆动,马达可以控制磁头摆动,控制盘片旋转。对应的磁盘也有自己的硬件电路,通过硬件电路+伺服系统,给磁盘发二进制指令,让磁盘定位寻址某个区域。
2.磁盘的存储结构
磁盘寻址的时候,其基本单位既不是bit,也不是byte,而是扇区。
扇区的大小:512字节,512字节是硬件要求,对于外磁道和内磁道大小都是一样的,密度不一样。越靠近圆心的比特位越大,外侧的较小。
在单面上定位扇区:通过确认磁道,最终确定在对应磁道的哪一个扇区。确认磁道:每个磁道都有自己的编号,磁道周长不一样,但是存储大小是一样的,因为扇区大小一样,一个磁道有多少扇区也是固定的,所以每个磁道的扇区也有编址。所以定位到某个磁道上就能够找到。
机械硬盘的寻址方式:盘片不断旋转,磁头不断摆动,就是在确认在哪一个磁道,如何确认在哪个扇区?盘片也在旋转,就是让磁头定位扇区。
柱面:把一系列同心的磁道压在一起,宏观上看成一个整体。一般定位的时候:磁头、柱面、扇区====(磁头、磁道、扇区),这两个是等价的。柱面相当于磁头一起指向的位置就是柱面的边界位置。
在磁盘中定位任何一个扇区:先定位在哪一个磁道(哪个柱面),磁道确定,所有磁头共进退,此时磁头不动,在去定位磁头(定位盘面),最后在定位哪一个扇区。
总结:磁盘中定位任何一个扇区,采用的硬件级别定位方式(CHS定位法):柱面Cylinder——磁头Head——扇区Sector
3.磁盘的逻辑结构
类比于磁带,卷起来是圆形的,扯开是线性结构的。所以我们可以把磁盘盘片想象成线性结构。以OS为角度,则认为磁盘是线性结构,要访问某个扇区,只需要定位数组下标,也就是说知道这个扇区的下标就算定位了一个扇区。在操作系统内部,我们称这种地址为LBA(Logic Block Address)地址!而要写到物理磁盘上,我们就要把LBA地址转换成对应磁盘的三维地址CHS地址。总结来说,OS的地址为LBA地址,而对应的磁盘为CHS地址。
OS要进行逻辑抽象,不直接使用CHS:1.便于管理,管理数组与管理三维立体结构,数组比较好管理;2.不想让OS的代码和硬件强耦合!比如磁盘的基本大小改变,OS的源码有必要跟着变
二、文件系统与inode
文件在磁盘中是如何存储:文件是在磁盘中的,而逻辑结构是线性结构。磁盘的空间很大,虽然对应的磁盘的访问的基本单位是512字节,但是依旧很小,OS内的文件系统会定制的多个扇区的读取,以1KB,2KB,4KB为基本单位,所以即使读取/修改1bit,也必须将4KB加载到内存,进行读取或修改,在将其写回磁盘。我们采用分治的思想,来管理磁盘空间进行分区:大的磁盘空间->小空间,大事化小,给每个分区写入不同的文件系统。
Boot Block是启动块,存在每个分区的开头,备份文件与启动相关的。
将剩下的空间继续分组,Block group 0…Block group n。管理好Block group0,其他的也能管理好,所以我们只需要了解Block group 0:
Super Block:保存的是整个文件系统的信息,为什么Super Block不像Boot Block一样存在每个分区的开头?Super Block保存在不同的分组里意味着备份,如果某个Super Block损坏,便可以通过拷贝其他分组的Super Block。
Linux的文件=内容+属性,而Linux的文件内容是属性是分批存储的。保存文件属性的是inode,inode块的大小是固定的,为128字节。一个文件,一个inode,包含文件几乎所有的属性,文件名并不在inode中存储。文件内容存储在data block块中,不同的文件文件内容不同,大小随着应用类型的变化大小也在变化。inode为了进行区分彼此,所以每一个inode都有自己的ID,这里我们利用指令ls -li查看inode编号:
inode table:保存了分组内部所有的可用(已经使用+没有使用)inode,前面说了,一般来说一个文件对应着一个inode
Data blocks:保存的是分组内部所有文件的数据块
inode Bitmap:inode对应的位图结构,统计inode的使用情况,位图中比特位的位置和当前文件对应的inode的位置是一样对应的,比特位为1,代表inode被占用,否则表示可用。
Block Bitmap:数据块对应的位图结构,位图中的比特位位置和当前data block对应的数据块位置是一一对应位置
GDT(group descripteor table):块组描述表,对应分组的宏观的属性信息,已经使用多少,inode有多少个,已经被占用了多少个,还剩下多少个。
查找文件的时候,统一使用的是inode编号。
内容放在data blocks中,属性在inode table中,而inode内部保存了一个数组,保存对应块的编号,二者就联系起来了:
但是如果文件特别大?并不是所有的data block只能存放文件的数据,也可以存放其他块的块号,所以最终指向更多的block来存储
创建一个文件:在位图的比特位由0置为1,找到其inode table,属性填进去,文件的数据写到block里,在inode和block建立映射关系,最后返回inode编号,创建成功
查找一个文件:拿到inode找到inode table,在根据inode table找到对应的数据块,内容加属性就全找到了
删除一个文件:删除文件也需要用到inode,实际上删除一个文件时,我们只需要找到inode在inode bitmap当中的比特位,把比特位由1置为0就删除了。
所以删除一个文件根本不需要把数据属性和内容清空,只要把inode bitmap的1置为0,属性就删除了,这个文件也占着数据块,也把block的比特位也置为0。所以把文件删除是能够恢复的,一旦删除只是把bit位清掉了,想要恢复只要得到inode的编号,然后把inode bitmap里的比特位由0置为1,在去inode table对应的映射表,在block bitmap的0置为1。
如果在Linux中误删除一个文件,还是能恢复的,但是前提必须是inode和data block没有被占用,所以当误删除一个文件时,最好的办法就是什么都不做。而我们在Windows中删除文件到回收站,只是转移了目录,在回收站中删除才是真正的删除。
可是我们在查找一个文件的时候,用的不是inode,而是文件名?
任何一个文件都在一个目录下,但是这些文件并没有重复的文件名
目录是一个文件,也有自己的inode,有对应自己的data block,目录的数据块存放的是当前目录下的文件名和inode的映射关系,所以inode并不需要保存文件名。
所以我们在一个目录下新增一个文件,必须得有写入权限,新增一个文件的时候,要向当前目录的内容里去写文件名和inode的映射关系,所以必须得有写入权限。罗列当前的文件,要有读权限,想读的时候要根据文件名找到inode读取底下的所有文件的属性,读的是拿到文件名,必须得去访问数据块,所以要有读权限
三、软硬链接
1.软链接
创建软链接:(文件名不重要)
ln -s myfile.txt soft_file.link
有自己独立的inode的称为软链接,即软链接是独立的文件,独立的文件有独立的inode和对应的文件内容。
所谓的软连接标定文件并不是用inode来标记的,我们删除myfile.txt,然后再去cat soft_file.link:
所以这个软链接并没有用目标文件对应的inode,而是用目标文件的文件名,把文件删了找不到,软链接的数据块里保存的是所指向的目标文件的路径,所以目标文件一删,软链接也就失效了。
删除软链接:既可以rm,也可以用unlink
unlink soft_file.link
软链接相当于快捷方式。软链接的作用:
当执行路径非常的深,导致路径非常的长,我们可能会忘记路径,所以我们可以通过软链接不用每次都输入长长的路径,可以通过软链接而快速找到:
这就相当于Windows的快捷方式了。
2.硬链接
创建硬链接:
ln myfile.txt hard_file.link
不带上s就是硬链接了。
软硬链接最重要的区别在于是否具有独立的inode,硬链接没有独立的inode,指向到其他文件的inode,不是独立的文件,**建立一个硬链接是在做什么?**当硬链接其中一个文件的大小、内容等发生变化,那硬链接的文件都会发生相应的变化,所以建立硬链接根本没有新增文件,因为没有给硬链接分配独立的inode,既然没有创建文件那么就没有自己的属性集合和内容集合,用的是别人的inode和内容。创建硬链接本质就是在指定的路径下,新增文件名和inode编号的映射关系!
inode可能会被多个文件指向,所以inode有一个计算器,count的引用计数,把引用计数称为硬链接数:
这也是我们为什么能看到1变为2的原因,因为有了新的文件名,inode被两个文件所指向,硬链接数变为2了:
如果把硬链接的文件删除,原始对应inode编号的文件:
所以一个文件真正的被删除:当一个文件的硬链接数变成0的时候才是真正的被删除。
硬链接的作用:
为什么创建一个普通文件的时候,硬链接数是1?
因为一个普通文件本身就有一个文件名和自己的inode,具有一个映射关系!
为什么创建一个目录的时候,硬链接数是2?
首先目录和本身的inode就是一组映射关系了,另外,第二个是目录内部的.(.表示当前目录,也是文件名。inode是一样的)和inode也是一组映射,所以是硬链接数是2
现在在empty目录下在创建一个目录dir,此时empty目录的硬链接数变为了3:
因为此时dir的…文件指向上级的目录empty,所以硬链接数为3
四、总结
我们大致了解磁盘的物理结构、存储结构、逻辑结构;然后就是文件系统与inode的认识。
最后是软硬链接,软硬链接本质区别就是有无独立的inode.