Utility df shows inconsistent calculation for ext filesystems

The output of “df” might sometimes seem inconsistent or wrong and especially in some situations the presented information seems to obviously not match up. The fact is, the information is not wrong but the calculation behind it considers facts that are not presented in df’s output.

The following example shows an output from a mostly empty root filesystem. It is obvious that these numbers do not sum up as they are presented.

The above output shows clearly a calculation that leads to the conclusion that something does not sum up. When doing the maths, it is clear that 17GB of Available space plus the 607MB does not result in a total size of 19GB.

The explanation is that the file systems reserves a certain amount of space and inodes for use by root. By default the amount of reserved space is 5%. Especially with bigger partitions this can be a significant amount of space that is not usable for services or users other then root.

In the above example, the total filesystem is 19GB in size. Considering the reserved space, the 5% would be about 950MB. With the reserved space and the used space, the numbers start adding up again.

What is the reason for the reserved space?

There are not many official statements about the reasons for the reserved space on ext filesystems. The ext2 filesystem documentation describes the reason for the reserved space like this.

In ext2, there is a mechanism for reserving a certain number of blocks
for a particular user (normally the super-user). This is intended to
allow for the system to continue functioning even if non-privileged users
fill up all the space available to them (this is independent of filesystem
quotas). It also keeps the filesystem from filling up entirely which
helps combat fragmentation.

As the quote from the ext2 filesystem states, there are two main reasons for the reserved space.

First the problem with filesystems that are filled up by non-root users. The intention behind this is that non-root users or services are not able to fill up the filesystem 100%, as this would cause the operating system to be rendered inaccessible. This would even prevent accessing the system to delete or fix the course of the problem. Having some reserved space allows the root user to login and fix the problem by deleting files to restore the full functionality of the system.

Second is fragmentation. The ext filesystems deal with fragmentation on their own. As the explanation implies, the filesystem’s ability to deal with fragmentation is bound to the free space. When there are fragmentation issues, the performance of the filesystem is going down. The conclusion here is clear, without free space to deal with fragmentation, the filesystem’s performance will get worse.

A suggestion from the above reasons would be the following. For root filesystems it would be good to reserve some percentage of the space to keep the system running in case of a filled up filesystem. On big filesystems storing only data, it could be helpful to reduce it or even not reserve space at all.

Check the reserved space

To check the amount of space reserved, the tune2fs utility can be used. The option -l shows all filesystem superblock information including the reserved space. As the output is quite long, grep is used below to filter out just what is interesting at the moment.

The above shows that the filesystem on /dev/vg_srv/lv_root contains some reserved space. This space is reserved for the root user and group as shown in the output. Additionally the output shows the block size which can be used to verify the output of df.

With the option -B4K instead of -h, the df command shows the sizes in 4KB blocks which represents the same format as tune2fs presents the reserved space.

Calculating the reserved space by subtracting the Used and Available space from the total space will give the reserved 4KB blocks. The result will be the same amount of blocks as there is reported reserved in the tune2fs output.

Change the reserved space

The reserved space can be configured using the tune2fs command. In cases where there is only data on the partition the reserved space could even be set to 0. The following command does exactly that.

The command above changes the reserved space with the -m option to 0% for the filesystem on /dev/vg_srv/lv_root. The reserved space can not only be defined as a percentage but also as a number of blocks. To see more options, see the tun2fs(8) man page. Either way, when set to 0% or 0 blocks, there will be no reserved space any more on this filesystem.

Checking the output of df again now shows a different result. The used space is still the same but the available space shows 1GB more. To show the exact amount of available space the output needs to be changed back to 4k blocks.

Subtracting the “Used” and “Available” space from the total size will show the amount of reserved space. Based on the above output, the reserved space is 0. This proves the effect of the changed settings on the filesystem.