这个存储用户 block 编号的 block 所在块的编号我们叫做间接索引,然后我们根据跳转的次数可以分类成一级索引,二级索引,三级索引 。顾名思义,一级索引就是跳转 1 次就能定位到用户数据,二级索引就是跳转 2 次,三级索引就是跳转 3 次才能定位到用户数据 。那么 inode->i_block[15] 里面存储的可以直接定位到用户数据的 block 就是直接索引 。
终于可以说回 ext2 的使用了,ext2 的 inode->i_block[15] 数组 。知识点来了,按照约定,这 15 个槽位分作 4 个不同类别来用:
- 前 12 个槽位(也就是 0 - 11 )我们成为直接索引;
- 第 13 个位置,我们称为 1 级索引;
- 第 14 个位置,我们称为 2 级索引;
- 第 15 个位置,我们称为 3 级索引;
![深度剖析 Linux cp 命令的秘密](https://www.isolves.com/d/file/p/2021/04-06/c09a20c120ff6eda4b29e786b8aa149b.jpg)
文章插图
好,那我们在来看下直接索引,一级,二级,三级索引的表现力 。
直接索引:能存 12 个 block 编号,每个 block 4K,就是 48K,也就是说,48K 以内的文件,只需要用到 inode->i_block[15] 前 12 个槽位存储编号就能完全 hold 住 。
一级索引:
inode->i_block[12] 这个位置存储的是一个一级索引,也就是说这里存储的编号指向的 block 里面存储的也是 block 编号,里面的编号指向用户数据 。一个 block 4K,每个元素 4 字节,也就是有 1024 个编号位置可以存储 。
所以,一级索引能寻址 4M(1024 * 4K)空间。
二级索引:
二级索引是在一级索引的基础上多了一级而已,换算下来,有了 4M 的空间用来存储用户数据的编号 。所以二级索引能寻址 4G (4M/4 * 4K) 的空间 。
三级索引:
三级索引是在二级索引的基础上又多了一级,也就是说,有了 4G 的空间来存储用户数据的 block 编号 。所以二级索引能寻址 4T (4G/4 * 4K) 的空间 。
最后,看一眼完整的表示图:
![深度剖析 Linux cp 命令的秘密](https://www.isolves.com/d/file/p/2021/04-06/96003fc256631b0848e750dd76e839d2.jpg)
文章插图
所以,在我们 ext2 的文件系统上,通过这种间接块索引的方式,最大能支撑的文件大小 = 48K + 4M + 4G + 4T ,约等于 4 T 。文件系统最大支撑 16T 空间,因为 4 Byte 的整形最大数就是 2^32=4294967296 ,乘以 4K 就等于 16 T 。
ext2 文件系统支持的最大单文件大小和文件系统最大容量就是这么算出来的(温馨提示:ext4 文件系统不仅兼容间接块的实现,还使用的是 extent 模式来管理的空间,最大支持单文件 16 TB ,文件系统最大 1 EB) 。
思考:这种多级索引寻址性能表现怎么样?
在不超过 12 个数据块的小文件的寻址是最快的,访问文件中的任意数据理论只需要两次读盘,一次读 inode,一次读数据块 。访问大文件中的数据则需要最多五次读盘操作:inode、一级间接寻址块、二级间接寻址块、三级间接寻址块、数据块 。
多级索引和后分配
问题二解决:多级索引和后分配
一级索引不够,表现力太差,预留空间又太浪费,不预留空间又无法扩展,怎么解决?
既然问题在于预分配,我们使用后分配(瘦分配,或精简分配)解决 。也就是说用户文件数据有多大,我才分配出多大的数组 。举个例子,我们存储 100 G 的文件,那么就要用到三级索引块,最多分配 26214400 个槽位的数组(因为要 26214400 个 block) 。如果是存储 6K 的文件,那么只需要 2 个槽位的数组 。
索引数组的后分配
后分配这里说的是 block 索引编号数组的后分配,需要用到的时候才分配,而不是说,现在用户存储一个 1k 的文件,我上来就给他分配一个 100M 的索引数组,只是为了以后这个文件可能增长到 100 G 。
数据的后分配
既然这里说到,关于后分配还有一个层面,就是数据所占的空间也是用到了才分配,这个也就是涉及到今天 cp的秘密的核心问题 。
实际的栗子
先看下下正常的文件写入要做的事情(注意这里只描述主干,实际流程可能,有优化):
- 创建一个文件,这个时候分配一个 inode;
- 在 [ 0,4K ] 的位置写入 4K 数据,这个时候只需要 一个 block 假设编号 102,把这个编号写到 inode->i_block[0] 这个位置保存起来;
- 在 [ 1T,1T+4K ] 的位置写入 4K 数据,这个时候需要分配一个 block 假设编号 7,因为这个位置已经落到三级索引才能表现的空间了,所以需要还需要分配出 3 个索引块;
推荐阅读
- Linux查看硬件信息超强命令sar,以及可视化工具ksar
- 微信正在用的深度学习框架开源!支持稀疏张量,基于C++开发
- PC电脑|5分钟开机上千台 无影云电脑免费体验1周:Win、Linux通吃
- linux内核SMP负载均衡浅析
- 浅谈在Linux中如何将脚本做成系统服务开机自启动
- 寒湿型肥胖喝什么茶,喝什么茶排寒湿深度好文
- Linux服务器磁盘满了怎么办
- 色相饱和度深度解析,photoshop明度观察层是什么?原理讲解
- linux安装php步骤详解
- 「linux专栏」top命令用法详解,再也不怕看不懂top了