目录
一、认识磁盘
一个磁盘由多个盘片组成,每个盘片有两个盘面和一个磁头,每个盘面上有磁道和扇区
每个扇区存储的数据量相同,但是越靠近圆心的扇区越小,越远离圆心的扇区越大,因此不同磁道上的扇区数据密度不同
寻找指定数据只需要找到存储数据的扇区即可,确定扇区位置需要使用CHS定址法:
- 确定盘面Header
- 确定磁道Cylinder
- 确定扇区Sector
二、操作系统对磁盘进行逻辑抽象
1.扇区数组sector disk_array[N]
将磁道展开,抽象为由扇区组成的数组sector disk_array[N]
假设一个磁盘800GB,由两个盘片组成,则共有四个盘面,每个盘面200GB,将盘面上的磁道展开即可抽象为数组
操作系统通过数组下标即可确定查询数据被存储在哪个扇区中:例如一个盘面上有10个磁道,每个磁道上有100个扇区,则一共有4*10*100=4000个扇区,数组下标即为[0, 3999]。
假设已知数据被存放在下标为2345的扇区中,2345/1000=2确定数据在第二个盘面上,2345%1000=345确定数据在第二个盘面的第345个扇区,345/100=3确定数据在第三磁道上,345%100=45确定数据在第三磁道的第45个扇区
由此实现操作系统对磁盘的逻辑抽象,可以根据下标找到实际磁盘中数据的具体存储位置
2.逻辑区块数组LBA blocks[N]
但是一个扇区往往很小,通常为512B,读取一个数据需要找到多个扇区,效率低。所以操作系统又引入了块,规定:1个块=8个连续的扇区,即4KB。
所以操作系统读取数据时就以块为单位,即LBA(逻辑区块地址),因此又有了LBA blocks[N]数组,只需要知道LBA blocks[N]数组的下标,再乘8即可得到扇区数组的下标,进而再通过CHS定址法确定数据在磁盘中的具体位置
3.磁盘分区
对于一个800GB的磁盘,通过块作为读取数据的基本单位还是太小了,因此操作系统又可以将磁盘进行分区,类似于C盘、D盘、E盘等,但实际电脑中只有一个磁盘。
三、文件系统
1.文件系统结构
磁盘分区后每个分区仍然很大不易管理,所以操作系统会在分区中再进行分组:块组
例如一个分区100GB,分为10个块组,每个块组10GB,只需要管理好一个块组,则其他块组使用同样的管理模式也能管理好
块组中存储着文件的内容和属性数据
Data blocks(数据区):所占空间最大,存储着文件的内容。其中分为许多LBA数据块,每个数据块都有编号
Block Bitmap(块位图):记录Data blocks数据区中哪个数据块被占用,哪个数据块没有被占用
inode Table(i节点表):存储文件属性,每个文件的属性都是一个大小固定的结构体。例如文件属性集合体的大小为128B,一个数据块为4KB,4*1024/128=32,i节点表中可以存放32个集合体。该结构体中包含文件大小、权限等,不包含文件名,因为包含了inode_number,在操作系统中使用inode号来唯一标识文件。除此以外还包含了datablocks[N],用于记录文件占用的数据块编号
inode Bitmap(inode位图):记录i节点表中哪个inode被使用,哪个inode没有被使用
GDT(块组描述符):描述块组的属性信息,包含块组的大小,i节点表中的inode个数,数据区中的数据块的个数,已使用/未使用的inode个数等
Super Block(超级块):描述当前块组所在分区的属性信息,包含分区的大小,分区中块组的个数,每个块组的使用情况等。超级块并不是每个块组中都有,而是部分块组拥有,这样既可以防止磁盘中存放超级块的位置被损坏从而丢失整个分区的信息,又可以节省空间资源
细节补充:
inode号和Data blocks中的数据块号在每个分区中是唯一的,i节点表中会记录当前块组中inode号和数据块号的范围。例如一个分区的每个块组中有1000个inode号,一个文件的inode号为1010,1010/1000=1,确定该文件的inode号存储在第1个块组中(前面有0号块组),1010-1001=9,inode号减去当前块组的起始inode号就可以确定在i节点表的第几个位置。又因为数据块号是以分区为单位唯一标识的,所以文件数据的存储可能存放在不同的块组中。但是不建议这样存储,因为存储数据块的不连续会导致磁盘振头和盘面的高速运转,降低效率。
Linux中ext2文件系统的i节点表中的datablocks[N]大小为datablocks[15],说明文件数据只存储在15个数据块中,但是一个数据块仅有4KB,显然这样的存储方式存储能力太小。其实datablocks数组中的前12个位置是物理映射,直接存储对应的数据块编号,而后三个位置是虚拟映射,其存储的数据块中,存储的又是一个datablocks数组,数组中又可以存储数据块编号,该数据块又可以存储datablocks数组,以此类推,这样的存储方式就可以大大提高文件存储空间能力。
2.如何拿到文件inode号?
ll -li
目录也是一个文件,也有文件属性和文件内容。目录文件的文件内容是该目录下文件名与inode号的映射关系,有了这个映射关系才能通过文件名找到inode号。
这也就是同一目录下不同有同名文件的原因
目录的r权限决定能否查看文件内容,即查看该目录下文件名与inode的映射关系,所以没有了r权限就不能查看该目录下的文件,因为找不到inode号。
目录的w权限决定能否写入文件,即在该目录下新增文件名的inode的映射关系,所以没有w权限就不能新建文件,因为无法新增inode号。
文件的删除其实也就是将对应块组中的inode位图置为0
综上所述,拿到一个文件的inode号,首先要找到该文件所在目录,而找到该文件所在的目录文件,又要找到该目录文件所在的目录,由此递推,直到根目录,对于根目录的文件名和inode都是确定的,所以可以拿到文件inode号。
3.如何确定文件在哪个分区?
不同分区有着相同的inode号,那么操作系统如何确定的文件在哪一个分区中呢?
分区被创建后,需要被格式化来包含文件系统结构。分区中有了文件系统后,操作系统会创建一个挂载点目录,并将分区挂载到挂载点上,分区被挂载后,用户和程序就可以通过挂载点目录访问分区上的文件,就像访问本地文件系统中的文件一样。
当打开一个文件时,操作系统会解析文件路径;操作系统会从路径的开始,逐级检查每个目录,直到找到文件所在的目录;对于每个目录,操作系统会查找其挂载点;一旦找到挂载点,操作系统就知道文件位于哪个分区。
标签:文件,存储,数据,分区,扇区,文件系统,Linux,inode From: https://blog.csdn.net/2301_76197086/article/details/142743697