Linux

使用 statvfs 獲取總和空閒文件系統大小

  • May 24, 2022

我想使用 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再來一次?

塊的碎片似乎是某些遺留文件系統中的文件系統功能(Google搜尋表明 UFS 和 JFS 有它的用途)。

片段大小似乎表明片段允許並且應該在 1 和 之間的最小值f_bsize

在不支持它的文件系統上,這個值應該等於f_bsize(或為零,見下文),因為不支持進一步的塊碎片。

如果您檢查coreutils原始碼(至少在基於 redhat 的系統上),您可以看到 GNU 如何在df. 鑑於 GNU應該使用各種風格的 UNIX 來處理各種 POSIX 語義,而不僅僅是 Linux,它應該就如何解決這個問題提供相當可靠的建議。

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突然想到由於重新連結副本,配額和快照不再給出確切的絕對值。在此階段,您可能更希望將此視為例外而不是規則,但您可能需要注意這一點。

引用自:https://unix.stackexchange.com/questions/672113