3

I know df is supposed to provide this information, but when I run df it shows the number of 1k blocks free, yet my filesystem is using 4k blocks.

I could simply divide by four of course, but this wouldn't necessarily be correct, due to the difference in granularity. For example, four 1k files would use four 1k blocks on a filesystem using 1k blocks, but four 1k files would use four 4k blocks on a filesystem using 4k blocks. (So dividing by four would produce the wrong answer.)

cat pants
  • 435

4 Answers4

5

If you have a 1K file occupying a 4K filesystem block, it will contribute 4K to the df output.

df calculates the number by asking the kernel for the free block count (with statfs/statvfs) and multiplying that by block size / 1024.

Just divide by 4. Sometimes things are simpler than you expect.

On the other hand, you shouldn't assume every version of df uses 1024-byte blocks as its reporting unit. Sometimes it's 512.

  • df explicitly states in the first line of output that it is using 1k blocks. Sounds good! I'll just divide by 4 then. I just found it strange that df wouldn't attempt to use the correct block size per filesystem. – cat pants May 14 '14 at 23:59
0

Option sets for different versions of df are interestingly diverse.

If you are using GNU's df (eg, with Linux), you can say
df -B4K
(or df -B4k) to compensate for 4KB block sizes.

For OpenBSD's df and the Mac's OSX df, set environment variable BLOCKSIZE to 4096 to tell df to use 4KB block sizes.

For Solaris's /usr/bin/df use the -v switch to find out “the total number of blocks allocated to the file system, the number of blocks allocated to existing files, [and] the number of blocks available for the creation of new files by unprivileged users” among other information. For -v, “sizes are displayed in multiples of the smallest block size supported by each specified file system.”

For AIX's df use the -I switch to find out “total number of blocks, the used space, the free space, the percentage of used space, and the mount point for the file system”. (It isn't clear to me what units the used and free space are given in when -I is in effect, and I don't see any more-relevant switches, except that -i will show the number of used inodes and the percentage of inodes in use.) Note, /usr/sysv/bin/df -v on AIX “Reports percent of blocks used as well as the number of blocks used and free”, which is similar to Solaris's /usr/bin/df -v behavior.

The Single UNIX Specification for df as described in wikipedia seems to have no relevant switches for showing df results in terms of blocks or inodes.

0

The POSIX df offers only 1024 or 512 byte units, so the answer is system specific, and quite likely file-system specific too (and I'll ignore complications like block suballocation and inline data.)

The first consideration is the concept of reserved blocks, per specification the free blocks count output by df will not include the reserved blocks (typically reserved for root, but not always).

A (mostly) portable way of finding out without using df is to use Gnu stat, using an output format of your choosing:

$ stat -fc "%n type=%T freeblk=%f totalblk=%b blksz=%S" /tmp
/tmp type=ext2/ext3 freeblk=99136 totalblk=494123 blksz=4096

You can use %a (instead of %f) to output the effective free block count (i.e. excluding reserved blocks), as df uses in its calculations.

Other systems (*BSD) have differences in their stat formatting flags and features, and may only work on files, not file-systems. stat isn't POSIX (it's a wrapper around the POSIX functions stat() and statvfs()), the GNU version (in the coreutils package) is quite portable.

With ext2/3/4-based filesystems you can as root (or more correctly: with read access to the block device node) dump this information with tune2fs:

# tune2fs -l /dev/sda3                              
tune2fs 1.42.8 (20-Jun-2013)                                                    
Filesystem volume name:   <none>                                                
Last mounted on:          /var/spool                                     
Filesystem UUID:          7b9d93dd-1322-4f54-a302-a0799f4518fb
Filesystem magic number:  0xEF53                                                
[...]
Filesystem state:         clean                                                 
Errors behavior:          Continue                                              
Filesystem OS type:       Linux                                                 
Inode count:              7651328                                               
Block count:              30588854                                              
Reserved block count:     305888                                                
Free blocks:              30060629                                              
Free inodes:              7651317                                               
First block:              0                                                     
Block size:               4096                         
Fragment size:            4096                  
[...]

This method works whether the filesystem is mounted or not.

mr.spuratic
  • 9,901
0

Usefull information about the df function behaviour, if there are a lot of files, which are smaller (or much smaller) than the block size of disk.

I ran into a problem, that the df function told me the following:

Filesystem     1K-blocks    Used Available Use% Mounted on
udev               89212       0     89212   0% /dev
tmpfs              24396    3236     21160  14% /run
/dev/mmcblk0p1   3583944 1926248   1593516  55% /
tmpfs             121980       0    121980   0% /dev/shm
tmpfs               5120       0      5120   0% /run/lock
tmpfs             121980       0    121980   0% /sys/fs/cgroup
tmpfs             121980       4    121976   1% /tmp
/dev/zram1         49584   17836     28164  39% /var/log
tmpfs              24396       0     24396   0% /run/user/0

But there was no more space for sure, because I got back error for creating new file. The solution was the "df -i" which gave back the occupied blocks on the disk:

Filesystem     Inodes  IUsed IFree IUse% Mounted on
udev            22303    338 21965    2% /dev
tmpfs           30495    523 29972    2% /run
/dev/mmcblk0p1 230144 230144     0  100% /
tmpfs           30495      1 30494    1% /dev/shm
tmpfs           30495      2 30493    1% /run/lock
tmpfs           30495     17 30478    1% /sys/fs/cgroup
tmpfs           30495     15 30480    1% /tmp
/dev/zram1      12800     34 12766    1% /var/log
tmpfs           30495     21 30474    1% /run/user/0

So, this was the more usabe free/used space indicator of the disk. For test I wrote ~180.000 pieces 409Byte sized files to fill 4096Byte sized blocks, so the simple "df" disk usage almost did not change, but the disk became full.