我有一个非常简单的测试程序,可以打印出以下数字。
即
int main(int argc, char* argv[]) struct statvfs vfs; statvfs(argv[1], &vfs); printf("f_bsize (block size): %lu\n" "f_frsize (fragment size): %lu\n" "f_blocks (size of fs in f_frsize units): %lu\n" "f_bfree (free blocks): %lu\n" "f_bavail free blocks for unprivileged users): %lu\n" "f_files (inodes): %lu\n" "f_ffree (free inodes): %lu\n" "f_favail (free inodes for unprivileged users): %lu\n" "f_fsid (file system ID): %lu\n" "f_flag (mount flags): %lu\n" "f_namemax (maximum filename length)%lu\n", vfs.f_bsize, vfs.f_frsize, vfs.f_blocks, vfs.f_bfree, vfs.f_bavail, vfs.f_files, vfs.f_ffree, vfs.f_favail, vfs.f_fsid, vfs.f_flag, vfs.f_namemax); return 0; }
打印输出:
f_bsize (block size): 4096 f_frsize (fragment size): 4096 f_blocks (size of fs in f_frsize units): 10534466 f_bfree (free blocks): 6994546 f_bavail free blocks for unprivileged users): 6459417 f_files (inodes): 2678784 f_ffree (free inodes): 2402069 f_favail (free inodes for unprivileged users): 2402069 f_fsid (file system ID): 12719298601114463092 f_flag (mount flags): 4096 f_namemax (maximum filename length)255
df输出根fs:
Filesystem 1K-blocks Used Available Use% Mounted on /dev/sda5 42137864 14159676 25837672 36% /
但是,这是我感到困惑的地方。
25837672 + 14159676!= 42137846(实际上是39997348)
因此,如果我要执行calc 14159676/42137864 * 100,我得到的df打印结果为33%,而不是36%。
但是如果我计算
14159676/39997348 * 100我得到了35%。
为什么所有差异以及df在哪里获得编号42137864?这与到1k块的转换与4k的实际系统块大小有关吗?
这将集成到我的缓存应用程序中,以告诉我驱动器何时处于某个阈值…例如90%,然后再开始释放固定大小为2 ^ n大小的固定大小的块。因此,我需要的是一个可以给我合理准确的使用率的函数。
编辑:我现在可以匹配什么df打印。除了已使用的百分比。这使我们想知道这一切有多精确。片段大小是多少?
unsigned long total = vfs.f_blocks * vfs.f_frsize / 1024; unsigned long available = vfs.f_bavail * vfs.f_frsize / 1024; unsigned long free = vfs.f_bfree * vfs.f_frsize / 1024; printf("Total: %luK\n", total); printf("Available: %luK\n", available); printf("Used: %luK\n", total - free);
编辑2:
unsigned long total = vfs.f_blocks * vfs.f_frsize / 1024; unsigned long available = vfs.f_bavail * vfs.f_frsize / 1024; unsigned long free = vfs.f_bfree * vfs.f_frsize / 1024; unsigned long used = total - free; printf("Total: %luK\n", total); printf("Available: %luK\n", available); printf("Used: %luK\n", used); printf("Free: %luK\n", free); // Calculate % used based on f_bavail not f_bfree. This is still giving out a different answer to df??? printf("Use%%: %f%%\n", (vfs.f_blocks - vfs.f_bavail) / (double)(vfs.f_blocks) * 100.0); f_bsize (block size): 4096 f_frsize (fragment size): 4096 f_blocks (size of fs in f_frsize units): 10534466 f_bfree (free blocks): 6994182 f_bavail (free blocks for unprivileged users): 6459053 f_files (inodes): 2678784 f_ffree (free inodes): 2402056 f_favail (free inodes for unprivileged users): 2402056 f_fsid (file system ID): 12719298601114463092 f_flag (mount flags): 4096 f_namemax (maximum filename length)255 Total: 42137864K Available: 25836212K Used: 14161136K Free: 27976728K Use%: 38.686470% matth@kubuntu:~/dev$ df Filesystem 1K-blocks Used Available Use% Mounted on /dev/sda5 42137864 14161136 25836212 36% /
我得到38%而不是36。如果用f_bfree计算,我得到33%。df是错误的,还是永远不会是准确的?如果是这种情况,那么我想靠保守一点。
df的数据可能基于而f_bavail不是f_bfree。您可能会发现查看df的源代码以了解其工作方式很有帮助。它有许多需要处理的极端情况(例如,当使用的空间超出了非root用户可用的空间量时),但是正常情况的相关代码如下:
df
f_bavail
f_bfree
uintmax_t u100 = used * 100; uintmax_t nonroot_total = used + available; pct = u100 / nonroot_total + (u100 % nonroot_total != 0);
换句话说100 * used / (used + available),四舍五入。插入df输出中的值,得到100 * 14159676 / (14159676 + 25837672) = 35.4015371,舍入为36%,与df计算得出的一样。
100 * used / (used + available)
100 * 14159676 / (14159676 + 25837672) = 35.4015371