How to Get Available Filesystem Space on Linux: a C Function with a C++ Example

Posted on In Linux, Programming, Tutorial

It 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

Eric Ma

Eric is a systems guy. Eric is interested in building high-performance and scalable distributed systems and related technologies. The views or opinions expressed here are solely Eric's own and do not necessarily represent those of any third parties.

Leave a Reply

Your email address will not be published. Required fields are marked *