'statvfs wrong SD available size returned
I'm trying to monitor the available SD card size in a embedded linux system (petalinux).
After looking for this topic around stackoverflow I learn that a good option is to use the statvfs structure.
So to test it I wrote the next code:
int main()
{
struct statvfs stat;
if (statvfs("/run/media/mmcblk1p2", &stat) != 0) {
// error happens, just quits here
return -1;
}
printf("bsize: %ld\n", stat.f_bsize);
printf("bavail: %ld\n", stat.f_blocks);
printf("size in bytes: %ld\n", stat.f_blocks*stat.f_bavail);
double megas= (((double)(stat.f_blocks*stat.f_bavail)) / (1024*1024));
printf("size in MB:%.0f \n", megas);
return 0;
}
And the output is:
bsize: 131072
bavail: 973877
size in bytes: 945460243017
size in MB:901661
Checking this with the df command I've got:
root@petalinux:~# df
Filesystem 1K-blocks Used Available Use% Mounted on
devtmpfs 484744 4 484740 0% /dev
tmpfs 1023712 128 1023584 0% /run
tmpfs 1023712 88 1023624 0% /var/volatile
/dev/mmcblk1p2 124656256 391168 124265088 0% /run/media/mmcblk1p2
/dev/mmcblk1p1 204607 135889 68719 66% /run/media/mmcblk1p1
root@petalinux:~# df -h
Filesystem Size Used Available Use% Mounted on
devtmpfs 473.4M 4.0K 473.4M 0% /dev
tmpfs 999.7M 128.0K 999.6M 0% /run
tmpfs 999.7M 88.0K 999.6M 0% /var/volatile
/dev/mmcblk1p2 118.9G 382.0M 118.5G 0% /run/media/mmcblk1p2
/dev/mmcblk1p1 199.8M 132.7M 67.1M 66% /run/media/mmcblk1p1
I would expect for the mmcblk1p2 folder an available space of 124265088 bytes but instead I'm having 945460243017 bytes.
I've already had a look to similar questions but unfortunately non of them helped me to solve this issue.
Does anyone have an idea what I'm doing wrong?
EDIT
As pointed it could be the a block multiplication issue, where I had:
stat.f_blocks*stat.f_bavail
And I changed it to:
stat.f_frsize*stat.f_bavail
But the result still wrong:
bsize: 131072
bavail: 973877
size in bytes: 127247450112
Size in MB:121353
Now it's showing 127247450112 and it should be 124265088, Any ideas what I've got wrong?
Thanks in advance.
Solution 1:[1]
This:
printf("size in bytes: %ld\n", stat.f_blocks*stat.f_bavail);
is multiplying two block counts, which surely is not what you meant.
Solution 2:[2]
You will most likely get a wrong answer when multiplying an unsigned long type (f_bsize and f_frsize) by an unsigned long long (f_blocks, f_bfree and f_bavail) without first casting the unsigned long as an unsigned long long... Try this:
printf("%llu\n", stat.f_bavail * (unsigned long long)stat.f_frsize);
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | unwind |
Solution 2 | Caleb Carroll |