Reputation:
When I use the statvfs command on a Linux machine to get the available free space on a mounted file system, the number I get is slightly different than what is reported by df.
For example, one on machine I have with a 500G hard drive, I get the following output from df:
# df --block-size=1 --no-sync
Filesystem 1B-blocks Used Available Use% Mounted on
/dev/md0 492256247808 3422584832 463828406272 1% /
tmpfs 2025721856 0 2025721856 0% /lib/init/rw
varrun 2025721856 114688 2025607168 1% /var/run
varlock 2025721856 4096 2025717760 1% /var/lock
udev 2025721856 147456 2025574400 1% /dev
tmpfs 2025721856 94208 2025627648 1% /dev/shm
A call to statvfs gives me a block size of 4096 and 119344155 free blocks, so that there should be 488,833,658,880 bytes free. Yet, df reports there are 463,828,406,272 bytes free. Why is there a discrepancy here?
Upvotes: 10
Views: 8704
Reputation: 162
Note that under Linux, df
uses stat
on the device file, not statvfs
; cf the coreutils source.
However, the basic principle above applies. As to why df
is so much faster and whether there are any shortcuts available for du
....
The filesystem entry for any specific folder contains information about that folder only: how much space is allocated for the folder itself, and how space is allocated for the file system entries for the files and folders in that folder - it does not contain the total space occupied by that folder and all of its subfolders.
To get that information, du
has to list all of the folders in the original folder, all of their folders, and so on, totalling as it goes.
So du
will return very quickly for a folder without subfolders, and ever more slowly for folders with increasing numbers of subfolders.
Contrast that with df
, with a call to stat(3)
against a device file, or with a call to statfs(2)
or statvfs(3)
against any file on a device, etc., all of which return information about the specific device/filesystem immediately.
du
can only rival the speed of df
in the case of being called against a single file, where both du
and df
are making a single system call and doing very little math.
Upvotes: 0
Reputation: 1181
#include <stdio.h>
#include <sys/statvfs.h>
int main(){
struct statvfs stat;
int a=statvfs("/",&stat);
printf("total free disk space of the partition: %d GB \n",(stat.f_bavail)*8/2097152);
//512 is 2^9 - one half of a kilobyte.
//A kilobyte is 2^10. A megabyte is 2^20. A gigabyte is 2^30. A terabyte
//is 2^40. And so on. The common computer units go up by 10's of powers
//of 2 like that.
//So you need to divide by 2^(30-9) == 2^21 == 2097152 to get gigabytes.
//And multiply by 8 because 1 byte=8bit
return 0;
}
I do in this form because I prefer the outcome in Gb, but you can modify the units changing the exponent.And is true the first answer, as you can see, I use that too
Upvotes: 0
Reputation: 5142
Since your discrepancy is close to 5% [1], which is the default percentage allocated for root, there is a possibility that you compare the df result with the ->f_bfree of statvfs and not with ->f_bavail, which is what df uses.
[1]: (488833658880 - 463828406272)/492256247808 = 0.0508
Upvotes: 11