Получите реальное бесплатное полезное пространство

У меня возникла проблема с программой, которая должна вернуть мне свободное место на диске, доступное любому пользователю.

Моя цель — получить все свободное дисковое пространство всех разделов моего жесткого диска, которое может использовать любой, у кого нет прав sudo.

Итак, я попробовал это:

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;
}

Это дает мне в общей сложности 2810 ...

Однако, когда я вывожу df -h, я могу прочитать, что доступное пространство равно 25G для sda3 и 30G для sda1.

Это кажется совершенно неверным.

Я бегал по сообщениям на Stackoverflow, смешивая решения, которые я видел, но ни одно из них не является удовлетворительным. Как я могу получить правильное значение доступного свободного места в мегабайтах?

РЕДАКТИРОВАТЬ: Полный вывод statvfs и df /

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%      / 

person Xaltar    schedule 11.04.2013    source источник


Ответы (2)


Кажется, что правильным значением для использования является размер фрагмента, а не размер блока (т.е. f_frsize).

Вы пробовали с

diskData.f_bavail * diskData.f_frsize

вместо ?

person Marco Righele    schedule 12.04.2013
comment
Да я думала лучше! Но размер фрагмента и размер блока в моей системе совпадают. Я получил тот же результат. - person Xaltar; 12.04.2013
comment
Не могли бы вы обновить сообщение со всеми выводами statvfs и df / (без -h)? Это очень помогло бы. - person Marco Righele; 12.04.2013
comment
6 520 885 * 4096/1024 составляет 26 083 540, что довольно близко к результату df (26 083 556). Разделив значение на 1024*1024, вы получите ожидаемый результат. - person Marco Righele; 12.04.2013
comment
Я предполагаю, что вы используете 32-битные целые числа со знаком, которые могут представлять не более 2 ^ 31-1 (около 2 147 483 647). 6 520 886 * 4096 равно 26 709 549 056, что больше. Вы должны использовать как минимум 64-битное целое число или, если вам достаточно приблизительных значений, тип с плавающей запятой. - person Marco Righele; 12.04.2013
comment
Вы должны выполнить преобразование перед выполнением умножения. Например float f_bavail = diskData.f_bavail; float f_frsize = diskData.f_frsize; float available = f_bavail * f_frsize / (1024 * 1024); - person Marco Righele; 12.04.2013

Это кажется более точным показателем свободного места на диске:

unsigned long long available = (diskData.f_bavail * diskData.f_bsize) / (1024 * 1024);

Он довольно точно соответствует выходным данным df в моей системе (df показывает размеры в гигабайтах и, возможно, округляет их).

Если вы хотите получить результат в гигабайтах, например df, вы можете использовать это:

#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;
}

Результат этого в моей системе:
Free Space : 31G

А если запустить df -h /home:

Filesystem            Size  Used Avail Use% Mounted on
                      181G  141G   31G  83% /home
person Michael    schedule 11.04.2013
comment
Хм, вы должны быть правы, однако теперь я получаю результат 1992 с тем, что вы мне предложили. f_bavail возвращает 510 003, а f_bsize возвращает 4096. Есть ли available в Gigs of Megs? Потому что ни один из них снова не кажется точным ... Я что-то упустил ? - person Xaltar; 12.04.2013
comment
Спасибо за новый ответ. Я думаю, что ваш код должен быть правильным, но тогда у меня должна быть другая проблема, потому что я вывожу 1G, когда использую /, а df -h / говорит мне, что на /dev/sda3 (единственное, что смонтировано на /) у меня есть 25G доступно... - person Xaltar; 12.04.2013