I have a Embedded Linux system which starts some recording of data on request in a SD card. The software controlling the system has a periodically called function to check the amount of available space in the SD Card, stopping the recording if it reaches 99% of occupation. The code I'm using is the following having statvfs
as the function to read the folder where data is stored:
struct statvfs buff;
const int resp = statvfs("/media/mmcblk0p2/", &buff);
if (resp < 0)
{
const QString strTemp = QString("INTERFACE: An error occurred while trying to read the file system info");
mDebugS(strTemp);
mLog(strTemp);
return;
}
const float size = float(buff.f_bsize * buff.f_blocks) / float(1024 * 1024 * 1024);
const float free = float(buff.f_bsize * buff.f_bfree) / float(1024 * 1024 * 1024);
const float available = float(buff.f_bsize * buff.f_bavail) / float(1024 * 1024 * 1024);
//const float used = size - free;
const float percentUsed = (size - free)/size; //E.g.: 0.98
const float percentAvailable = available/size;
const float totalStorageTime = size/1.2f * 24.0f;
//const float hoursUsed = percentUsed * totalStorageTime;
const float timeAvailable = percentAvailable * totalStorageTime;
const qint32 hoursLeft = (qint32)timeAvailable;
const qint32 minutesLeft = qint32((timeAvailable - (float)hoursLeft) * 60.0f);
// mDebugS(QString("INTERFACE: mmcblk0p2 info: size: %1 | free: %2 | available: %3 | percent used: %4 | percent available: %5 | totalStorageTime: %6 | time available: %7 \n | hoursLeft: %8 "
// "| minutes left: %9")
// .arg(size).arg(free).arg(available).arg(percentUsed).arg(percentAvailable).arg(totalStorageTime).arg(timeAvailable).arg((qint32)timeAvailable)
// .arg(qint32((timeAvailable - (float)hoursLeft) * 60.0f)));
emit signalSetMassMemory(hoursLeft,minutesLeft);
if (percentUsed >= 0.99f)
//...
Note: The 1.2f value there is relative to the speed of recording: 1.2 Gb per day. I also use this function to know how much recording time is left.
This algorithm was tested first in a 4 Gb SD card and it worked fine. This SDC is divided in two partitions, the relevant one called /media/mmcblk0p2/
. The problem I'm facing is that when running the exact code in another system with a different SD card, the returned values for folder size are wrong: that SDC is 16 Gb and the function is returning me something like 2.22 Gb. What could be wrong since the algorithm and everything else is exactly the same?
My only suspicion for now is that there is a problem in the SD Card, a Kingston 16 Gb micro sdhc Class 4 which is exactly equal to the other, successful one, with the exception of the size. But I wouldn't know exactly which problem it could have since it's working fine for everything else (copying, pasting, creating folders, etc.). Btw the formatting is the same for both memory cards and I have no other left to run some extra tests.
So does anybody have a clue on what could be happening? Has statvfs
some sort of limitation the docs don't talk about? Should I change the function?
32-bit data type can hold sizes at most 4G, while to represent 16G you need more bits, so 64-bit data type must be used. Try to use quint64 instead of what you use now, or check what native unsigned 64-bit data type your compiler supports. It is typically unsigned long long.