Reputation: 1716
I've got an issue with a program that should send me back the free disk space usable by any user.
My goal is to get all the free disk space of every partitions of my hard drive that is usable by anyone who doesn't have sudo rights.
So I tryed this :
int main() {
struct statvfs diskData;
statvfs("/", &diskData);
unsigned long long available = (diskData.f_favail + diskData.f_bavail) * diskData.f_frsize) / (1024 * 1024)
std::cout << "Free Space : " << available << std::endl;
}
This gives me a total of 2810 ...
However, when I output df -h
, I can read that the available space is 25G
for sda3
and 30G
for sda1
This seems completely inaccurate.
I've been running on the posts on Stackoverflow, mixing solutions I saw, but none is satisfactory. How can I get a correct value in Megabytes of my available free space ?
EDIT : Full statvfs
and df /
output
statvfs
:
Block Size : 4 096
Fragment Size : 4 096
Blocks : 9 612 197
Free Blocks : 7 009 166
Non Root Free Blocks : 6 520 885
Inodes : 2 444 624
Free Inodes Space : 2 137 054
Non Root Free Inodes : 2 137 054
File System ID : 4 224 884 198
Mount Flags : 4 096
Max Filename Length : 255
df /
:
Filesystem 1K-Blocks Used Available Use% Mounted on
/dev/sda3 38 448 788 10 412 112 26 083 556 29% /
Upvotes: 2
Views: 2041
Reputation: 2852
It seems that the right value to use is the fragment size, not the block size (i.e. f_frsize)
Have you tried with
diskData.f_bavail * diskData.f_frsize
instead ?
Upvotes: 2
Reputation: 58447
This seems like a more accurate measure of the free disk space:
unsigned long long available = (diskData.f_bavail * diskData.f_bsize) / (1024 * 1024);
It matches the output from df
quite closely on my system (df
shows the sizes in gigs, and probably rounds them).
If you want the output in gigs like df
you could use this:
#include <sys/statvfs.h>
#include <stdio.h>
unsigned long rounddiv(unsigned long num, unsigned long divisor) {
return (num + (divisor/2)) / divisor;
}
int main() {
struct statvfs diskData;
statvfs("/home", &diskData);
unsigned long available = diskData.f_bavail * diskData.f_bsize;
printf("Free Space : %luG\n", rounddiv(available, 1024*1024*1024));
return 0;
}
The output from this on my system:
Free Space : 31G
And if I run df -h /home
:
Filesystem Size Used Avail Use% Mounted on
181G 141G 31G 83% /home
Upvotes: 4