更快的存储统计

在早期版本的 Android 中,系统会遍历特定应用程序拥有的所有文件来测量磁盘使用情况。在“设置”中向用户显示结果之前,这种手动测量可能需要几分钟的时间来计算。

此外,清除缓存数据文件的内部算法仅查看所有应用程序的修改时间。这使得恶意应用程序可以通过将修改时间设置为遥远的未来来不公平地偏向于其他应用程序,从而降低整体用户体验。

为了改善这些体验,Android 8.0 提供了利用 ext4 文件系统的“配额”支持来几乎立即返回磁盘使用统计信息。此配额功能还可以防止任何单个应用程序使用超过 90% 的磁盘空间或 50% 的索引节点,从而提高系统稳定性。

执行

配额功能是installd默认实现的一部分。当在特定文件系统上启用时, installd会自动使用配额功能。当正在测量的块设备上未启用或不支持配额功能时,系统会自动且透明地恢复手动计算。

要在特定块设备上启用配额支持:

  1. 启用CONFIG_QUOTACONFIG_QFMT_V2CONFIG_QUOTACTL内核选项。
  2. quota选项添加到 fstab 文件中的用户数据分区:
    /dev/block/platform/soc/624000.ufshc/by-name/userdata   /data
    ext4    noatime,nosuid,nodev,barrier=1,noauto_da_alloc
    latemount,wait,check,formattable,fileencryption=ice,quota

可以在现有设备上安全地启用或禁用fstab选项。在更改fstab选项后的首次引导期间, fsmgr会强制执行fsck传递来更新所有配额数据结构,这可能会导致首次引导花费的时间稍长。后续启动不会受到影响。

配额支持仅在 ext4 和 Linux 3.18 或更高版本上进行了测试。如果在其他文件系统或较旧的内核版本上启用,设备制造商负责测试和审查统计数据的正确性。

不需要特殊的硬件支持。

验证

StorageHostTest下有 CTS 测试,它使用公共 API 来测量磁盘使用情况。无论启用还是禁用配额支持,这些 API 都应返回正确的值。

调试

测试应用程序使用唯一的素数来仔细分配磁盘空间区域的大小。调试这些测试时,请使用它来确定任何差异的原因。例如,如果测试失败且增量为 11MB,请检查Utils.useSpace()方法以查看 11MB blob 是否存储在getExternalCacheDir()中。

还有一些内部测试可能对调试有用,但它们可能需要禁用安全检查才能通过:

runtest -x frameworks/base/services/tests/servicestests/ \
  src/com/android/server/pm/InstallerTest.java
adb shell /data/nativetest64/installd_utils_test/installd_utils_test
adb shell /data/nativetest64/installd_cache_test/installd_cache_test
adb shell /data/nativetest64/installd_service_test/installd_service_test