我在多级分页中也遇到了同样的困惑。对于 inode,我们有指向数据块的直接和间接指针。但是,对于小文件,我们更喜欢使用间接指针,因为它们可以为我们的目的存储更多的指针。
但是,为什么在一级上按顺序存储直接指针会更消耗数据,而如果我们使用间接指针则更少呢?当然,指针都必须存在于文件系统中的某个位置,并且会产生相同数量的空间,不是吗?这个额外的空间是从哪里来的?
这是我认为的一个例子:如果我有 10 个直接指针和 2 个间接指针,每个指针分别导致 128 和 128^2 指针,那么消耗的总大小是否与 10 + 128 + 128^2 相同直接指针?如果没有,如何节省空间?
作为一个附带问题,inode 的典型大小是多少,为什么 inode 的大小会有所不同?
inode 级别的原始层次结构大致如下:
您可以直接在 inode 中存储一个或几个块号。这意味着您为 inode 多使用了几个字节,但对于小文件,您不必分配一个完整的块,该块大部分是空的。
下一级是一个间接:分配一个块来存储块指针。仅此间接块的地址存储在 inode 中。这不会以某种方式使用“更少的空间”,并且大多数文件系统,甚至是早期的文件系统,都是这样工作的(在 inode/filename 附近有一个指针,它指向一个块,该块存储文件的块号)。
但是当这个块中的空间用完时你会怎么做?您必须分配另一个块,但是您将对该块的引用存储在哪里?您可以将这些引用添加到 inode,但要存储更大的文件,inode 会变大。并且您需要小的 inode,因此尽可能多的 inode 可以放入一个块中(更少的磁盘访问以读取更多的 inode)。
所以你使用了两级间接块:你只需添加一个指向 inode 的指针,然后你有一个完整的块来存储指向间接块的指针,间接块存储文件本身的块地址。
依此类推,您可以添加更高级别的间接块,或在某个阶段停止,直到您达到具有所需结构的文件的最大大小。
因此,重点不是“总共占用更少的空间”,而是“使用一种有效地使用块的方案来实现文件的预期分布,即许多小文件、一些大文件和很少的大文件”。
另一方面,页表的工作方式非常不同。
编辑
要回答评论中的问题:
数据块的大小是固定的(最初是 512 字节,IIRC),是底层硬盘块大小的倍数。所以数据块大小不能“减少”。
正如我在上面试图描述的那样,让 inode 不占用太多空间的全部意义在于使inode 访问更快(或者,使缓存 inode 使用更少的内存 - 那时,当带有 inode 的 unix 文件系统被发明时,计算机的内存比今天少得多)。这不是以某种方式节省空间。正如您自己所说,所有东西都必须存储在某个地方,如果它不使用位置 X 的空间,它将使用位置 Y 的空间。
仅仅向inode添加可变数量的块指针是不切实际的,因为inode必须占用固定数量的空间——你想用inode号来计算块地址和inode信息所在的块内的偏移量存储。如果每个 inode 的大小不同,您就无法做到这一点。所以必须有某种形式的间接性。
页表的工作方式不同,因为硬件实现它们的方式不同——就是这样。层次结构具有固定的深度,始终相同(尽管有时可配置。虽然从磁盘读取块很慢,但这对于页表来说并不重要。所以设计问题完全不同。