我在玩拇指驱动器时发现了一种违反直觉的趋势。
我使集群大小(Windows 中的分配单元大小,Linux 中的块大小)越大,报告的容量就越少。
这很奇怪,因为基本逻辑要求相反——更大的集群应该导致更少的文件系统元数据,这应该产生更多的可用空间。关于我可以在互联网上找到的“最佳”集群大小的建议的每一页都重复了这一点(此时有十几个)。
这里有一些数字exFAT
。
容量[字节] | 簇大小 [KiB] | 差异[KiB] |
---|---|---|
15792537600 | 64 | |
15792472064 | 128 | 64 |
15792340992 | 256 | 128 |
15792078848 | 512 | 256 |
15791554560 | 1024 | 512 |
15789457408 | 2048 | 2048 |
15783165952 | 4096 | 6144 |
此外,差异列中的模式在最后一行中断......
而现在NTFS
。
容量[字节] | 簇大小 [KiB] | 差异[KiB] |
---|---|---|
15794679808 | 4个 | |
15794675712 | 8个 | 4个 |
15794667520 | 16 | 8个 |
15794667520 | 32 | 0 |
15794634752 | 64 | 32 |
15794569216 | 128 | 64 |
15794438144 | 256 | 128 |
我们又一次得到了一个异常的差异。
方法:通过 windows 资源管理器格式化实用程序完成格式化。通过 Windows 资源管理器属性收集的容量数据。分区表:GPT。
那么为什么更大的集群产生更少的容量呢?
随机琐事:exFAT 在 2019 年获得了某种“开源”。
exFAT 文件系统规范
exFAT 的情况。
鉴于 exFAT 具有公开且易于访问的规范,它是最容易处理的示例。
使用Joep van Steen 建议的DMDE工具,我们可以检查磁盘上文件系统的确切结构。
磁盘在硬件中分为扇区^。那是数据的基本单位。
有几种类型的元数据和效果决定了可用数据的确切数量。
分区:分区方案和分区边界本身根据一些非常简单的规则将磁盘划分为可用的部分。两种最流行的方案是:MBR 和 GPT。我没有详细研究MBR。
文件系统结构:在分区的开始处开始与文件系统相关的结构和元数据。第一个扇区是文件系统的引导扇区(这与引导您的机器无关)。它定义了它是什么类型的文件系统及其布局。不同类型的文件系统根据需要和设计将不同类型的数据放在那里。这是我的闪存驱动器的引导扇区:
exFAT 是一个基于 FAT 的文件系统,因此它会说明 FAT 表的长度和位置。
它还说明了集群堆所在的位置。集群堆是用户可以放置滑雪视频和猫图片的所有空间。
文件系统元数据:到目前为止,我们已经测量了扇区中的数据和位置。文件系统是一种用于以简单且一致的方式管理这些扇区的结构。它根据其设计创建自己的数据单元,并根据其内部机制进行管理。(这是添加抽象层的示例。)这些数据单元称为集群。每个簇可以是一个或多个连续扇区。它们只在文件系统范围内有意义。上面的引导扇区说明了它们有多大(作为 2 的幂),这个集群堆从哪里开始,以及我们有多少。
$BITMAP
)。位图中的每一位指定相应的簇是否空闲。剩余空间:我们将驱动器上的空间和分区中的空间分成小块。但有时空间并不能与所有的小块整齐地对齐。就像你给浴室贴瓷砖,一开始是整块瓷砖,但最后你放不下整块,所以你必须把它切掉一部分。
除了在我们的例子中,我们不能削减它,所以一点点(任何不能容纳整个集群的少量空间)被闲置。群集大小越大,可能未使用的空间就越多。
完整答案
以上就是exFAT问题的充分必要说明。
以上广泛适用于所有文件系统,但细节可能不同(例如,另一个文件系统可能不会像 exFAT 那样将前 2 个簇留空)。
我创建了一个电子表格来展示这些关系:
exFAT 中的簇大小与可用空间
观察:
这些数字与报告的驱动器容量完全吻合^^^。
就元数据效率而言,将何种文件放入文件系统并不重要。(无论如何,对于 exFAT 和其他静态元数据文件系统,如
ext4
.)由于平铺问题(请参见上面的 4),文件大小仍然很重要。从统计上讲,平均而言,您将浪费
(文件数)*(簇大小
的一半)空间
btrfs
能够用完这个闲置空间。这称为块子分配。
根据特定驱动器/分区的大小,将有一个元数据效率的最佳点(电子表格中的粗体列)。求最小的数字。
您可以查看每个单元格中的公式,了解每个值的计算方式。
表格中有许多附加评论
有 2 个硬编码参数(通过查看格式化后的结果发现,而不是根据先前数据计算):FAT 长度和 Cluster 堆偏移量。
fmifs.dll::FormatEx
) 来执行实际操作。FAT len
。查看末尾的列,并注意min FAT len
列中突然出现的相同值。但是我没有数学印章来推断它。我欢迎帮助。编辑:奖金优化时间。有一个点,高集群大小的浪费空间变得大于元数据的节省。这取决于文件系统上的文件数量。我在末尾添加了一个新列来展示这种关系。
注意:我欢迎对电子表格做出贡献。如果你想贡献,请求访问,你将被授予。
^ 这里有一些抽象层,比如高级格式和 NAND 页面大小,我们不会在这里讨论。这些抽象是由设备本身强加的,并且(大部分)对操作系统是透明的。
^^ 操作系统在格式化时可能会破坏抽象以避免对齐问题。请参阅高级格式。
^^^ 除了1 cluster = 1 sector,具体原因我没有详细探究。
这不是答案,但它可以帮助您确定正在发生的事情并扩展我的评论。自从我深入研究以来已经有一段时间了,所以有点生疏..
首先我们需要引导扇区的一些值:
我们现在可以计算数据区域,即减去 FAT 等元数据后剩余的文件系统区域:
数据区开始 = 保留 + (2 * 每个 FAT 的大扇区),所以数据区开始 = 7166 + (2 * 513) = 8192。
我们还可以确定每个簇的扇区,我们读取 8 个扇区,扇区总数为 532480。因此数据区域大小 = 524288
来自同一分区的 clustermap 的总集群:
所以我们看到差异 524304 - 524288 = 16 这实际上占 2 个集群。嗯。这实际上可能是正常的,我必须检查一下。
现在我要说的是,你可以用不同的集群进行试验,看看数字会发生什么,看看你观察到的这种怪异现象从何而来。
我的理论是/曾经是格式将“玩”保留扇区值,以便可能在 4k 边界对齐数据区域,例如,如果分区从奇数 LBA 开始,但它可能还想避免奇数个簇或未完全使用脂肪扇区。
保留扇区主要是“丢失的空间”,这可能会以某种方式影响数学计算可寻址集群数量的方式。但请注意,这只是一个假设。该区域越大,集群的空间就越小。因此,通过修改它的大小,它可以对齐簇,可以避免奇数个簇,并可以确保所有 FAT 条目都与实际簇相对应。
所以再次,不是答案,但也许它有助于缩小答案范围。
对于 NTFS,这是一个完全不同的故事,因为它没有像 FAT 这样的一组固定的文件系统元数据结构。$MFT 可以增长/收缩(尽管我从未见过它做后者),我想只要有大量空闲簇,$Bitmp 就可能在很大程度上是稀疏的,仅举出一些差异 exFAT <> NTFS。
对于作为一个整体的“数据区域”而言,它并不重要,因为文件系统元数据本身被 NTFS 视为文件。并且整个分区被分成簇,所以第一个扇区也是第一个簇的第一个扇区。
我写了一个小的 python 脚本来给我们一些见解:
这是输出:
对于 NTFS 的情况,答案很简单:当集群大小变大时,分区的不可用/“不可集群”“剩余部分”也会变大。
对于 exFAT 案例,这也是原因之一,但它更复杂,因为根据您获得的报告容量,至少 2MiB将被用于未知目的,而且它变得更加复杂,显然,占用的部分至少有 2 个簇大。
不过,我不熟悉 exFAT 的内部结构,所以我没有关于 2MiB / 2-cluster 的信息。
根据我所做的一些研究和测试(使用exfatprogs),似乎 2MiB 是"Cluster Heap Offset"的一个选择,它由一半大小的 "FAT Offset"组成。(基本上是 1MiB 对齐,这与 Windows 中的分区行为一致。)
此外,显然“FAT Length”通常与集群大小相同,微软似乎选择确保“FAT Offset”始终是“Cluster Heap Offset”的一半,因此当集群大小反过来“FAT Length”超过1MiB,“FAT Offset”将等同于“FAT Length”,导致“Cluster Heap Offset”变为2-cluster big。(未观察到此行为/exfatprogs 中的默认行为
mkfs.exfat
。)编辑:正如我所想但没有写的那样,不是让“FAT 偏移量”成为“集群堆偏移量”的一半,“FAT 偏移量”在所有/大部分时间都可以是 1-MiB,即剩余的填充/间隙,如果有的话,在“Cluster Heap Offset”中位于 FAT 之后而不是之前。
不过,我还没有真正检查过在 Windows 中使用 exfatprogs 生成的格式
dump.exfat
。如果您想知道确切和已确认的细节,您可以在 Linux 环境(甚至可能是 WSL)中自己尝试该程序。顺便说一句,显而易见的是,您的表中报告的容量是
cluster size * number of clusters
. 换句话说,任何集群中的数据和元数据(的大小)与数字无关。我将尝试回答这个问题,乍一看确实是违反逻辑的。
首先澄清帖子中使用的术语。簇大小与块大小不同,块大小由硬件决定,但簇包含多个块,是磁盘的分配单位。
一方面,簇大小越大,磁盘上的簇越少,因此管理分配位图和 FAT 条目的簇所需的开销越小。
另一方面,exFAT 磁盘格式(实际上是所有格式)按簇分配空间,因此如果数据(任何类型)没有完全占据整个簇,则剩余空间将被浪费。
我的想法是,不仅文件会以这种方式浪费空间,而且作为 exFAT 磁盘的一部分分配的磁盘表(或数据结构)也会如此。
查看 exFAT 文件系统规范,我试图计算定义的区域(或区域)。
我的统计是在创建 exFAT 格式时分配了大约 15 个区域,这些区域构成了它的结构。
当定义了更大和更少的集群时,这些区域中的每一个都不包含更多数据,有些实际上更小。其中一些区域占用的空间是按簇计算的,因此在扩大簇时,浪费的空间也被扩大了。
这可能解释了一些可用空间的浪费,但张贴者在浪费测量中的不规则性也可能表明这些表的分配存在错误,或者文档中缺少信息。