【发布时间】:2023-03-28 22:40:01
【问题描述】:
我有一个非常简单的测试程序,可以打印出以下数字。
即
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,我会得到 33% 而不是 df 打印的 36%。
但是如果我计算
14159676 / 39997348 * 100 我得到 35%。
为什么会有所有的差异,df 是从哪里得到 42137864 的?是否与转换为 1k 块与实际系统块大小为 4k 相关?
这将集成到我的缓存应用程序中,以告诉我驱动器何时处于某个阈值...例如90% 在我开始释放大小为 2^n 大小的固定大小的块之前。 所以我所追求的是一个能够给我一个相当准确的 %used 的函数。
编辑: 我现在可以匹配 df 打印的内容。除了 %Used。这让我们想知道这一切有多准确。片段大小是多少?
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);
EDIT2:
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 是错误的还是永远不会准确?如果是这种情况,那么我想倾向于保守。
【问题讨论】:
标签: c++ c linux filesystems