我想使用 statvfs 的返回值来获取总的和可用的文件系统大小。
unsigned long f_bsize; /* Filesystem block size */
unsigned long f_frsize; /* Fragment size */
fsblkcnt_t f_blocks; /* Size of fs in f_frsize units */
fsblkcnt_t f_bfree; /* Number of free blocks */
...
来源:https://man7.org/linux/man-pages/man3/statvfs.3.html
因此,为了获得文件系统的总大小,似乎我想要f_blocks * f_frsize
,因为评论f_blocks
说它是“以单位为f_frsize
单位”的大小。然而,f_bfree
是空闲块的数量。因此,对于免费文件系统大小,我必须使用f_bsize
?还是f_frsize
再来一次?
答案1
块碎片似乎是某些遗留文件系统中的一个文件系统功能(谷歌搜索表明 UFS 和 JFS 有它的用处)。
片段大小似乎指示片段允许的最小值,并且应该介于 1 和 之间f_bsize
。
在不支持它的文件系统上,该值应该等于f_bsize
(或为零,见下文),因为不支持块的进一步碎片。
如果您检查coreutils
源代码(至少在基于 Redhat 的系统上),您可以看到 GNU 如何在df
.给定 GNU 是应该为了使用各种 UNIX(而不仅仅是 Linux)处理各种 POSIX 语义,它应该就如何解决这个问题提供相当可靠的建议。
在lib/fsusage.c
120 if (statvfs (file, &vfsd) < 0)
121 return -1;
122
123 /* f_frsize isn't guaranteed to be supported. */
124 fsp->fsu_blocksize = (vfsd.f_frsize
125 ? PROPAGATE_ALL_ONES (vfsd.f_frsize)
126 : PROPAGATE_ALL_ONES (vfsd.f_bsize));
127
128 fsp->fsu_blocks = PROPAGATE_ALL_ONES (vfsd.f_blocks);
129 fsp->fsu_bfree = PROPAGATE_ALL_ONES (vfsd.f_bfree);
130 fsp->fsu_bavail = PROPAGATE_TOP_BIT (vfsd.f_bavail);
131 fsp->fsu_bavail_top_bit_set = EXTRACT_TOP_BIT (vfsd.f_bavail) != 0;
132 fsp->fsu_files = PROPAGATE_ALL_ONES (vfsd.f_files);
133 fsp->fsu_ffree = PROPAGATE_ALL_ONES (vfsd.f_ffree);
134 return 0;
在他们的代码中,他们将 POSIXstatvfs
结构复制到自己制作的结构中,但重要的部分是124-126
显示他们正在做什么的行:使用f_frsize
if 不为零,否则使用f_bsize
.
我的建议是复制他们的方法,因为df
在野外和时间上已经看到了极其广泛的分布。人们希望有人会指出,如果它不正确,那么现在它报告了错误的值。
您还应该意识到更现代的文件系统对于文件系统的使用有一个相当模糊的概念。btrfs
我突然想到,由于引用链接副本、配额和快照不再给出确切的绝对值。您可能希望将此视为一个例外,而不是现阶段的规则,但您可能希望了解这一点。
答案2
谷歌是你最好的朋友。的结果“f_frsize 和 f_bsize 的差异”
=>“如果你有8KB的块大小并尝试向该块写入1KB的文件,结果你浪费了7KB的块空间。但最近我注意到文件块的碎片。在同样的情况下,如果你有8KB的文件块并且片段大小 1KB - 您可以节省块空间,因为 1KB 文件将仅填充 1 个片段,其他 7 个片段将用于其他文件。”
你的问题的答案是:使用f_bsize。