使用 statvfs 获取文件系统总大小和可用大小

使用 statvfs 获取文件系统总大小和可用大小

我想使用 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_frsizeif 不为零,否则使用f_bsize.

我的建议是复制他们的方法,因为df在野外和时间上已经看到了极其广泛的分布。人们希望有人会指出,如果它不正确,那么现在它报告了错误的值。

您还应该意识到更现代的文件系统对于文件系统的使用有一个相当模糊的概念。btrfs我突然想到,由于引用链接副本、配额和快照不再给出确切的绝对值。您可能希望将此视为一个例外,而不是现阶段的规则,但您可能希望了解这一点。

答案2

谷歌是你最好的朋友。的结果“f_frsize 和 f_bsize 的差异”
=>“如果你有8KB的块大小并尝试向该块写入1KB的文件,结果你浪费了7KB的块空间。但最近我注意到文件块的碎片。在同样的情况下,如果你有8KB的文件块并且片段大小 1KB - 您可以节省块空间,因为 1KB 文件将仅填充 1 个片段,其他 7 个片段将用于其他文件。”
你的问题的答案是:使用f_bsize。

相关内容