一.认识硬件–磁盘
1. 物理结构
1.2 存储结构
❓如何定位⼀个扇区呢?
可以先定位磁头(header)——》确定磁头要访问哪⼀个柱⾯(磁道)(cylinder)——》 定位⼀个扇区(sector)。
柱⾯(cylinder),磁头(head),扇区(sector),显然可以定位数据了,这就是数据定位(寻址)⽅式之⼀,CHS寻址方式。
1.3 逻辑抽象
我们知道磁带存储数据的结构是一个很长很长的带子,我们可以把磁带“拉直”,形成一个线性结构。
那么磁盘本质上虽然是硬质的,但是逻辑上我们可以把磁盘想象成为卷在⼀起的磁带,那么磁盘的逻辑存储结构我们也可以类似于:
这样每⼀个扇区,就有了⼀个线性地址(其实就是数组下标),这种地址叫做LBA
❓为什么扇区大小不均匀的但是LBA地址是均匀??
——》因为磁道是从中间向外辐射的,所以里面的磁道有多少个扇区,外面的磁道就有多少个扇区,只不过里面磁道的扇区会小一点(扇区大小不均匀) 但其实可以通过调整密度来变得均匀(里面的01序列稠密一点,外面的稀疏一点)
二.文件系统
通过逻辑抽象,我们可以把对扇区的地址抽象成线性的LBA地址,整个磁盘都可以被抽象是成一个一维数组。
但是具体磁盘有多大呢?已经用了多少扇区?哪些扇区还没被使用?哪些扇区存的是属性?哪些扇区存的是内容?要往哪个扇区去写入??——>诸如以上问题,注定了我们的操作系统必须想办法把磁盘空间组织起来!!
操作系统如何对磁盘空间进行管理❓
❗ inode存放的是文件的属性,Block存放的是文件的内容,在Linux文件系统中,文件的属性和内容是分开存储的!
2.1 inode
我们知道,文件 = 属性 + 内容,属性也是数据,要管理这些数据,就要以结构体的方式构建出来,这些管理属性数据的结构体,就是inode!一个文件就有一个inode,inode就是属性数据的集合。
❗ Linux系统里标记文件的唯一标识用的是inode,且文件的属性中不包含文件的名称!!
❓如何在Linux查到每一个文件的inode编号
ls -li
2.2 Data Block
❗ Data Block:存文件内容的区域,以块作为最小单位,块的大小常见的是4KB大小,一般而言一个块只有自己的数据!
❗ 一个文件只有一个inode,但如果是个大文件可能会有很多个块。所以在inode结构体内部会有一个block数组,存储的是数据块的块号,标识自己这个文件的内容占据了具体的哪一个数据块。注意:inode的block数组存的只是块号,而一个块号对应着一个Data Block(4KB)。
2.3 BlockBitmap和 InodeBitmap
InodeBitmap:是一个位图,每一个bit表示⼀个inode是否空闲可用。
BlockBitmap:同样是个位图,每一个bit记录着DataBlock中哪个数据块已经被占⽤,哪个数据块没有被占⽤
❓问题1: 为什么我们下载一个文件需要很久,但是删除的时候却很快呢??
❗删除一个文件的时候,并不会把块(文件内容)清空,而仅仅只是把对应比特标志位给修改了,表明该块是空闲可用的。
❓问题2:如果我们想恢复一个被删除的文件,要怎么办呢??
❗ 如果我们不小心误删的一个文件,如果这个文件很重要,最好的办法就是什么都不做然后找专业的人去恢复(一般来说恢复其实就是得找到该文件的inode编号,比如通过Linux的日志信息找到被删文件的inode,但是具体怎么恢复得依靠一些专业的东西!),因为虽然内容还在,但是他的位图信息表明是可以被使用的,所以你如果乱操作可能会导致文件内容被覆盖。
2.4 SuperBlock
存放⽂件系统本⾝的结构信息,描述整个分区的文件系统信息。记录的信息主要有:bolck和inode的总量,未使⽤的block和inode的数量,⼀个block和inode的⼤⼩,最近⼀次挂载的时间,最近⼀次写⼊数据的时间,最近⼀次检验磁盘的时间等其他⽂件系统的相关信息。SuperBlock的信息被破坏,可以说整个文件系统结构就被破坏了
❗格式化:就是写入空的文件系统!!
2.5 GDT(GroupDescriptorTable)
块组描述符表,描述块组属性信息,整个分区分成多个块组就对应有多少个块组描述符。每个块组描述符存储⼀个块组的描述信息,如在这个块组中从哪⾥开始是inodeTable,从哪⾥开始是Data Blocks,空闲的inode和数据块还有多少个等等。块组描述符在每个块组的开头都有⼀份拷贝。
三.深刻理解文件系统下目录文件
3.1 对文件操作,os怎么做?
❓新建和删除文件,在文件系统的角度下,os到底是怎么做的?
❗1️⃣新建文件
:OS会在某个路径下去创建,路径帮助我们确定在哪一个分区——》读取了超级块后确定了一个block,然后通过查该block的GDT知道该分区的inode还有很多没有被使用——》于是到inodebitmap位图结构里找到了没有用过的inode,然后分配给该文件——》分配好之后把自己的属性往里面填,这样就算新建成功了!
❗如果还打算写入的话,先确认一下要写入内容的大小,确定一下需要几个块,然后到blockbitmap里面找到没被使用的块,把块号填到inode结构体里面的block数组里,然后再把文件内容写进这些块里面。
❗2️⃣删除文件
:先找到分区,再找到inode,然后把对应inodebitmap和blockbitmap的位置置0。其实文件还在,只不过对应的块可以被覆盖。
❓但是我们会发现一个问题,就是在文件系统的角度下,os无论对文件进行怎样的操作,都要取到对应的inode号,进而才能对其操作,但是我们在对文件进行操作的时候,可从来没有关心过indoe号啊?!我们对文件操作向os提供的是文件的地址,os是怎么根据文件的地址知道文件的inode的???
❗回答这个问题必须先了解文件系统下的目录。
3.2 目录文件
首先要明白一个事实,那就是目录也是文件,也有自己的inode ,也是有内容+属性构成!
❓但是我们知道,目录文件跟普通文件不同的是,目录文件没有所谓的"文件内容"的,那目录文件的文件内容存的是什么?
❗有内容就要占据数据块,目录有自己的数据块,其中数据块存储的就是,在当前目录下的文件和其inode值的映射关系!!!!
我们可以借助这一结论回答很多问题,提升我们对文件的理解:
❓疑问1:在同一目录下,为什么不允许有同名文件?
❗因为文件名和inode是key和value的关系,通过文件名找到inode,key值必须唯一。
❓疑问2:为什么没有w权限无法创建文件??
❗没有w权限意味着我们就无法将文件名和inode的映射关系写进去,因此无法创建文件。
❓疑问3:为什么没r无法查看文件??
❗没有r权限着意味着我们也看不到文件名和inode的映射关系,找不到inode就找不到文件,也就找不到文件的内容。
❓疑问4:为什么没有x无法进入目录??
❗x意味着没有操作权限,要进入一个目录必须cd目录名,并且将当前目录名更新到环境变量PWD中,所以无法进行该操作的话我们就无法进入。
3.3 路径解析
❓问题:打开当前工作⽬录文件,查看当前⼯作⽬录⽂件的内容?当前⼯作⽬录不也是⽂件吗?我们访问当前⼯作⽬录不也是只知道当前⼯作⽬录的⽂件名吗?要访问它,不也得知道当前⼯作⽬录的inode吗?
❗所以也要打开当前⼯作⽬录的上级⽬录,类似"递归",需要把路径中所有的⽬录全部解析,出⼝是"/"根⽬录。
❗⽽实际上,任何⽂件,都有路径,访问⽬标⽂件,⽐如:
/home/lvision/code/test/test/test.c
都要从根⽬录开始,依次打开每⼀个⽬录,根据⽬录名,依次访问每个⽬录下指定的⽬录,直到访问到test.c。这个过程叫做Linux路径解析。
四.深刻理解软硬链接
4.1 硬链接
4.1.1 如何建立硬链接
ln a[源文件] b[硬链接名字]
4.1.2 如何理解硬链接
我们知道,真正找到磁盘上⽂件的并不是文件名,inode。其实在linux中,可以让多个文件名映射同⼀个inode,而这些新建立的,对indoe建立的映射关系,的文件,就是硬链接。
硬链接不是一个独立的文件,因为他没有独立的inode!!
-
Hardlink和myfile.cc的链接状态完全相同,他们被称为指向⽂件的硬链接。内核记录了这个连接数,inode 650257 的硬连接数为2。
-
我们在删除⽂件时干了两件事情:1.在目录中将对应的记录删除,2.将硬连接数-1,如果为0,则将对应的磁盘释放。
硬链接应用场景:通常用来做路径定位!!可以通过硬链接进行目录切换!
4.1.3为什么Linux不允许对目录建立硬链接
如果对目录建立硬链接,就可能会出现这样的情景,
❓可是目录内部不是有. 和 … 的硬链接,他们不是目录的硬链接吗??
-
. 和 … 是操作系统创建的,操作系统提前规定好了 .和…不会被做搜索,这是强制规定的!所以不会有环的问题!
-
操作系统给我们. 和 … ,我们就可以用相对路径去访问文件了,可以在一些情境中不必用很长的绝对路径去访问文件。
4.2 软链接
4.2.1 如何建立软链接
ln -s a[源文件] b[硬链接名字]
4.2.2 如何理解软链接
软连接是一个独立的文件,有独立的inode,也有独立的数据块 ,他的内容里面保存的是指向的文件的路径。(相当于windows的快捷方式)
应用场景:快捷方式