How to Get Available Filesystem Space on Linux: a C Function with a C++ Example
Posted on In Linux, Programming, TutorialIt is common for programs to write to files in filesystems on disks. However, what if the disk was almost full when your program writes to the filesystem on a disk? For systems software and mission critical programs, it is a better or must-to-do practice to check the available filesystem space before actually writing to files. On POSIX OSes, we have the statvfs
POSIX API to get filesystem statistics (On Linux, you may use the Linux specific statfs
, but POSIX APIs are better for portability). In this post, we will introduce a C function and a C++ example to use the statvfs
API to get the available filesystem space.
The header that you need to include in your C or C++ programs to use the statvfs
API:
// header for statvfs
#include <sys/statvfs.h>
and the prototype of the statvfs
is
int statvfs(const char *path, struct statvfs *buf);
The results will be filled to the buf
statvfs struct
:
struct statvfs {
unsigned long f_bsize; /* filesystem block size */
unsigned long f_frsize; /* fragment size */
fsblkcnt_t f_blocks; /* size of fs in f_frsize units */
fsblkcnt_t f_bfree; /* # free blocks */
fsblkcnt_t f_bavail; /* # free blocks for unprivileged users */
fsfilcnt_t f_files; /* # inodes */
fsfilcnt_t f_ffree; /* # free inodes */
fsfilcnt_t f_favail; /* # free inodes for unprivileged users */
unsigned long f_fsid; /* filesystem ID */
unsigned long f_flag; /* mount flags */
unsigned long f_namemax; /* maximum filename length */
};
For unprivileged users, there are f_bavail
available blocks in the filesystem and each block’s size is f_bsize
bytes. So the overall available space in the filesystems is
f_bsize * f_bavail
I summarize and implement the method here in one simple function as follows.
long GetAvailableSpace(const char* path)
{
struct statvfs stat;
if (statvfs(path, &stat) != 0) {
// error happens, just quits here
return -1;
}
// the available size is f_bsize * f_bavail
return stat.f_bsize * stat.f_bavail;
}
If you are using boost in your C++ project, you may alternatively use the space
function.
With the above GetAvailableSpace
function, a full example in C++ is as follows.
The program can accept a path to a file or a directory and report the available space in the corresponding filesystem. Several examples are as follows. Here, the above C++ program is build to GetAvailableSpace
.
Find the available space where a file is in:
$ touch /tmp/a.txt
$ ./GetAvailableSpace /tmp/a.txt
Available space under `/tmp/a.txt`: 4140032000 bytes.
Find the available space from a directory path (no need to be a mount point):
$ ./GetAvailableSpace /tmp/
Available space under `/tmp/`: 4140032000 bytes.
Note that the directory must exist. Otherwise, it will reports an error:
$ ./GetAvailableSpace /dd/
Available space under `/dd/`:
ERROR: failed to get available space