Converting statvfs to percentage free correctly
On your Edit #2, the Usage% calculation needs to be updated to this to match df output:
100.0 * (double) (vfs.f_blocks - vfs.f_bfree) / (double) (vfs.f_blocks - vfs.f_bfree + vfs.f_bavail)
Reasoning:
Used = f_blocks - f_bfree
Avail = f_bavail
df % = Used / (Used + Avail)
df
's data may be based on f_bavail
, not f_bfree
. You may find it helpful to look at the source code to df to see how it does things. It has a number of edge cases it needs to deal with (eg, when the used space exceeds the amount of space available to non-root users), but the relevant code for the normal case is here:
uintmax_t u100 = used * 100;
uintmax_t nonroot_total = used + available;
pct = u100 / nonroot_total + (u100 % nonroot_total != 0);
In other words, 100 * used / (used + available)
, rounded up. Plugging in the values from your df output gives 100 * 14159676 / (14159676 + 25837672) = 35.4015371
, which rounded up is 36%, just as df
calculated.