磁盘数据块大小的由来
在我们的硬件平台上,CPU不能直接读取硬盘上的数据,而是通过内存先将硬盘上的数据读入并保存,在x86平台上,32位的处理器只能寻址到4G大小的内存空间,内存的存储单元是被编址的,这样CPU可以读取内存中每个存储单元中的数据,内存的存储单元又被称为页框,Linux系统默认每个页框是4K大小,进而硬盘的数据块依据内存页框的大小来分配基本的存储单元,每个存储单元不能大于4K,这也是为什么我们的磁盘数据块大小1K,2K,4K这样几种类型的原因,这样每次读取4个或者是2个或者1个数据块到内存的一个页框中,所以硬盘的数据块大小是由CPU硬件平台直接决定的。
文件系统的组成
我们的磁盘分区犹如图书馆,如果要在方便在磁盘上查找存储的文件,那么文件的实际存储需要分类,编号,再查找索引。
创建分区后,如果要对文件实现快速存取,就需要在分区上创建文件系统,文件系统是个软件,是存储在磁盘上的,它本身不在分区上,它是一个管理软件,用来对存储数据进行管理,它能把一个分区化成两部分,一部分是原数据存储区,元数据的存储单元叫做inode,另一部分是数据存储区,数据存储区被划分为一个个逻辑存储单元,这些存储单元叫磁盘块,叫做block。
数据在磁盘上的存储
Linux系统中每个文件都有对应的inode号,权限,属主属组,时间戳,文件大小等信息,这些信息被称为元数据,被存储在inode中,它们是方便我们在硬盘上查找文件的数据信息的,而我们的硬盘在被格式化以后,会被划分为数据区和元数据区,所以我们看到的数据的存储空间会少于原有磁盘空间大小,损失的部分用来保存文件的元数据而提前预留出来了。
一个文件有了具体的元数据信息保存在inode中,对应的数据存储在磁盘块上,但是如果文件很多,我们在查找对应的文件的元数据信息或者数据信息,还是要以遍历的方式去查看整个元数据区和数据区,这样的速度会很慢,所以出现了inode位图和块位图。这两个种位图都存放在元数据区。
在块位图中,为每个数据块对应一个位,使用了的块会在对应的块位图中标记为1,未使用为0,同样在inode位图中,每个inode也有相应的标记位,使用了的标记为1,未使用的标记为0.
在查找文件的块位置的时候,就查找块位图,而不是再遍历整个分区,这样可以加速查找空闲磁盘块的位置,inode位图的效果也是一样。
由于磁盘是在分区格式化以后才能使用的,其数据块大小在格式化时就固定了,于是出现元数据区的大小和数据区的大小要有合适的比例的问题,如果存储的文件很大,每个文件都占据很多的磁盘块,所需要的inode空间就不会很大,相应的,如果存储的文件都很小,那么文件占据的磁盘块就不会很多,而需要的inode空间就比较多,所以在分区格式化时要根据我们存储文件的类型特点来提前指定数据块的大小,避免空间的浪费。
我们知道在inode中存储的文件的大小和磁盘块存储位置的信息,一旦这些元数据比如数据块的位置信息特点大的情况下,那么它对应的inode就不足以存储它占据的磁盘块信息,所以这样的情况下,就需要分级指向,就需要二级间接目录,甚至是三级间接目录等也就是二级inode,三级inode,而允许扩展的inode信息就限制了单个文件的最大大小。
事实上,我们在磁盘并不是把整个磁盘作为一个组织来管理的,为了尽可能在扫描的时候,每个位图对应的位都足够小,而且扫描的速度足够快,就算我们是按范围查找,也足够快,我们的系统,是首先要将我们的磁盘的数据块划分成块组,每个块组都有自己的inode表,块位图,Inode位图,将来我们扫描一个块的时候,我们是一个组一个组进行的,对文件来讲,我们的文件可以跨块组的,但是我们的扫描过程是一个块组一个块组的进行的,事实上,对一个分区来讲,有几个组?这取决于你的空间大小,一个组应该有多大,这取决于你的块位图和Inode位图的大小来决定的,一般来讲一个位图都是用一个磁盘块来标识的,一个数据块比如有1K,1024byte*8bit,这是一个位图能标识的所有位,那这意味着,一个位对应一个磁盘块,那最多可以管理固定数量的磁盘块,如果块大小是4K,那么块位图占据一个磁盘块,它能标识4*1024*8个磁盘块,在不同大小的磁盘空间上,块组数量也是肯定不一样的,块组的大小是由块和块位图共同决定的,块大小影响到块位图的空间大小,块位图的大小决定了块组能标识的数据块的多少,也就决定了块组的大小,不同的分区大小,块组的数量也就不同,但是,在创建文件系统的时候,一共创建了多少个块组,在我们的元数据区域里保存了,叫做超级块,superblock,如果一个磁盘的超级块坏了,那么块组信息,块组中的信息就都丢失了,因此,超级块的信息要有多个备份。超级块中保存的是整个分区的全局信息,包括1、块组数,2、每个块组包含多少块,3,块大小,4,空闲磁盘块,已经使用磁盘块,空闲inode,已经用的inode,整体的信息都在里面。
而块组从哪个块开始,哪个块结束,这个信息也类似于文件所占的数据块位置信息,这个信息可能会很大,所以这个信息不在超级块中保存,超级块只是占据了一个块的空间,它可能会记录不下来这么多的信息,所以我们还要借助于块组描述符表来描述这些信息,这也是一个数据块,它里面保存了当前系统上有多少个块组,每个块组从哪个块开始,到哪个块结束。
数据在磁盘上真正的存储方式是:
1、超级块:定义各个块组的信息,这个和我们常看到的分区不是一个概念,它也是逻辑的,我们通过fdisk命令可以查看到。
2、块组:每个块组里面定义了元数据索引位图,也就是inode位图,还有数据块位图,和inode。