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
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 -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.